JetJej has quit [Read error: Connection reset by peer]
frodef has quit [Remote host closed the connection]
frodef has joined #lisp
ebrasca has quit [Remote host closed the connection]
skapata has quit [Ping timeout: 260 seconds]
jpli has joined #lisp
perrier-jouet has quit [Quit: WeeChat 3.0]
skapata has joined #lisp
red-dot has joined #lisp
troydm has quit [Quit: What is Hope? That all of your wishes and all of your dreams come true? To turn back time because things were not supposed to happen like that (C) Rau Le Creuset]
troydm has joined #lisp
nydel has quit [Quit: WeeChat 3.1-dev]
erh^ has joined #lisp
zacts has quit [Quit: leaving]
zacts has joined #lisp
rople has joined #lisp
enzuru has joined #lisp
slyrus has quit [Quit: Leaving]
random-nick has quit [Ping timeout: 265 seconds]
zacts has quit [Quit: leaving]
unimog has left #lisp ["ERC (IRC client for Emacs 27.1.90)"]
zacts has joined #lisp
semz has quit [Ping timeout: 258 seconds]
Inline has joined #lisp
galex-713 has quit [Remote host closed the connection]
galex-713 has joined #lisp
semz has joined #lisp
semz has quit [Changing host]
semz has joined #lisp
logand`` has joined #lisp
logand` has quit [Ping timeout: 240 seconds]
gaqwas has quit [Ping timeout: 246 seconds]
gaqwas has joined #lisp
gaqwas has joined #lisp
gaqwas has quit [Changing host]
aartaka has joined #lisp
<beach>
Good morning everyone!
Alfr_ has joined #lisp
<zacts>
hi beach
Alfr has quit [Ping timeout: 258 seconds]
<beach>
minion: memo for rogersm: I recommend you use Clouseau instead. It is way more competent than the SLIME inspector.
<minion>
Remembered. I'll tell rogersm when he/she/it next speaks.
loli has quit [Quit: WeeChat 3.0]
loli has joined #lisp
aartaka has quit [Read error: Connection reset by peer]
aartaka_d has joined #lisp
Inline has quit [Ping timeout: 260 seconds]
<Josh_2>
I have added two restarts to my restart-case and sbcl is complaining that it cannot stack allocate
<Josh_2>
is this normal?
aartaka has joined #lisp
gutter has quit [Remote host closed the connection]
<beach>
Josh_2: I get that message a lot, and I turn it off whenever I can.
aartaka_d has quit [Ping timeout: 240 seconds]
zacts has quit [Quit: leaving]
zacts has joined #lisp
loli has quit [Quit: WeeChat 3.0]
recalloc has quit [Remote host closed the connection]
loli has joined #lisp
aartaka has quit [Ping timeout: 240 seconds]
<Josh_2>
ah okay
loli has quit [Client Quit]
loli has joined #lisp
aartaka has joined #lisp
loli has quit [Client Quit]
Nilby has joined #lisp
loli has joined #lisp
toorevitimirp has joined #lisp
ex_nihilo has quit [Quit: Leaving]
terpri has quit [Remote host closed the connection]
zacts has quit [Quit: leaving]
iskander- has joined #lisp
iskander has quit [Ping timeout: 276 seconds]
frodef` has joined #lisp
Lord_of_Life has quit [Ping timeout: 276 seconds]
amb007 has quit [Ping timeout: 276 seconds]
Jesin has quit [Ping timeout: 276 seconds]
Lord_of_Life has joined #lisp
aartaka has quit [Read error: Connection reset by peer]
amb007 has joined #lisp
Jesin has joined #lisp
frodef has quit [Ping timeout: 276 seconds]
loli has quit [Quit: WeeChat 3.0]
paul0 has joined #lisp
loli has joined #lisp
aartaka has joined #lisp
_whitelogger has joined #lisp
scymtym_ has joined #lisp
zacts has joined #lisp
scymtym has quit [Ping timeout: 264 seconds]
Bike has quit [Quit: leaving]
frgo has quit [Ping timeout: 258 seconds]
bitmapper has quit [Quit: Connection closed for inactivity]
waleee-cl has quit [Quit: Connection closed for inactivity]
frgo has joined #lisp
Nilby has quit [Ping timeout: 240 seconds]
rople has quit [Ping timeout: 260 seconds]
zacts has quit [Quit: leaving]
aartaka has quit [Ping timeout: 272 seconds]
rumbler31 has joined #lisp
rumbler31 has quit [Remote host closed the connection]
beach has quit [Remote host closed the connection]
beach has joined #lisp
nullman has quit [Ping timeout: 264 seconds]
nullman has joined #lisp
zch has joined #lisp
<beach>
In SICL, I use the term "code object" for a data structure that is created as a result of processing a FASL file, but I am not happy with the term.
<beach>
I considered "compilation unit", but I suspect it would not be accurate with respect to the way that term is used by the Common Lisp standard. But I am not sure, so I am asking here.
<beach>
The macro with-compilation-unit seems to suggest a compilation unit is all about delaying (or avoiding when possible) messages from the compiler. And the glossary is not much help either.
<beach>
So what I am asking is, does the macro with-compilation-unit generate a single FASL from all the files being compiled in its dynamic environment?
shka_ has joined #lisp
karlosz has joined #lisp
daphnis has joined #lisp
Nilby has joined #lisp
Codaraxis has joined #lisp
lowryder_ has quit [Ping timeout: 240 seconds]
lowryder_ has joined #lisp
Codaraxis__ has quit [Ping timeout: 246 seconds]
loli has quit [Quit: WeeChat 3.0]
loli has joined #lisp
skapata has quit [Remote host closed the connection]
contrapunctus has left #lisp ["Disconnected: closed"]
contrapunctus has joined #lisp
<Alfr_>
beach, I don't think it can for compile-file.
<beach>
Yeah, maybe not.
<Alfr_>
beach, but if you want to do some inter function optimizations, I think you'd be able to.
<beach>
I see, yes.
<Alfr_>
I would interpret "actions deferred by the compiler until the end of compilation will be deferred until the end of the outermost call to with-compilation-unit" that way.
<flip214>
engblom: yes. neovim and vlime with sbcl and swank.
<beach>
Alfr_: You may be right.
<Alfr_>
But I don't know to where to write the results of such.
toorevitimirp has quit [Read error: Connection reset by peer]
luni has joined #lisp
pve has joined #lisp
pankajsg has quit [Ping timeout: 264 seconds]
zacts has joined #lisp
niceplace has joined #lisp
rumbler31 has joined #lisp
h4ck3r9696 has joined #lisp
rumbler31 has quit [Ping timeout: 276 seconds]
heisig has joined #lisp
imode has quit [Ping timeout: 265 seconds]
frodef`` has joined #lisp
rople has joined #lisp
frodef` has quit [Ping timeout: 276 seconds]
terpri has joined #lisp
shka_ has quit [Quit: Konversation terminated!]
anticrisis has quit [Read error: Connection reset by peer]
frodef`` has quit [Ping timeout: 265 seconds]
wildlander has quit [Quit: Konversation terminated!]
aindilis has quit [Ping timeout: 276 seconds]
tessier_ has quit [Ping timeout: 272 seconds]
hendursa1 has joined #lisp
rogersm has joined #lisp
hendursaga has quit [Ping timeout: 268 seconds]
orivej has joined #lisp
karayan has joined #lisp
narimiran has joined #lisp
narimiran has quit [Remote host closed the connection]
rogersm has quit []
rgherdt has joined #lisp
sunset_NOVA has joined #lisp
pankajsg has joined #lisp
scymtym_ has quit [Remote host closed the connection]
scymtym has joined #lisp
karayan has quit [Remote host closed the connection]
karayan has joined #lisp
tessier has joined #lisp
Christ0pher is now known as anunnaki
niceplace has quit [K-Lined]
zacts has quit [Quit: leaving]
<ioa>
Any lispers watching FOSDEM this weekend? :)
ebrasca has quit [Read error: Connection timed out]
ebrasca has joined #lisp
vegansbane6963 has joined #lisp
pankajsg has quit [Ping timeout: 256 seconds]
pankajsg has joined #lisp
gaqwas has quit [Ping timeout: 256 seconds]
orivej_ has joined #lisp
gaqwas has joined #lisp
orivej has quit [Ping timeout: 276 seconds]
theothornhill has joined #lisp
cosimone has joined #lisp
frodef`` has joined #lisp
luni has quit [Quit: Connection closed]
random-nick has joined #lisp
pankajsg has quit [Read error: Connection reset by peer]
pankajsg has joined #lisp
roelj has joined #lisp
fubbiquantz has quit [Ping timeout: 240 seconds]
contrapunctus has left #lisp ["Disconnected: closed"]
contrapunctus has joined #lisp
<heisig>
ioa: Sorry, I'm probably too late to comment on pre 13:00 suggestions. I will probably join the HPC devroom later.
<heisig>
But I fully agree. Tomorrow is the day of "declarative and minimalist languages". Which, surprisingly, seems to include Elisp and Common Lisp :)
theothornhill has quit [Ping timeout: 276 seconds]
pankajsg has quit [Ping timeout: 246 seconds]
pankajsg has joined #lisp
sunset_NOVA has quit [Quit: Leaving]
birdwing has joined #lisp
pankajsg has quit [Ping timeout: 240 seconds]
pankajsg has joined #lisp
theothornhill has joined #lisp
surabax_ has joined #lisp
Posterdati has quit [Ping timeout: 276 seconds]
Posterdati has joined #lisp
surabax has quit [Ping timeout: 276 seconds]
surabax_ has quit [Quit: Leaving]
<ioa>
lol yes, I also found it funny that a common-lisp project is there. :)
<contrapunctus>
Elisp? Declarative and minimal? wat
<ioa>
Well, a lot of lispers are in that room, there are Scheme and Racket talks every year, and also other lisp-friend languages (as i see them) like Smalltalk, Pharo, etc. So it makes sense to have the common-lisp and elisp talks there too, even if they are not minimalistic (at all).
<phoe>
declarative for sure, given that you can macro your way all the way into declarative programming
<beach>
I uploaded a new version of my draft paper on call-site optimization: http://metamodular.com/SICL/call-site-optimization.pdf The new version contains sections on how call sites to FUNCALL and APPLY with a function name known at compile time are handled.
theothornhill has quit [Read error: Connection reset by peer]
theothornhill has joined #lisp
theothornhill has quit [Ping timeout: 264 seconds]
IPmonger has quit [Quit: ZNC 1.7.5+deb4 - https://znc.in]
IPmonger has joined #lisp
iskander- has joined #lisp
lavaflow has quit [Ping timeout: 260 seconds]
IPmonger has quit [Client Quit]
iskander has quit [Ping timeout: 276 seconds]
galex-713 has quit [Ping timeout: 272 seconds]
sunset_NOVA has quit [Quit: Leaving]
lavaflow has joined #lisp
hiroaki has quit [Ping timeout: 265 seconds]
jonatack has joined #lisp
elflng has quit [Ping timeout: 272 seconds]
ted_wroclaw has joined #lisp
theothornhill has joined #lisp
jonatack has quit [Ping timeout: 265 seconds]
X-Scale` has joined #lisp
jonatack has joined #lisp
ukari has quit [Ping timeout: 276 seconds]
X-Scale has quit [Ping timeout: 276 seconds]
engblom has quit [Ping timeout: 276 seconds]
X-Scale` is now known as X-Scale
engblom has joined #lisp
theothornhill has quit [Ping timeout: 256 seconds]
zdm has joined #lisp
madage has quit [Ping timeout: 268 seconds]
loli has quit [Quit: WeeChat 3.0]
IPmonger has joined #lisp
loli has joined #lisp
zch has left #lisp ["(part-or-quit)"]
IPmonger has quit [Quit: ZNC 1.7.5+deb4 - https://znc.in]
asarch has joined #lisp
<asarch>
If I have two lists: '(ao aka shiro) and '(kuro midori aka), how could I know what elements of the first list are no present on the second list?
euandreh has quit [Ping timeout: 272 seconds]
IPmonger has joined #lisp
<_death>
are they sets? if so, (set-difference set1 set2)
<asarch>
Sets?
frgo has joined #lisp
<_death>
does ordering or multiplicity of elements matter
<asarch>
(setf farbe (set-difference '(aka ao shiro) '(midori aka kuro)))
<asarch>
No, it doesn't
marusich has joined #lisp
<asarch>
Yeah! Thank you _death! Thank you very much! :-)
IPmonger has quit [Quit: ZNC 1.7.5+deb4 - https://znc.in]
IPmonger has joined #lisp
thmprover has joined #lisp
IPmonger has quit [Client Quit]
Inline__ has joined #lisp
IPmonger has joined #lisp
IPmonger has quit [Quit: ZNC 1.7.5+deb4 - https://znc.in]
<edgar-rft>
asarch: set theory = mengenlehre
aartaka_d has joined #lisp
IPmonger has joined #lisp
Inline__ has quit [Ping timeout: 265 seconds]
aartaka has quit [Ping timeout: 246 seconds]
Inline__ has joined #lisp
Inline is now known as Guest25336
Inline__ is now known as Inline
<Alfr_>
_death, just made me have a terrible idea: (let (acc) (set-difference list1 list2 :test (lambda (x y) (push (list x y)) nil)) acc)
<phoe>
Alfr_: what is this supposed to achieve though
<Alfr_>
Oh, push onto acc of course.
<phoe>
yes, but why put that in TEST?
<loke[m]>
Alfr_: that is indeed a terrible idea. SET-DIFFERENCE doesn't specify how the test function is called.
<Alfr_>
phoe, cartesian product of list1 and list2 elements.
IPmonger has quit [Client Quit]
<phoe>
...oh
<phoe>
oh goodness
<Alfr_>
loke[m], it does, namely "for all ordered pairs" of the list's elements.
<Alfr_>
*lists'
<phoe>
loke[m]: but one thing is sure, if the test returns NIL all the time, then it is called on all combinations of list elements
<phoe>
"For all possible ordered pairs consisting of one element from list-1 and one element from list-2, the :test or :test-not function is used to determine whether they satisfy the test."
<phoe>
actually it looks like it specifies how the test function is called
<phoe>
that's a simple O(n²) test
<Alfr_>
In light of that requirement, is sbcl wrong to short circuit when a :test succeeds?
IPmonger has joined #lisp
<loke[m]>
phoe: so it would seem.
euandreh has joined #lisp
<Nilby>
isn't there cautions about assuming things about test functions elsewhere?
<Alfr_>
Oh it's okay, "used to determine" should cover short circuiting.
<ted_wroclaw>
Hi everyone. I noticed that in the user list Fabrice Nicol is implementing some extensions to the emacs toolchain. This made me wonder...How much work would it be to implement the language server protocol (LSP) for Mercury? Has anyone worked with the LSP in another context?
IPmonger has quit [Quit: ZNC 1.7.5+deb4 - https://znc.in]
euandreh has quit [Ping timeout: 272 seconds]
euandreh has joined #lisp
theothornhill has quit [Remote host closed the connection]
theothornhill has joined #lisp
asarch has quit [Ping timeout: 272 seconds]
IPmonger has joined #lisp
IPmonger has quit [Client Quit]
Posterdati has joined #lisp
IPmonger has joined #lisp
<Alfr_>
ck_, those are neat.
rumbler31 has joined #lisp
madage has joined #lisp
__jrjsmrtn__ has quit [Ping timeout: 265 seconds]
__jrjsmrtn__ has joined #lisp
rumbler31 has quit [Ping timeout: 272 seconds]
aindilis has joined #lisp
<waleee-cl>
ted_wroclaw: the mercury language? The prior art is limited to the flycheck addon I think so probably lots of work
paul0 has quit [Remote host closed the connection]
paul0 has joined #lisp
dilated_dinosaur has quit [Remote host closed the connection]
anticrisis has joined #lisp
aartaka_d has quit [Ping timeout: 246 seconds]
dilated_dinosaur has joined #lisp
theothornhill has quit [Remote host closed the connection]
theothornhill has joined #lisp
elflng has joined #lisp
puchacz has joined #lisp
<puchacz>
hi, in sbcl, what's the recommended way of making sure that a globally accessible thing is updated, so other threads don't see a garbage or unupdated value?
IPmonger has quit [Quit: ZNC 1.7.5+deb4 - https://znc.in]
<puchacz>
lispworks manual says that (1) if you acquire a lock, it executes all pending updates to memory, or (2) if you start a new thread, it will only be started when all pending updates are complete; here: http://www.lispworks.com/documentation/lw71/LW/html/lw-142.htm#91403
IPmonger has joined #lisp
<puchacz>
.3.4.1 Ways to guarantee the visibility of stores, points 1 and 5
<puchacz>
are the practical ways if I don't want to think about it too much
h4ck3r9696 has quit [Quit: Leaving.]
<puchacz>
but obviously it is specific to lispworks
asarch has joined #lisp
<puchacz>
do I have to use barriers in sbcl? or both of these conditions like in lispworks are enough?
<asarch>
Bingo! Tadaima! :-)
<phoe>
a globally accessible thing is updated...
<phoe>
is this thing CASable?
<puchacz>
what is CAS?
<phoe>
check the SBCL manual!
<phoe>
it's compare-and-swap
<phoe>
atomic updating operations.
<asarch>
Theory, edgar-rft?
<puchacz>
phoe, ok, tks
<puchacz>
:)
ggoes has quit [Quit: WeeChat 2.3]
<puchacz>
right, so would I have to update everything with compare-and-swap, that I would normally setf or call a setter method?
<phoe>
either your updates are simple and atomic enough to fit within a single CAS operation
ggoes has joined #lisp
<phoe>
or, if you need to update multiple objects or your place is not CASable, then you need to use a lock
<puchacz>
lock is fine by me. so it would make it identical to lispworks rule 1 (use lock)
<puchacz>
how about rule 5? when starting a new thread, all memory updates are completed before your code runs?
attila_lendvai has joined #lisp
attila_lendvai has quit [Changing host]
attila_lendvai has joined #lisp
<phoe>
you shouldn't need to care about this if you use locks properly; your other thread will wait for the lock to get freed before doing anything nasty anyway
<puchacz>
I guess if "rule 5" was not true in sbcl, you wouldn't be guaranteed to see symbol bindings from another thread (even defuns) that you load from a file.
<puchacz>
but I did not find it stated explicitely
<phoe>
why does this have anything to do with threads?
<phoe>
global bindings are accessible from all threads in the same way, this includes global function bindings
<phoe>
if thread A modifies a global binding, then this binding becomes apparent in all other threads when thread A is done updating it
imode has joined #lisp
<puchacz>
so when slime or sly loads a program, and then starts REPL for you, what guarantees that in the REPL thread you see all bindings loaded before? just that enough time has passed?
<phoe>
when the function in the other thread returns
<puchacz>
on the other hand you see bindings in REPL thread that are made when your REPL thread is already running
<phoe>
when a function finishes doing stuff, then stuff is done
<phoe>
that's a thread-independent assumption
vutral_ has joined #lisp
<puchacz>
maybe I am too paranoid from Java influence, where nothing is guaranteed to be visible to another thread if it is in a non-final object field and the field was not modifined inside synchronized block
<puchacz>
(however in practice I have never seen this problem)
<Nilby>
I very rarely experience such problems with threads.
<phoe>
lisp ain't java
<puchacz>
and lispworks manual is explicit that a new thread sees all global updates that the parent thread executed
<Nilby>
But I also ussually encapulate most state in dynamic objects.
<phoe>
when a thread mutates the state of the image then the state of the image is mutated for *all* threads
<phoe>
that's for global objects
Guest25336 has quit [Quit: Leaving]
IPmonger has quit [Quit: ZNC 1.7.5+deb4 - https://znc.in]
galex-713 has joined #lisp
lowryder_ has quit [Ping timeout: 240 seconds]
<puchacz>
so you think in sbcl that a new thread will see all updates to say defvar-ed global variables that are done by its parent thread before bt:make-thread?
<phoe>
then the value of *FOO* will be 42 before the thread is spawned
<puchacz>
(defvar x 3) (setf x 4) (bt:make-thread (lambda () x))
<puchacz>
yes
sunset_NOVA has joined #lisp
lowryder_ has joined #lisp
<puchacz>
is the lambda guaranteed to read x as 4, and never 3? (assuming nothing else modified it)
<phoe>
I would say so, yes
<phoe>
#sbcl might be able to confirm
<puchacz>
this is what lispworks manual explicitely says, I wonder why they made it explicit.... as if it was not obvious
<puchacz>
ok, thanks - I will ask
ggoes has joined #lisp
IPmonger has quit [Quit: ZNC 1.7.5+deb4 - https://znc.in]
sunset_NOVA has quit [Quit: Leaving]
sunset_NOVA has joined #lisp
IPmonger has joined #lisp
IPmonger has quit [Client Quit]
IPmonger has joined #lisp
IPmonger has quit [Quit: ZNC 1.7.5+deb4 - https://znc.in]
h4ck3r9696 has joined #lisp
IPmonger has joined #lisp
ted_wroclaw has quit [Ping timeout: 240 seconds]
pankajsg has quit [Quit: Konversation terminated!]
galex-713 has quit [Read error: Connection reset by peer]
ted_wroclaw has joined #lisp
perrier-jouet has quit [Quit: WeeChat 3.0]
<puchacz>
I think I remember from previous conversations that a non-dynamic let (i.e. lexical only) is always visible in another thread, like (let ((x 7)) (run-in-another-thread (lambda () x )) )
<puchacz>
is it so:-) ?
<puchacz>
mind I did not necessarily create a new thread there, I could have queued a closure for execution on a thread that already existed
<puchacz>
yes, this is what I referred to - the closure created there could have been put in a queue for an existing thread to be executed, not necessarily a new one.
aeth_ has joined #lisp
aeth has quit [Disconnected by services]
aeth_ is now known as aeth
<puchacz>
and how do you know that a mutated state of the image is mutated to all threads? I can't see it in the manual.
<puchacz>
(might be indeed that I worry too much)
perrier-jouet has joined #lisp
h4ck3r9696 has quit [Quit: Leaving.]
Inline has joined #lisp
Nilby has quit [Ping timeout: 258 seconds]
gaqwas has quit [Ping timeout: 272 seconds]
<phoe>
in the general case, I guess this depends on your CPU and compiler combination
<phoe>
and, ultimately, on memory fences wherever they are required
eden has quit [Ping timeout: 268 seconds]
<puchacz>
hmmm
birdwing has quit [Quit: Leaving]
theothornhill has quit [Ping timeout: 265 seconds]
pfdietz has joined #lisp
theothornhill has joined #lisp
puchacz has quit [Quit: Ping timeout (120 seconds)]
pfdietz has quit [Quit: Ping timeout (120 seconds)]
theothornhill has quit [Ping timeout: 272 seconds]
puchacz has joined #lisp
louis771 has joined #lisp
pfdietz has joined #lisp
IPmonger has quit [Quit: ZNC 1.7.5+deb4 - https://znc.in]
IPmonger has joined #lisp
hjudt has joined #lisp
Bike has joined #lisp
hiroaki has joined #lisp
<Bike>
"this is what lispworks manual explicitely says, I wonder why they made it explicit.... as if it was not obvious" it's not obvious. i mean, it is intuitively, but intuition doesn't usually work very well with concurrency.
cage_ has quit [Quit: Leaving]
<Bike>
i don't think sbcl has any kind of memory model to define the behavior here. i'm kind of surprised lispworks has anything. practically speaking you can probably rely on make-thread and join-thread synchronizing, and locks working, but other than that you might need barriers
hrberg has quit [Ping timeout: 256 seconds]
<puchacz>
Bike - so if I let ((x "hen")) .... ) and have any closure where I put dots, I understand that the closure will read x as "hen" (I wanted a complex object, not a fixnum), no matter what thread will execute the closure, providing that nothing will (setf x "chicken") at some point, is it right?
<puchacz>
setfing anything requires a barrier, no matter if it is a global / special variable, or a lexical one?
<Bike>
if you never setf x you can probably rely on it having that value, yes
<puchacz>
is it "obvious":-) ?
<Bike>
strictly speaking no, you can imagine a system where x is garbage in other threads
<puchacz>
like I can rely on it in any lisp because for example it is impossible to implement it other way
<puchacz>
ah, ok
<Bike>
the whole thing is technically undefined behavior, is the issue
<Bike>
so you're stuck with "well, sbcl PROBABLY works this way"
<puchacz>
and is a lock enforcing a barrier, like in lispworks?
<puchacz>
sorry if it was said already, I am confused
<Bike>
Yes, locks involve read and write barriers
<Bike>
It is confusing. Here's the problem: When you write your sequence of operations (setf x 0) (setf y 1) whatever, in one thread, the compiler and or machine might reorder those sets to be in some other order, as long as the single-thread semantics are the obvious ones
<Bike>
so if you're looking from other threads, you see impossible things
<puchacz>
agree
<Bike>
what a barrier does is tell the compiler and the machine to actually finish all the writes or reads or whatever that it's doing
<puchacz>
never seen it in Java, however they stress it in every tutorial
<Bike>
java put a lot of thought into how this behavior works
<Bike>
the problem only comes when one thread writes a place and another thread reads or writes it, and there's no synchronization relationship. If you only read and write to shared places from within excluded regions (like, with locks), that handles the synchronization so there's no issue.
<puchacz>
because grabbing a lock involves waiting for all pending stores to complete, globally in the whole image? this is what lispworks people imply I think about their system
<puchacz>
(I still don't understand if a barrier flushes everything, how would it decide otherwise what to flush)
<Bike>
When you release a lock there's a write barrier. When you acquire a lock there's a read barrier. So the thread that grabs the lock sees any writes done by the thread that just gave up the lock.
<Bike>
I don't think you can rely on writes in other threads being completed, though
<puchacz>
I see
<puchacz>
while I can imagine a write barrier means execute pending stores to memory (from instructions executes while the lock was held), what is a read barrier? clear any compiler level hidden caches?
<Bike>
say you have (progn (acquire-lock lock) (do-stuff (+ x y))). Without a read barrier, the compiler (or more likely the machine) might rewrite this as (let ((my-x x) (my-y y)) (acquire-lock lock) (do-stuff (+ x y)))
<Bike>
So if another thread has the lock and writes to x and y, this thread might not see that
swflint has quit [Ping timeout: 264 seconds]
<Bike>
Like, it might start the read earlier, anticipating that it will need the result soon
<Bike>
The barrier tells the compiler and the machine that it can't start reads after the barrier until it actually reaches the barrier
IPmonger has quit [Quit: ZNC 1.7.5+deb4 - https://znc.in]
<puchacz>
I see, because, as in your examples, it copies values to local variables
<puchacz>
before the main operation begins
<puchacz>
read barrier means do not copy variables before the barrier
IPmonger has joined #lisp
<Bike>
Yeah. You can imagine X might be a more complicated read, like accessing a vector or something.
swflint has joined #lisp
<Bike>
(really, if x is a shared lexical variable, reading it probably amounts to reading a vector)
<puchacz>
right. and I always pass values to a thread by creating lexical variables visible in a closure that will be executed in a thread. you said I can rely it will PROBABLY work in sbcl, so is there a more recommended way? I would do the same in lispworks, but when I read carefully what they wrote, they only say I will have my variable values if I pass
<puchacz>
it to a closure that will be executed in a new thread, they don't say what happens if the thread is a long lived executor and I only pass my closure to a queue.
<Bike>
You mean, you put your closure in a queue, and then the other thread dequeues the closure and calls it?
<puchacz>
yes
<puchacz>
they don't say anything about this scenario
<puchacz>
and btw, this is how I pass unmodifiable variables only, and with objects that I don't intend to modify
<Bike>
So you mean, the sequence is like: You start the executor thread. You bind x. You create this closure that will read x. You put this closure in the queue.
<puchacz>
yes
terpri has quit [Ping timeout: 240 seconds]
<Bike>
if the queue is lock based there could be a synchronization relationship that way
terpri has joined #lisp
<Bike>
otherwise, i suppose you would have to use a barrier. it looks like this "ensure-stores-after-stores" thing in lispworks is a barrier.
<puchacz>
yes, it seems so, however I only read it today :)
<Bike>
When I say "practically" part of what I mean is that this reordering stuff is usually pretty quick temporally. It's not like you'll have a read reordered an entire second before you expect it
<puchacz>
it is a realistic scenario in Android, you are supposed to "do stuff" and then stick a lambda into a queue to be executed in the main thread
IPmonger has quit [Quit: ZNC 1.7.5+deb4 - https://znc.in]
<puchacz>
excellent, thank you very much!
<Bike>
thank you for pointing out that lispworks does have some definitions here, it's the first lisp implementation i've seen that does
IPmonger has joined #lisp
<puchacz>
yes, but they don't say about lexical variables, most of what I read today is about globally accessible cells
<puchacz>
I think I shall start writing code that passes variables to other threads like I did before, with lexical (let ...), but in addition add a barrier
<Bike>
Yeah the only mention of lexical variables I see is that you can't use the atomic operations on them, which isn't very encouraging
<Bike>
also, with the definitions here "globally accessible cell" seems to me like it encompasses shared lexical variables, even though they're not actually global
<Bike>
since it just says a globally accessible cell is "a cell that may be accessed by those threads"
<Bike>
It's possible you don't need to use barriers depending on how your queue works. what kind of queue is it? something lispworks provides?
<Bike>
i ask because with only the primitives lispworks has here, i don't think you could actually implement a queue that doesn't itself synchronize
euandreh has quit [Ping timeout: 258 seconds]
<Bike>
oh, let's see
<Bike>
"The invocation of the function is done by the event loop of the GUI thread, so it is synchronous with respect to processing events, in other words it will not happen in the middle of processing an event." maybe that's enough? i don't know
<Bike>
you might be able to ask lispworks support about this, they'd know better than i do
<puchacz>
it is just that andorid draws everything in one thread, like java swing
euandreh has joined #lisp
<puchacz>
event processing uses the same thread, so what you put there, won't execute in parallel with event processing, because there is a single thread that responds to touches and draws
<puchacz>
so I am thinking I am reading a database in the background thread, which creates some objects, not practical to wrap it with bt:with-lock-held and use the same lock to access the objects in android thread. need to use memory barrier
<puchacz>
and it is compatible with sbcl (not that I would use sbcl on android, but the code may be shared)
<Bike>
I'm not familiar with android, but what I mean is - if you put something on this queue while processing an event, and you know that processing events synchronizes with the something being called, that's enough, and you don't need a barrier
<Bike>
The thing won't be called until definitely after you're done processing the event. the event loop has its own barriers
<Bike>
but i'm not totally sure that's how it works from the description here. it might
drl has joined #lisp
<puchacz>
I see what you mean. it will finish processing an event, execute write barrier, and then when it grabs my closure, first thing it will do is a read barrier. but will read barrier help if I created an object reading from the database in the background thread without a write barrier? what will make sure that it is fully written to memory if I used no
<puchacz>
lock or barrier when reading the object?
<Bike>
You mean like... there's one thread that reads from the database, a different thread that pushes the closure to the queue, and then the third main thread that executes the closure?
<puchacz>
no, just 2 threads
<puchacz>
one thread reads the database and creates an object, puts it into a lexical variable using (let ((obj ....)) if not lexical already, and then pushes a lambda into the android queue.
<puchacz>
so my point is that I never used a write barrier - you said that write barrier related to a lock only flushes pending stores executed when the lock was held
<puchacz>
android will possibly run a write barrier when finishing last event processing, but it will flush its own writes onlhy
long4mud has joined #lisp
<Bike>
hm. i dunno.
<Bike>
i mean, there shouldn't be any harm in putting in barriers, except that it might make things slower
<puchacz>
looks like in lispworks I should put store-after-store, and find equivalent barrier call in sbcl
<Bike>
sb-thread:barrier
<Bike>
with :write or :read or whatever
<puchacz>
ok, thanks - I will read the details which values are actually stored, unless it is global for the whole image?
attila_lendvai_ has joined #lisp
attila_lendvai has quit [Ping timeout: 264 seconds]
<Bike>
should be any stores from the thread doing the barrier, i think
<puchacz>
perfect
<puchacz>
flush all my writes up till this point
scymtym_ has joined #lisp
<puchacz>
and read barrier on the "opposite" side, to make sure the code did not read the values before I flush them, so now I understand why a new thread will not need read barrier in lispworks (it did not exist, it could not "cache" anything in lexicals for example)
attila_lendvai has joined #lisp
attila_lendvai has quit [Changing host]
attila_lendvai has joined #lisp
<puchacz>
but frankly, it is unlikely a lambda passed on a queue for the existing thread to be executed would need a read barrier as the first instruction
scymtym has quit [Ping timeout: 272 seconds]
<Bike>
yeah
<Bike>
i guess i can imagine some compiler transformations that would make it look like a read barrier violation
<Bike>
but it would be kind of asinine to do them
attila_lendvai_ has quit [Ping timeout: 260 seconds]
<Bike>
e.g., (let ((x 7)) (make-thread (lambda () (setf x 5))) (make-thread (lambda () (loop until (= x 5) do ...)))). the compiler could constant fold the x in (= x 5) to be 7
<Bike>
on the theory that there's nothing forcing the (setf x 5) to be visible ever
<puchacz>
right
<puchacz>
it is scary
<puchacz>
btw, on #sbcl - stassats told me in my example lexical x will always have the last value in sbcl, no matter if my lambda is passed to a new thread, or a queue for the old thread
<puchacz>
he disappeared before I understood what "shared" is though
<puchacz>
and I am supposed to use barriers and locks for shared things :)
<puchacz>
anyway, I learned a lot today
<puchacz>
locks I know from java, but barriers are the new friends now
<Bike>
probably just means in the unexamined sense of being accessible from multiple threads. but in your example x will always be 4 in the thread because make-thread does synchronization
<puchacz>
sure, but I also asked what if it is passed onto executor started long time ago, he says 4
<puchacz>
make-thread behaves like in lispworks, I see more and more evidence for it now
<puchacz>
maybe creating a closure is also a barrier
<Bike>
mh. like i said, if "a long time ago" is more than like a millisecond you don't need a barrier practically speaking
<Bike>
whatever, i'm sure you got it
<puchacz>
thanks :)
Bike has quit [Quit: Connection closed]
<puchacz>
very very helpful things you said
drl has quit [Quit: Leaving]
<puchacz>
(the executor may have been created long time ago but my closure may be executed 0.5 ms after being put on the queue, which is what matters I think)
jprajzne has quit [Quit: Leaving.]
heisig has quit [Quit: Leaving]
attila_lendvai has quit [Ping timeout: 264 seconds]
VincentVega has joined #lisp
h4ck3r9696 has joined #lisp
h4ck3r9696 has left #lisp [#lisp]
VincentVega has quit [Quit: Connection closed]
theothornhill has joined #lisp
<puchacz>
why does (sb-thread:barrier ...) macro accept a body? the manual says the body is executed before the barrier, so can I just put (sb-thread:barrier :write) and would it mean that all writes before this form will be completed before any write is executed after this form? in another word, it seems to me that I never need to put any body into this
<puchacz>
macro and use it exactly like I would use lispworks' (sys:ensure-stores-after-stores).
<puchacz>
similarly with (sb-tread:barrier :read) macro with no body being exactly equivalent of lispworks' form (sys:ensure-loads-after-loads)