I propose that we introduce a WITH-EXCLUSIVE-ACCESS form in the EXT package, which takes 1 argument (the second value) and a body (the third value). The form makes sure that the body is evaluated as if it had been called with:
synchronized (arg1) { body-to-evaluate; }
Except that it implements this in Lisp. This way, our Lisp<>Java interoperability would increase. It would also be an efficient way to guarantee exclusive access when modifying a cross-thread shared resource (such as generic functions).
Comments?
Bye,
Erik.
On Tue, Jul 7, 2009 at 4:30 PM, Erik Huelsmannehuels@gmail.com wrote:
I propose that we introduce a WITH-EXCLUSIVE-ACCESS form in the EXT package, which takes 1 argument (the second value) and a body (the third value). The form makes sure that the body is evaluated as if it had been called with: synchronized (arg1) { body-to-evaluate; } Except that it implements this in Lisp. This way, our Lisp<>Java interoperability would increase. It would also be an efficient way to guarantee exclusive access when modifying a cross-thread shared resource (such as generic functions). Comments?
Sounds good, although WITH-EXCLUSIVE-ACCESS isn't very descriptive to me, I'd go for WITH-THREAD-LOCK. (not WITH-LOCK, because there are many kinds of locks). Just my 0.02. ;)
On Tue, Jul 7, 2009 at 3:49 PM, Ville Voutilainenville.voutilainen@gmail.com wrote:
On Tue, Jul 7, 2009 at 4:30 PM, Erik Huelsmannehuels@gmail.com wrote:
I propose that we introduce a WITH-EXCLUSIVE-ACCESS form in the EXT package, which takes 1 argument (the second value) and a body (the third value). The form makes sure that the body is evaluated as if it had been called with: synchronized (arg1) { body-to-evaluate; } Except that it implements this in Lisp. This way, our Lisp<>Java interoperability would increase. It would also be an efficient way to guarantee exclusive access when modifying a cross-thread shared resource (such as generic functions). Comments?
Sounds good, although WITH-EXCLUSIVE-ACCESS isn't very descriptive to me, I'd go for WITH-THREAD-LOCK. (not WITH-LOCK, because there are many kinds of locks). Just my 0.02. ;)
Do you mean so that Lisp code could be synchronized with Java code on the same object lock? That would be great. It'll need also a Lisp interface to wait(), notify() and company, but this is trivial. About the name, why not SYNCHRONIZED or SYNCHRONIZED-ON or WITH-SYNCHRONIZED-BLOCK or something like those? It's closer to Java terminology that way. But, any of the proposed names are fine by me.
A.
On Jul 7, 2009, at 16:28 , Alessio Stalla wrote:
On Tue, Jul 7, 2009 at 3:49 PM, Ville Voutilainenville.voutilainen@gmail.com wrote:
On Tue, Jul 7, 2009 at 4:30 PM, Erik Huelsmannehuels@gmail.com wrote:
I propose that we introduce a WITH-EXCLUSIVE-ACCESS form in the EXT package, which takes 1 argument (the second value) and a body (the third value). The form makes sure that the body is evaluated as if it had been called with: synchronized (arg1) { body-to-evaluate; } Except that it implements this in Lisp. This way, our Lisp<>Java interoperability would increase. It would also be an efficient way to guarantee exclusive access when modifying a cross-thread shared resource (such as generic functions). Comments?
Sounds good, although WITH-EXCLUSIVE-ACCESS isn't very descriptive to me, I'd go for WITH-THREAD-LOCK. (not WITH-LOCK, because there are many kinds of locks). Just my 0.02. ;)
Do you mean so that Lisp code could be synchronized with Java code on the same object lock? That would be great. It'll need also a Lisp interface to wait(), notify() and company, but this is trivial. About the name, why not SYNCHRONIZED or SYNCHRONIZED-ON or WITH-SYNCHRONIZED-BLOCK or something like those? It's closer to Java terminology that way. But, any of the proposed names are fine by me.
I second that. SYNCHRONIZED-ON or variants look better than the WITH- variants. Also, please do not make the EXT package a kitchen sink. Java thought us to (at least) try to separate things in appropriate namespaces. Choose a special threading-related package name where these thing should be put.
Cheers
-- Marco Antoniotti
On Tue, Jul 7, 2009 at 4:36 PM, Marco Antoniottimarcoxa@cs.nyu.edu wrote:
Also, please do not make the EXT package a kitchen sink. Java thought us to (at least) try to separate things in appropriate namespaces. Choose a special threading-related package name where these thing should be put.
This is very sensible. We should also move to this package all the thread-related stuff that's currently in EXT, and probably make EXT :use the new package for a while to avoid breaking existing code, while deprecating the use of EXT for multithreading stuff.
(this makes me think that I added my little GUI stuff to EXT, too ;) when I manage to include more GUI code, I'll switch to a GUI-dedicated package).
Bye, Alessio
Note, btw, that "synchronized" in java is not only about locking, but also about memory synchronization: the code in the synchronized block is compiled so that other threads see the changes it has made to memory and it sees changes from other threads too. Compiler doesn't cache values in registers or other temporary places.
Example:
(let ((zu 0) (monitor "just a string")) (defun set-zu (val) (synchonized (monitor) (setf zu val))) (defun print-zu () (dotimes (i 10) (synchonized (monitor) (format t "zu: ~A~%" zu)))))
If we want to preserve java "synchronized" semantics, when compiling PRINT-ZU the compiler should not read ZU value only once, cache it in some local variable, and the use this local to as an argument to FORMAT in DOTIMES.
Not sure whether this requirement complicates "synchronized" implementation for ABCL.
Best regards, - Anton
On Wed, Jul 8, 2009 at 12:36 AM, Anton Vodonosovavodonosov@gmail.com wrote:
Note, btw, that "synchronized" in java is not only about locking, but also about memory synchronization: the code in the synchronized block is compiled so that other threads see the changes it has made to memory and it sees changes from other threads too. Compiler doesn't cache values in registers or other temporary places.
I just read
http://java.sun.com/docs/books/tutorial/essential/concurrency/syncmeth.html
Which says
"Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads. "
The memory changes are committed (just) before a synch block exits. Not necessarily during the block. Thus I think the caching is allowed. That thought is further supported by
http://java.sun.com/docs/books/tutorial/essential/concurrency/memconsist.htm...
Of course I may be wrong - but I'd be somewhat surprised if all memory memory access is volatile (in the C sense) during a synchronized block. That would take an enormous perf hit on multi-cpu systems with IPIs and such.
2009/7/8 Ville Voutilainen ville.voutilainen@gmail.com:
Of course I may be wrong - but I'd be somewhat surprised if all memory memory access is volatile (in the C sense) during a synchronized block. That would take an enormous perf hit on multi-cpu systems with IPIs and such.
Not during a block of course. That's why in my example SYNCHRONIZED is _inside_ of the DOTIMES.
Formal specification is here http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.4.
Again, not sure if memory synchronization semantics of "synchronized" is a problem for ABCL impl. Maybe no difficulties arise from that. Just wanted to remind that sycnrhonized is not just an API call to some locking method.
Best regards, -Anton
armedbear-devel@common-lisp.net