On Thu, 24 Dec 2009 08:13:53 +0300, Andrei Alexandrescu <[email protected]> wrote:

Jason House wrote:
Andrei Alexandrescu wrote:

Jason House wrote:
Andrei Alexandrescu Wrote:

But let's not forget we have concurrency ahead of us. I encourage you
all to chime in with your thoughts and ideas regarding all aspects of
concurrency. The recent multicore performance bug is a great starting
point. If you try e.g. shared and it's broken, let us know. If you try it and it works, push it til it breaks. If you have ideas on how to make
semantic checking better, pipe up.
I posted several shared issues to the NG a few days ago and got no
replies. Most of it was about poor error messages (both misleading text and missing file/line numbers). I should do proper bugzilla entries but
haven't tinkered with D much since. As always, this post comes from my
phone instead of a proper computer, or else I'd provide a link or do the
bugzilla entries while I'm thinking of it.

IIRC, the most troublesome error happened when I created "shared
this(){...}" constructor and no information on where it caused errors.
Thanks, Jason. I did see those messages but I didn't want to dilute
focus back when you posted them.

If you could put together bugzilla entries as you try things, that would
be great. The shared constructor I'll experiment with first.
I have reproduced and reported most of the issue I had hit with shared. If it's any consolation, I was able to convert my message passing queues to use shared, but hit issues when expanding to cover other uses of shared data within my code base. There may also be an issue with what a shared delegate is supposed to be and what can be inside of one, but I haven't really worried about that too much. It's a hairy issue and partly my fault for using delegates as messages between threads. When sending a message, I cast the delegate to a shared delegate even though it access immutable data and has no side effect except on thread-local data in the receiving thread.
 bugzilla 3640
     shared this() constructor does not work and reports strange errors
     without line numbers
 bugzilla 3641 keywords: rejects-valid
    alias shared T U does not work
 bugzilla 3642 keywords: diagnostic
Poor error message when using shared: function ___ not callable with argument types ___


Great. I just got word from Walter that he fixed a lot of shared bugs (most reported and some probably not yet reported), so I expect the situation to get considerably better with the next minor release.

Andrei

I'll add my experience with shared/local separation.

Shared/local as it is now relies solely on convention. For example, I have wrote a large heavily-multithreaded application in D2 without any use of shared (i.e. everything is "local", yet pointers are freely passed among threads).

This is because stdlib is not shared aware at all, starting with druntime: thread creation is "broken" in a sense that it allows passing local this pointer through delegate to another thread:

class Foo {
    void bar() { /* do stuff */ }
    void createNewThread() {
auto thread = new Thread(&bar); // local this pointer is bound to delegate thread.start(); // "this" is now accessible from 2 different threads (current one, and a new one)
    }
}

A simple fix would be to disallow starting a new thread with a delegate, allowing free function pointers only. Other options would be to introduce "shared delegates" - a delegate that has shared context pointer.

I'd suggest starting with fixing signatures of those OS API functions that deal with creating new thread. For example, there are _beginthreadex (Windows) and pthread_create (POSIX) functions that are declared in druntime roughly like this:

extern (C) uintptr_t _beginthreadex(void* /+security,+/, uint /+stack_size+/, uint function(void*) /+start_routine+/, void* /+arg+/, uint /+initflag+/, uint* /+thrdaddr+/); // added variable names to make it more clear

int pthread_create(pthread_t* /+thread+/, in pthread_attr_t* /+attr+/, void* function(void*) /+start_routine+/, void* /+arg+/);

(there are a lot more functions like this, of course)

Variable arg is passed from one thread to another, and thus *must* be marked as shared (or unique). The same applies to start_routine (should be "void function(shared void*) start_routine" instead).

This will break a lot of code but will at least try to enforce program correctness.

Reply via email to