www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - propsal: inclusion of wait/notify threading code 'somewhere'

reply Mike Swieton <mike swieton.net> writes:
I'd like to propose that a java-style wait-notify ability in D somewhere.
Ben Hinkle has already implemented it in the port of Doug Lea's concurrent
programming library (see the site on dsource).

The rationale for inclusion into Phobos, or maybe even somewhere more
integrated is this: it requires some very dirty, behind-the-scenes magic to
make this work. Consider this brief summary of the Linux implementation:

- Cast the object waited on to its internal representation (to get access to
	the object monitor mutex)
- Stick a hand up the mutex and reset the recursion count to 1. No APIs are
	exposed to do this, so it is done by reaching into the structure's
	theoretically private parts (of course, C structs have no real concept of
	private, but we're definitely treading in a no-man's land here)
- Wait on a pthread condition variable and the object monitor mutex
- After the wait returns, reset the recursion count of the mutex and return.

There's a couple more details in there, but that's the gist of it. This is
rather dirty. I think that this sort of back-door stuff should not be in a
'user' library, because of all of this black magic. It seems to me to 1)
depend on implementation details not necessarily guaranteed, and 2) be
fragile.

I can't really suggest a good place for the code to go: I don't know that it's
a good idea to place the code in Object, because that makes Object bigger,
along with adding dependencies. Of course, Object has the monitor already.

Any comments on this?

Mike Swieton
__
Brutes find out where their talents lie; a bear will not attempt to fly.
	- Jonathan Swift
May 24 2004
next sibling parent "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
Mike,

Your description is both most apt and amusing. I fully agree that this
should preferably be somewhere other than user-land, for all the reasons you
state.

If Object were to lose the darned print() method, that would open up some
"room" without making it any "bigger" :-)

- Kris

"Mike Swieton" <mike swieton.net> wrote in message
news:pan.2004.05.25.00.49.42.542254 swieton.net...
 I'd like to propose that a java-style wait-notify ability in D somewhere.
 Ben Hinkle has already implemented it in the port of Doug Lea's concurrent
 programming library (see the site on dsource).

 The rationale for inclusion into Phobos, or maybe even somewhere more
 integrated is this: it requires some very dirty, behind-the-scenes magic
to
 make this work. Consider this brief summary of the Linux implementation:

 - Cast the object waited on to its internal representation (to get access
to
 the object monitor mutex)
 - Stick a hand up the mutex and reset the recursion count to 1. No APIs
are
 exposed to do this, so it is done by reaching into the structure's
 theoretically private parts (of course, C structs have no real concept of
 private, but we're definitely treading in a no-man's land here)
 - Wait on a pthread condition variable and the object monitor mutex
 - After the wait returns, reset the recursion count of the mutex and
return.
 There's a couple more details in there, but that's the gist of it. This is
 rather dirty. I think that this sort of back-door stuff should not be in a
 'user' library, because of all of this black magic. It seems to me to 1)
 depend on implementation details not necessarily guaranteed, and 2) be
 fragile.

 I can't really suggest a good place for the code to go: I don't know that
it's
 a good idea to place the code in Object, because that makes Object bigger,
 along with adding dependencies. Of course, Object has the monitor already.

 Any comments on this?

 Mike Swieton
 __
 Brutes find out where their talents lie; a bear will not attempt to fly.
 - Jonathan Swift
May 24 2004
prev sibling parent reply Sean Kelly <sean f4.ca> writes:
In article <pan.2004.05.25.00.49.42.542254 swieton.net>, Mike Swieton says...
I'd like to propose that a java-style wait-notify ability in D somewhere.
Ben Hinkle has already implemented it in the port of Doug Lea's concurrent
programming library (see the site on dsource).
At the very least I'd like to see a condvar implementation in Phobos. I had been planning on working on it myself but for a lack of free time. One of the problems I see is that AFAIK nothing written in D can coordinate with the existing "synchronized" keyword (ie. the hidden mutex it uses), so Phobos would also have to contain its own mutex and other primitives to work. And this seems like a pointless redundancy. This being the case it would be nice if this hidden mutex were exposed somehow or if condvars and such made it into D itself via some new keywords.
The rationale for inclusion into Phobos, or maybe even somewhere more
integrated is this: it requires some very dirty, behind-the-scenes magic to
make this work. Consider this brief summary of the Linux implementation:

- Cast the object waited on to its internal representation (to get access to
	the object monitor mutex)
Not really necessary. Assuming this library contains a list of mutexes and condvars somewhere they could be uniquely identified using the toHash method provided by all D variables.
- Stick a hand up the mutex and reset the recursion count to 1. No APIs are
	exposed to do this, so it is done by reaching into the structure's
	theoretically private parts (of course, C structs have no real concept of
	private, but we're definitely treading in a no-man's land here)
No we're not. This is the official way to use pthread condvars.
- Wait on a pthread condition variable and the object monitor mutex
- After the wait returns, reset the recursion count of the mutex and return.

There's a couple more details in there, but that's the gist of it. This is
rather dirty. I think that this sort of back-door stuff should not be in a
'user' library, because of all of this black magic. It seems to me to 1)
depend on implementation details not necessarily guaranteed, and 2) be
fragile.
Comments aside, I completely agree. Thread synchronization is far too complex for even many competent programmers to handle correctly. And to do so portably is even harder--condvars don't exist in Windows and to replicate them requires a very complex hack involving multiple synchronization primitives. Check the source code in Boost sometime if you're so inclined. I've also got a public domain version of the algorithm if there are licensing concerns and we don't have any reference material for that bit of the port.
I can't really suggest a good place for the code to go: I don't know that it's
a good idea to place the code in Object, because that makes Object bigger,
along with adding dependencies. Of course, Object has the monitor already.
Personally, I hate the idea of a universal base Object class. It promotes the Java mentality that things should be casted to this base type when using containers. That aside, I don't see much of a need to add anything to Object itself, unless perhaps complete language integration occurs (new keywords). I'd suggest putting this all in Phobos, but it really has to be discussed a bit more to sort out the details. Sean
May 25 2004
parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
"Sean Kelly" <sean f4.ca> wrote in message
news:c8vs3u$1ed4$1 digitaldaemon.com...
 In article <pan.2004.05.25.00.49.42.542254 swieton.net>, Mike Swieton
says...
I'd like to propose that a java-style wait-notify ability in D somewhere.
Ben Hinkle has already implemented it in the port of Doug Lea's
concurrent
programming library (see the site on dsource).
At the very least I'd like to see a condvar implementation in Phobos. I
had
 been planning on working on it myself but for a lack of free time.  One of
the
 problems I see is that AFAIK nothing written in D can coordinate with the
 existing "synchronized" keyword (ie. the hidden mutex it uses), so Phobos
would
 also have to contain its own mutex and other primitives to work.  And this
seems
 like a pointless redundancy.  This being the case it would be nice if this
 hidden mutex were exposed somehow or if condvars and such made it into D
itself
 via some new keywords.
The dsource code uses the internal "synchronized" mutex which is why Mike is suggesting making it more "official". I agree it is unfortunate to have compiler-dependent parts to a threading library so it would be nice to get those files into phobos somewhere.
The rationale for inclusion into Phobos, or maybe even somewhere more
integrated is this: it requires some very dirty, behind-the-scenes magic
to
make this work. Consider this brief summary of the Linux implementation:

- Cast the object waited on to its internal representation (to get access
to
 the object monitor mutex)
Not really necessary. Assuming this library contains a list of mutexes
and
 condvars somewhere they could be uniquely identified using the toHash
method
 provided by all D variables.

- Stick a hand up the mutex and reset the recursion count to 1. No APIs
are
 exposed to do this, so it is done by reaching into the structure's
 theoretically private parts (of course, C structs have no real concept
of
 private, but we're definitely treading in a no-man's land here)
No we're not. This is the official way to use pthread condvars.
It is official? That's a relief. My hand still feels a little icky though. :-P
- Wait on a pthread condition variable and the object monitor mutex
- After the wait returns, reset the recursion count of the mutex and
return.
There's a couple more details in there, but that's the gist of it. This
is
rather dirty. I think that this sort of back-door stuff should not be in
a
'user' library, because of all of this black magic. It seems to me to 1)
depend on implementation details not necessarily guaranteed, and 2) be
fragile.
Comments aside, I completely agree. Thread synchronization is far too
complex
 for even many competent programmers to handle correctly.  And to do so
portably
 is even harder--condvars don't exist in Windows and to replicate them
requires a
 very complex hack involving multiple synchronization primitives.  Check
the
 source code in Boost sometime if you're so inclined.  I've also got a
public
 domain version of the algorithm if there are licensing concerns and we
don't
 have any reference material for that bit of the port.
I'm not convinced it's worth it to implement a POSIX condvar on Windows. Like you say it is a mess and the performance probably is worse than simpler constructs. The code on dsource doesn't implement a full-blown atomic condvar but instead has one mixin for notify (signal) and another for notifyAll (broadcast). It is not atomic since the LockCount is separate from the LockSemaphore in a CriticalSection. I'm in the process of getting performance tests in place to compare this approach with Java and hopefully some C POSIX condvar implementations out there.
I can't really suggest a good place for the code to go: I don't know that
it's
a good idea to place the code in Object, because that makes Object
bigger,
along with adding dependencies. Of course, Object has the monitor
already.
 Personally, I hate the idea of a universal base Object class.  It promotes
the
 Java mentality that things should be casted to this base type when using
 containers.  That aside, I don't see much of a need to add anything to
Object
 itself, unless perhaps complete language integration occurs (new
keywords). I'd
 suggest putting this all in Phobos, but it really has to be discussed a
bit more
 to sort out the details.
If the API is put into Object then it would have to be a full-blown condvar assuming both notify and notifyAll are implemented. Since synchronization constructs vary quiet a bit between Windows and Unix I think it would be trouble trying to put everything into Object. Putting it in Phobos is a good idea since it is compiler-dependent, but an argument for not putting it in Phobos is that users might want to use standalone threading libraries like http://sources.redhat.com/pthreads-win32/ or Boost or something like that.
 Sean
May 25 2004
parent reply Sean Kelly <sean f4.ca> writes:
In article <c904sk$1sgb$1 digitaldaemon.com>, Ben Hinkle says...
"Sean Kelly" <sean f4.ca> wrote in message
news:c8vs3u$1ed4$1 digitaldaemon.com...

The dsource code uses the internal "synchronized" mutex which is why Mike is
suggesting making it more "official". I agree it is unfortunate to have
compiler-dependent parts to a threading library so it would be nice to get
those files into phobos somewhere.
Excellent. In this case it should really be "official" then, assuming the design is approved and such.
 No we're not.  This is the official way to use pthread condvars.
It is official? That's a relief. My hand still feels a little icky though. :-P
I should qualify that by saying that I haven't looked at the dsource, I'm only speaking from memory about how condvars work.
I'm not convinced it's worth it to implement a POSIX condvar on Windows.
Like you say it is a mess and the performance probably is worse than simpler
constructs. The code on dsource doesn't implement a full-blown atomic
condvar but instead has one mixin for notify (signal) and another for
notifyAll (broadcast). It is not atomic since the LockCount is separate from
the LockSemaphore in a CriticalSection. I'm in the process of getting
performance tests in place to compare this approach with Java and hopefully
some C POSIX condvar implementations out there.
Assuming this is a candidate for Phobos, I would very much like to see a condvar implementation included for Windows. It certainly isn't easy, which is why I'd prefer to have an official version out there. And once that's done, making atomic signal and broadcast mechanisms is not too difficult. To me it's really an all or nothing argument. Either we make no claims of atomicity regardless of platform, or we do our best to gurantee it on all platforms. The alternative is code whose behavior changes depending on the OS it's compiled and run on, which would hurt D's claims of portability. Plus, high-end threading support in D would help distinguish it both from Java and from C++. That said, I'd much rather have something than nothing :)
If the API is put into Object then it would have to be a full-blown condvar
assuming both notify and notifyAll are implemented. Since synchronization
constructs vary quiet a bit between Windows and Unix I think it would be
trouble trying to put everything into Object. Putting it in Phobos is a good
idea since it is compiler-dependent, but an argument for not putting it in
Phobos is that users might want to use standalone threading libraries like
http://sources.redhat.com/pthreads-win32/ or Boost or something like that.
They still could, by simply not using the "synchronized" and other keywords D supplies. Though if what's built into D is good enough then I would be surprised if many people searched for other libraries. I'm still undecided, but I think the presence of "synchronized" in the language implies that threading is supported at the language level. If that means adding code to Object then so be it. But this is all speculative. How soon before we get to play with the implementation you're working on? :) Sean
May 25 2004
parent "Ben Hinkle" <bhinkle mathworks.com> writes:
  How soon before we get to play with the implementation you're working on?
:) The best way to play with the wait/notify support is to download the files http://svn.dsource.org/svn/projects/concurrent/concurrent/waitnotify.d and http://svn.dsource.org/svn/projects/concurrent/concurrent/waitnotifyimpl.d I should make another zip file and ask Brad to update the Downloads section. Mike has been contributing, too, and we are getting close to having all the major pieces done. The only remaining area is the Fork/Join Task code for lightweight threading tasks and I wanted to get some performance data. -Ben
May 25 2004