Thread overview
propsal: inclusion of wait/notify threading code 'somewhere'
May 25, 2004
Mike Swieton
May 25, 2004
Kris
May 25, 2004
Sean Kelly
May 25, 2004
Ben Hinkle
May 25, 2004
Sean Kelly
May 25, 2004
Ben Hinkle
May 25, 2004
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 25, 2004
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 25, 2004
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
"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
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
>  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