July 02, 2010 [phobos] Typo (bug) in std.concurrency | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Hm... and then the mutex and condition variable in MessageBox would be declared as shared and I suppose everything would work. I was worried that making Mutex shared, for example, would add synchronized loads every time a handle was used, but it looks like I'm wrong. I can't recall what rule was provided for where synchronization is used for shared concrete variables... can someone refresh my memory? For example, the following code has no synchronized ops at all:
import std.stdio;
class Mutex
{
shared void lock() {
if (x == 0)
x = 1;
}
int x;
}
void main()
{
shared(Mutex) m = new shared(Mutex);
m.lock();
}
__Dmain:
push EBP
mov EBP,ESP
sub ESP,8
call LB
LB: pop EAX
sub ESP,0Ch
push dword ptr 0EDh[EAX]
call L174
add ESP,010h
mov ECX,[EAX]
call dword ptr 018h[ECX]
xor EAX,EAX
leave
ret
_D5ytest5Mutex4lockMOFZv:
push EBP
mov EBP,ESP
sub ESP,8
mov -4[EBP],EAX
call LA5
mov EAX,-4[EBP]
cmp dword ptr 8[EAX],0
jne L21
mov ECX,-4[EBP]
mov dword ptr 8[ECX],1
L21: leave
ret
nop
I was worried I'd see a synchronized load when m.lock() was called and a synchronized load and/or store when x is accessed. Is the current behavior a bug? On x86, stores aren't reordered with other stores and loads aren't (supposed to be) reordered with other loads, but loads can be reordered to occur before preceding stores. Does that mean I'll only see a memory barrier when I'm interleaving shared loads and stores?
On Jul 2, 2010, at 11:50 AM, Andrei Alexandrescu wrote:
> I think we should bite the bullet and mark the signatures as shared.
>
> Andrei
>
> Sean Kelly wrote:
>> As I'd feared, this is getting more and more complicated. I tried making the lock() and unlock() methods in Mutex shared and now I'm getting these errors:
>> xtest.d(98): Error: function core.sys.posix.pthread.pthread_mutex_lock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*)
>> xtest.d(98): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t*
>> xtest.d(120): Error: function core.sys.posix.pthread.pthread_mutex_unlock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*)
>> xtest.d(120): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t*
>> xtest.d(146): Error: function core.sys.posix.pthread.pthread_mutex_trylock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*)
>> xtest.d(146): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t*
>> While technically correct, I find this behavior quite frustrating. I suppose I could go through the Posix API and mark all the thread stuff as shared to make sure it will compile correctly, but that would break any existing code that is using this stuff in an unshared data type (ie. basically everyone), and since these are extern (C) routines I can't overload them on shared either. The simplest alternative fix I've found so far is basically what I described below:
>> class Mutex
>> {
>> shared void lock()
>> {
>> (cast(Mutex) this).doLock();
>> }
>> private void doLock()
>> {
>> // lock the mutex
>> }
>> }
>> I'm coming to wish there were a way to tell the compiler "this is part of the TCB, shut up, I know what I'm doing."
>> I think for the next release I'm simply going to allow sending Tid instances regardless of whether they contain an unshared reference so I can have more time to figure out the best way to handle this.
>> On Jun 30, 2010, at 1:37 PM, Sean Kelly wrote:
>>> Okay, alternate evil solution:
>>>
>>> class Condition
>>> {
>>> shared void notify()
>>> {
>>> static void doNotify() {}
>>> (cast(Condition) this).doNotify();
>>> }
>>> }
>>>
>>> Seems like it should work, though I'm hoping that the classes in core.sync are about the only ones where it's necessary (something similar will probably be necessary for Mutex to make lock() and unlock() explicitly callable, etc). I'm half tempted to try labeling these functions as __gshared and see if it compiles.
>>>
>>> On Jun 30, 2010, at 1:24 PM, Sean Kelly wrote:
>>>
>>>> Well that was a disaster. I have this:
>>>>
>>>> class MessageBox
>>>> {
>>>> this()
>>>> {
>>>> // this makes m_lock the monitor for the MessageBox instance.
>>>> m_lock = new Mutex( this );
>>>> m_cond = new Condition( m_lock );
>>>> }
>>>>
>>>> final synchronized void put( Message msg )
>>>> {
>>>> // m_lock is locked now
>>>> m_list.add( msg );
>>>> m_cond.notify(); // error: notify () is not callable using argument types () shared
>>>> }
>>>> }
>>>>
>>>> struct Tid
>>>> {
>>>> shared MessageBox mbox;
>>>> }
>>>>
>>>> class Condition
>>>> {
>>>> void notify()
>>>> {
>>>> // fancy stuff involving semaphores
>>>> }
>>>> }
>>>>
>>>> How do I fix this? Condition.notify() is technically shared, but I don't want to pay the cost for memory barriers that are utterly pointless. Should I change the call to notify() to:
>>>>
>>>> (cast(Condition)m_cond).notify();
>>>>
>>>> This should work, but it seems like an even worse subversion of the shared system than I'm already doing for MessageBox. If it helps, MessageBox is a thread-local class instance with put() as its one shared public method, so other threads have a shared reference to MessageBox while the object's owner has a non-shared reference to it. This is functionally correct, though it seems theoretically wrong to have both shared and unshared references to the same instance in the first place.
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
|
July 02, 2010 [phobos] Typo (bug) in std.concurrency | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | FWIW, I changed std.concurrency to allow Tid to be included in a send() until this is sorted out correctly. Please let me know if there are any remaining problems with functionality.
On Jul 2, 2010, at 11:49 AM, Sean Kelly wrote:
> As I'd feared, this is getting more and more complicated. I tried making the lock() and unlock() methods in Mutex shared and now I'm getting these errors:
>
> xtest.d(98): Error: function core.sys.posix.pthread.pthread_mutex_lock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*)
> xtest.d(98): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t*
> xtest.d(120): Error: function core.sys.posix.pthread.pthread_mutex_unlock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*)
> xtest.d(120): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t*
> xtest.d(146): Error: function core.sys.posix.pthread.pthread_mutex_trylock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*)
> xtest.d(146): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t*
>
> While technically correct, I find this behavior quite frustrating. I suppose I could go through the Posix API and mark all the thread stuff as shared to make sure it will compile correctly, but that would break any existing code that is using this stuff in an unshared data type (ie. basically everyone), and since these are extern (C) routines I can't overload them on shared either. The simplest alternative fix I've found so far is basically what I described below:
>
> class Mutex
> {
> shared void lock()
> {
> (cast(Mutex) this).doLock();
> }
>
> private void doLock()
> {
> // lock the mutex
> }
> }
>
> I'm coming to wish there were a way to tell the compiler "this is part of the TCB, shut up, I know what I'm doing."
>
> I think for the next release I'm simply going to allow sending Tid instances regardless of whether they contain an unshared reference so I can have more time to figure out the best way to handle this.
>
> On Jun 30, 2010, at 1:37 PM, Sean Kelly wrote:
>
>> Okay, alternate evil solution:
>>
>> class Condition
>> {
>> shared void notify()
>> {
>> static void doNotify() {}
>> (cast(Condition) this).doNotify();
>> }
>> }
>>
>> Seems like it should work, though I'm hoping that the classes in core.sync are about the only ones where it's necessary (something similar will probably be necessary for Mutex to make lock() and unlock() explicitly callable, etc). I'm half tempted to try labeling these functions as __gshared and see if it compiles.
>>
>> On Jun 30, 2010, at 1:24 PM, Sean Kelly wrote:
>>
>>> Well that was a disaster. I have this:
>>>
>>> class MessageBox
>>> {
>>> this()
>>> {
>>> // this makes m_lock the monitor for the MessageBox instance.
>>> m_lock = new Mutex( this );
>>> m_cond = new Condition( m_lock );
>>> }
>>>
>>> final synchronized void put( Message msg )
>>> {
>>> // m_lock is locked now
>>> m_list.add( msg );
>>> m_cond.notify(); // error: notify () is not callable using argument types () shared
>>> }
>>> }
>>>
>>> struct Tid
>>> {
>>> shared MessageBox mbox;
>>> }
>>>
>>> class Condition
>>> {
>>> void notify()
>>> {
>>> // fancy stuff involving semaphores
>>> }
>>> }
>>>
>>> How do I fix this? Condition.notify() is technically shared, but I don't want to pay the cost for memory barriers that are utterly pointless. Should I change the call to notify() to:
>>>
>>> (cast(Condition)m_cond).notify();
>>>
>>> This should work, but it seems like an even worse subversion of the shared system than I'm already doing for MessageBox. If it helps, MessageBox is a thread-local class instance with put() as its one shared public method, so other threads have a shared reference to MessageBox while the object's owner has a non-shared reference to it. This is functionally correct, though it seems theoretically wrong to have both shared and unshared references to the same instance in the first place.
>
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
|
July 02, 2010 [phobos] Typo (bug) in std.concurrency | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | On Jul 2, 2010, at 12:46 PM, Sean Kelly wrote:
> Hm... and then the mutex and condition variable in MessageBox would be declared as shared and I suppose everything would work. I was worried that making Mutex shared, for example, would add synchronized loads every time a handle was used, but it looks like I'm wrong. I can't recall what rule was provided for where synchronization is used for shared concrete variables... can someone refresh my memory? For example, the following code has no synchronized ops at all
I suppose the other option is that the compiler is already doing a lot more static analysis than I expected. Any chance this is it?
|
July 02, 2010 [phobos] Typo (bug) in std.concurrency | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Wouldn't it be better to just redefine pthread_mutex_t to always be a shared type? Something like: struct pthread_mutex {...} alias shared(pthread_mutex) pthread_mutex_t; or perhaps: shared struct phtread_mutex_t {...} Le 2010-07-02 ? 14:50, Andrei Alexandrescu a ?crit : > I think we should bite the bullet and mark the signatures as shared. > > Andrei > > Sean Kelly wrote: >> As I'd feared, this is getting more and more complicated. I tried making the lock() and unlock() methods in Mutex shared and now I'm getting these errors: >> xtest.d(98): Error: function core.sys.posix.pthread.pthread_mutex_lock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*) >> xtest.d(98): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t* >> xtest.d(120): Error: function core.sys.posix.pthread.pthread_mutex_unlock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*) >> xtest.d(120): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t* >> xtest.d(146): Error: function core.sys.posix.pthread.pthread_mutex_trylock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*) >> xtest.d(146): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t* >> While technically correct, I find this behavior quite frustrating. I suppose I could go through the Posix API and mark all the thread stuff as shared to make sure it will compile correctly, but that would break any existing code that is using this stuff in an unshared data type (ie. basically everyone), and since these are extern (C) routines I can't overload them on shared either. The simplest alternative fix I've found so far is basically what I described below: >> class Mutex >> { >> shared void lock() >> { >> (cast(Mutex) this).doLock(); >> } >> private void doLock() >> { >> // lock the mutex >> } >> } >> I'm coming to wish there were a way to tell the compiler "this is part of the TCB, shut up, I know what I'm doing." >> I think for the next release I'm simply going to allow sending Tid instances regardless of whether they contain an unshared reference so I can have more time to figure out the best way to handle this. >> On Jun 30, 2010, at 1:37 PM, Sean Kelly wrote: >>> Okay, alternate evil solution: >>> >>> class Condition >>> { >>> shared void notify() >>> { >>> static void doNotify() {} >>> (cast(Condition) this).doNotify(); >>> } >>> } >>> >>> Seems like it should work, though I'm hoping that the classes in core.sync are about the only ones where it's necessary (something similar will probably be necessary for Mutex to make lock() and unlock() explicitly callable, etc). I'm half tempted to try labeling these functions as __gshared and see if it compiles. >>> >>> On Jun 30, 2010, at 1:24 PM, Sean Kelly wrote: >>> >>>> Well that was a disaster. I have this: >>>> >>>> class MessageBox >>>> { >>>> this() >>>> { >>>> // this makes m_lock the monitor for the MessageBox instance. >>>> m_lock = new Mutex( this ); >>>> m_cond = new Condition( m_lock ); >>>> } >>>> >>>> final synchronized void put( Message msg ) >>>> { >>>> // m_lock is locked now >>>> m_list.add( msg ); >>>> m_cond.notify(); // error: notify () is not callable using argument types () shared >>>> } >>>> } >>>> >>>> struct Tid >>>> { >>>> shared MessageBox mbox; >>>> } >>>> >>>> class Condition >>>> { >>>> void notify() >>>> { >>>> // fancy stuff involving semaphores >>>> } >>>> } >>>> >>>> How do I fix this? Condition.notify() is technically shared, but I don't want to pay the cost for memory barriers that are utterly pointless. Should I change the call to notify() to: >>>> >>>> (cast(Condition)m_cond).notify(); >>>> >>>> This should work, but it seems like an even worse subversion of the shared system than I'm already doing for MessageBox. If it helps, MessageBox is a thread-local class instance with put() as its one shared public method, so other threads have a shared reference to MessageBox while the object's owner has a non-shared reference to it. This is functionally correct, though it seems theoretically wrong to have both shared and unshared references to the same instance in the first place. >> _______________________________________________ >> phobos mailing list >> phobos at puremagic.com >> http://lists.puremagic.com/mailman/listinfo/phobos > _______________________________________________ > phobos mailing list > phobos at puremagic.com > http://lists.puremagic.com/mailman/listinfo/phobos -- Michel Fortin michel.fortin at michelf.com http://michelf.com/ |
July 02, 2010 [phobos] Typo (bug) in std.concurrency | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michel Fortin | Yeah. I'll need to change a bunch of the defs that way. Less clear is how to deal with the Windows defs, since everything is just a handle. I'm inclined to change HANDLE from void* to size_t.
On Jul 2, 2010, at 1:31 PM, Michel Fortin wrote:
> Wouldn't it be better to just redefine pthread_mutex_t to always be a shared type? Something like:
>
> struct pthread_mutex {...}
> alias shared(pthread_mutex) pthread_mutex_t;
>
> or perhaps:
>
> shared struct phtread_mutex_t {...}
>
>
> Le 2010-07-02 ? 14:50, Andrei Alexandrescu a ?crit :
>
>> I think we should bite the bullet and mark the signatures as shared.
>>
>> Andrei
>>
>> Sean Kelly wrote:
>>> As I'd feared, this is getting more and more complicated. I tried making the lock() and unlock() methods in Mutex shared and now I'm getting these errors:
>>> xtest.d(98): Error: function core.sys.posix.pthread.pthread_mutex_lock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*)
>>> xtest.d(98): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t*
>>> xtest.d(120): Error: function core.sys.posix.pthread.pthread_mutex_unlock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*)
>>> xtest.d(120): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t*
>>> xtest.d(146): Error: function core.sys.posix.pthread.pthread_mutex_trylock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*)
>>> xtest.d(146): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t*
>>> While technically correct, I find this behavior quite frustrating. I suppose I could go through the Posix API and mark all the thread stuff as shared to make sure it will compile correctly, but that would break any existing code that is using this stuff in an unshared data type (ie. basically everyone), and since these are extern (C) routines I can't overload them on shared either. The simplest alternative fix I've found so far is basically what I described below:
>>> class Mutex
>>> {
>>> shared void lock()
>>> {
>>> (cast(Mutex) this).doLock();
>>> }
>>> private void doLock()
>>> {
>>> // lock the mutex
>>> }
>>> }
>>> I'm coming to wish there were a way to tell the compiler "this is part of the TCB, shut up, I know what I'm doing."
>>> I think for the next release I'm simply going to allow sending Tid instances regardless of whether they contain an unshared reference so I can have more time to figure out the best way to handle this.
>>> On Jun 30, 2010, at 1:37 PM, Sean Kelly wrote:
>>>> Okay, alternate evil solution:
>>>>
>>>> class Condition
>>>> {
>>>> shared void notify()
>>>> {
>>>> static void doNotify() {}
>>>> (cast(Condition) this).doNotify();
>>>> }
>>>> }
>>>>
>>>> Seems like it should work, though I'm hoping that the classes in core.sync are about the only ones where it's necessary (something similar will probably be necessary for Mutex to make lock() and unlock() explicitly callable, etc). I'm half tempted to try labeling these functions as __gshared and see if it compiles.
>>>>
>>>> On Jun 30, 2010, at 1:24 PM, Sean Kelly wrote:
>>>>
>>>>> Well that was a disaster. I have this:
>>>>>
>>>>> class MessageBox
>>>>> {
>>>>> this()
>>>>> {
>>>>> // this makes m_lock the monitor for the MessageBox instance.
>>>>> m_lock = new Mutex( this );
>>>>> m_cond = new Condition( m_lock );
>>>>> }
>>>>>
>>>>> final synchronized void put( Message msg )
>>>>> {
>>>>> // m_lock is locked now
>>>>> m_list.add( msg );
>>>>> m_cond.notify(); // error: notify () is not callable using argument types () shared
>>>>> }
>>>>> }
>>>>>
>>>>> struct Tid
>>>>> {
>>>>> shared MessageBox mbox;
>>>>> }
>>>>>
>>>>> class Condition
>>>>> {
>>>>> void notify()
>>>>> {
>>>>> // fancy stuff involving semaphores
>>>>> }
>>>>> }
>>>>>
>>>>> How do I fix this? Condition.notify() is technically shared, but I don't want to pay the cost for memory barriers that are utterly pointless. Should I change the call to notify() to:
>>>>>
>>>>> (cast(Condition)m_cond).notify();
>>>>>
>>>>> This should work, but it seems like an even worse subversion of the shared system than I'm already doing for MessageBox. If it helps, MessageBox is a thread-local class instance with put() as its one shared public method, so other threads have a shared reference to MessageBox while the object's owner has a non-shared reference to it. This is functionally correct, though it seems theoretically wrong to have both shared and unshared references to the same instance in the first place.
>>> _______________________________________________
>>> phobos mailing list
>>> phobos at puremagic.com
>>> http://lists.puremagic.com/mailman/listinfo/phobos
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
>
> --
> Michel Fortin
> michel.fortin at michelf.com
> http://michelf.com/
>
>
>
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
|
July 06, 2010 [phobos] Typo (bug) in std.concurrency | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | I'm giving this a shot. Ran into a compiler bug that I'm investigating:
dmd -c -d -o- -Isrc -Iimport -Hfimport/core/sync/barrier.di src/core/sync/barrier.d
Assertion failed: (tn->mod & MODimmutable || tn->mod & MODshared), function check, file mtype.c, line 879.
I labeled all the classes in core.sync as "shared class Blah", which seems to be the problem.
On Jul 2, 2010, at 11:50 AM, Andrei Alexandrescu wrote:
> I think we should bite the bullet and mark the signatures as shared.
>
> Andrei
>
> Sean Kelly wrote:
>> As I'd feared, this is getting more and more complicated. I tried making the lock() and unlock() methods in Mutex shared and now I'm getting these errors:
>> xtest.d(98): Error: function core.sys.posix.pthread.pthread_mutex_lock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*)
>> xtest.d(98): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t*
>> xtest.d(120): Error: function core.sys.posix.pthread.pthread_mutex_unlock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*)
>> xtest.d(120): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t*
>> xtest.d(146): Error: function core.sys.posix.pthread.pthread_mutex_trylock (pthread_mutex_t*) is not callable using argument types (shared(pthread_mutex_t)*)
>> xtest.d(146): Error: cannot implicitly convert expression (&this.m_hndl) of type shared(pthread_mutex_t)* to pthread_mutex_t*
>> While technically correct, I find this behavior quite frustrating. I suppose I could go through the Posix API and mark all the thread stuff as shared to make sure it will compile correctly, but that would break any existing code that is using this stuff in an unshared data type (ie. basically everyone), and since these are extern (C) routines I can't overload them on shared either. The simplest alternative fix I've found so far is basically what I described below:
>> class Mutex
>> {
>> shared void lock()
>> {
>> (cast(Mutex) this).doLock();
>> }
>> private void doLock()
>> {
>> // lock the mutex
>> }
>> }
>> I'm coming to wish there were a way to tell the compiler "this is part of the TCB, shut up, I know what I'm doing."
>> I think for the next release I'm simply going to allow sending Tid instances regardless of whether they contain an unshared reference so I can have more time to figure out the best way to handle this.
>> On Jun 30, 2010, at 1:37 PM, Sean Kelly wrote:
>>> Okay, alternate evil solution:
>>>
>>> class Condition
>>> {
>>> shared void notify()
>>> {
>>> static void doNotify() {}
>>> (cast(Condition) this).doNotify();
>>> }
>>> }
>>>
>>> Seems like it should work, though I'm hoping that the classes in core.sync are about the only ones where it's necessary (something similar will probably be necessary for Mutex to make lock() and unlock() explicitly callable, etc). I'm half tempted to try labeling these functions as __gshared and see if it compiles.
>>>
>>> On Jun 30, 2010, at 1:24 PM, Sean Kelly wrote:
>>>
>>>> Well that was a disaster. I have this:
>>>>
>>>> class MessageBox
>>>> {
>>>> this()
>>>> {
>>>> // this makes m_lock the monitor for the MessageBox instance.
>>>> m_lock = new Mutex( this );
>>>> m_cond = new Condition( m_lock );
>>>> }
>>>>
>>>> final synchronized void put( Message msg )
>>>> {
>>>> // m_lock is locked now
>>>> m_list.add( msg );
>>>> m_cond.notify(); // error: notify () is not callable using argument types () shared
>>>> }
>>>> }
>>>>
>>>> struct Tid
>>>> {
>>>> shared MessageBox mbox;
>>>> }
>>>>
>>>> class Condition
>>>> {
>>>> void notify()
>>>> {
>>>> // fancy stuff involving semaphores
>>>> }
>>>> }
>>>>
>>>> How do I fix this? Condition.notify() is technically shared, but I don't want to pay the cost for memory barriers that are utterly pointless. Should I change the call to notify() to:
>>>>
>>>> (cast(Condition)m_cond).notify();
>>>>
>>>> This should work, but it seems like an even worse subversion of the shared system than I'm already doing for MessageBox. If it helps, MessageBox is a thread-local class instance with put() as its one shared public method, so other threads have a shared reference to MessageBox while the object's owner has a non-shared reference to it. This is functionally correct, though it seems theoretically wrong to have both shared and unshared references to the same instance in the first place.
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
|
July 30, 2010 [phobos] Typo (bug) in std.concurrency | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | I think it's fair to cast shared away on certain core fns.
Sent by shouting through my showerhead.
On Jun 30, 2010, at 1:37 PM, Sean Kelly <sean at invisibleduck.org> wrote:
> Okay, alternate evil solution:
>
> class Condition
> {
> shared void notify()
> {
> static void doNotify() {}
> (cast(Condition) this).doNotify();
> }
> }
>
> Seems like it should work, though I'm hoping that the classes in core.sync are about the only ones where it's necessary (something similar will probably be necessary for Mutex to make lock() and unlock() explicitly callable, etc). I'm half tempted to try labeling these functions as __gshared and see if it compiles.
>
> On Jun 30, 2010, at 1:24 PM, Sean Kelly wrote:
>
>> Well that was a disaster. I have this:
>>
>> class MessageBox
>> {
>> this()
>> {
>> // this makes m_lock the monitor for the MessageBox instance.
>> m_lock = new Mutex( this );
>> m_cond = new Condition( m_lock );
>> }
>>
>> final synchronized void put( Message msg )
>> {
>> // m_lock is locked now
>> m_list.add( msg );
>> m_cond.notify(); // error: notify () is not callable using
>> argument types () shared
>> }
>> }
>>
>> struct Tid
>> {
>> shared MessageBox mbox;
>> }
>>
>> class Condition
>> {
>> void notify()
>> {
>> // fancy stuff involving semaphores
>> }
>> }
>>
>> How do I fix this? Condition.notify() is technically shared, but I don't want to pay the cost for memory barriers that are utterly pointless. Should I change the call to notify() to:
>>
>> (cast(Condition)m_cond).notify();
>>
>> This should work, but it seems like an even worse subversion of the shared system than I'm already doing for MessageBox. If it helps, MessageBox is a thread-local class instance with put() as its one shared public method, so other threads have a shared reference to MessageBox while the object's owner has a non-shared reference to it. This is functionally correct, though it seems theoretically wrong to have both shared and unshared references to the same instance in the first place.
>>
>>
>> On Jun 30, 2010, at 12:27 PM, Sean Kelly wrote:
>>
>>> Looks like it's time I start labeling references as shared in std.concurrency. The static checking is new.
>>>
>>> On Jun 30, 2010, at 12:15 PM, Lars Tandle Kyllingstad wrote:
>>>
>>>> Great, thanks! I can confirm that receiveTimeout() doesn't hang
>>>> anymore.
>>>>
>>>> I just encountered another problem with the SVN version of
>>>> std.concurrency. The following code is a simplified version of
>>>> an idiom
>>>> which is used in TDPL, namely, sending a Tid as a message:
>>>>
>>>> import std.concurrency;
>>>>
>>>> void main()
>>>> {
>>>> Tid someTid;
>>>> someTid.send(thisTid);
>>>> }
>>>>
>>>> Upon compilation, I get the following error:
>>>>
>>>> /home/lars/code/phobos-trunk/phobos/std/concurrency.d(217): Error:
>>>> static assert "Aliases to mutable thread-local data not allowed."
>>>> a.d(6): instantiated from here: send!(Tid)
>>>>
>>>> I do not get this message when I compile with the released (2.047)
>>>> version of std.concurrency.
>>>>
>>>> -Lars
>>>>
>>>>
>>>> On Wed, 2010-06-30 at 11:36 -0700, Sean Kelly wrote:
>>>>> Okay, should be fixed now.
>>>>>
>>>>> On Jun 30, 2010, at 8:38 AM, Sean Kelly wrote:
>>>>>
>>>>>> Oh well, looks like I have even more fixing to do :-)
>>>>>>
>>>>>> On Jun 30, 2010, at 7:35 AM, Lars Tandle Kyllingstad wrote:
>>>>>>
>>>>>>> Yeah, I noticed that you committed the fix, but too late. :)
>>>>>>> Due to
>>>>>>> some server lag, I got the "phobos commit" message several
>>>>>>> hours after I
>>>>>>> sent my e-mail, even though the commit was apparently done
>>>>>>> before I sent
>>>>>>> it.
>>>>>>>
>>>>>>> In case it's useful, I should mention that even after fixing
>>>>>>> the tuple
>>>>>>> issue and changing the return type of receiveTimeout() to
>>>>>>> void, it still
>>>>>>> doesn't work. The following code hangs indefinitely:
>>>>>>>
>>>>>>> import std.concurrency;
>>>>>>>
>>>>>>> void main()
>>>>>>> {
>>>>>>> // Should only block for 1ms:
>>>>>>> receiveTimeout(1, (int i) { });
>>>>>>> }
>>>>>>>
>>>>>>> -Lars
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Tue, 2010-06-29 at 20:47 -0700, Sean Kelly wrote:
>>>>>>>> The code has changed a ton recently and I hadn't gotten around to testing receiveTimeout yet. I'll take care of it.
>>>>>>>>
>>>>>>>> Sent from my iPhone
>>>>>>>>
>>>>>>>> On Jun 29, 2010, at 4:09 PM, Lars Tandle Kyllingstad <lars at kyllingen.net
>>>>>>>> > wrote:
>>>>>>>>
>>>>>>>>> I'm guessing this error turned up because someone tried to use
>>>>>>>>> receiveTimeout(). That's when it happened for me, at
>>>>>>>>> least. But when I
>>>>>>>>> fixed this, another error occurred:
>>>>>>>>>
>>>>>>>>> receiveTimeout() is supposed to return a bool, but it tries
>>>>>>>>> to return
>>>>>>>>> the result of MessageBox.get(), which is void. So get()
>>>>>>>>> should, in the
>>>>>>>>> case when ops[0] is an integer, somehow detect whether a
>>>>>>>>> message was
>>>>>>>>> received within the time limit and return a bool.
>>>>>>>>>
>>>>>>>>> Sean, if you aren't working on this already, I can look into
>>>>>>>>> it if you
>>>>>>>>> like.
>>>>>>>>>
>>>>>>>>> -Lars
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Tue, 2010-06-29 at 09:40 -0700, Sean Kelly wrote:
>>>>>>>>>> Okay I guess that makes sense. Should be easy enough to fix anyway.
>>>>>>>>>>
>>>>>>>>>> On Jun 29, 2010, at 8:43 AM, Steve Schveighoffer wrote:
>>>>>>>>>>
>>>>>>>>>>> You can't slice a tuple and assign it back to the same tuple type.
>>>>>>>>>>>
>>>>>>>>>>> -Steve
>>>>>>>>>>>
>>>>>>>>>>> ----- Original Message ----
>>>>>>>>>>>> From: Sean Kelly <sean at invisibleduck.org>
>>>>>>>>>>>> To: Discuss the phobos library for D <phobos at puremagic.com>
>>>>>>>>>>>> Sent: Tue, June 29, 2010 11:39:50 AM
>>>>>>>>>>>> Subject: Re: [phobos] Typo (bug) in std.concurrency
>>>>>>>>>>>>
>>>>>>>>>>>> On Jun 29, 2010, at 7:00 AM, Simen Kjaeraas wrote:
>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> http://d.puremagic.com/issues/show_bug.cgi?id=4406
>>>>>>>>>>>>
>>>>>>>>>>>> Posting it
>>>>>>>>>>>> here too, to make sure it gets noticed. It's a rather
>>>>>>>>>>>> simple fix.
>>>>>>>>>>>
>>>>>>>>>>> You
>>>>>>>>>>>> can't slice a tuple? Seriously? I could have sworn that
>>>>>>>>>>>> I tested
>>>>>>>>>>>> this and it worked.
>>>>>>>
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> phobos mailing list
>>>>>>> phobos at puremagic.com
>>>>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>>>
>>>>>> _______________________________________________
>>>>>> phobos mailing list
>>>>>> phobos at puremagic.com
>>>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>>
>>>>> _______________________________________________
>>>>> phobos mailing list
>>>>> phobos at puremagic.com
>>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>
>>>>
>>>> _______________________________________________
>>>> phobos mailing list
>>>> phobos at puremagic.com
>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>
>>> _______________________________________________
>>> phobos mailing list
>>> phobos at puremagic.com
>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
>
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
|
July 31, 2010 [phobos] Typo (bug) in std.concurrency | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Once I apply shared to the posix definitions this shouldn't be necessary. I'll try to apply it throughout core.sync in the next release. core.thread hopefully as well.
On Jul 30, 2010, at 11:45 PM, Andrei Alexandrescu wrote:
> I think it's fair to cast shared away on certain core fns.
>
> Sent by shouting through my showerhead.
>
> On Jun 30, 2010, at 1:37 PM, Sean Kelly <sean at invisibleduck.org> wrote:
>
>> Okay, alternate evil solution:
>>
>> class Condition
>> {
>> shared void notify()
>> {
>> static void doNotify() {}
>> (cast(Condition) this).doNotify();
>> }
>> }
>>
>> Seems like it should work, though I'm hoping that the classes in core.sync are about the only ones where it's necessary (something similar will probably be necessary for Mutex to make lock() and unlock() explicitly callable, etc). I'm half tempted to try labeling these functions as __gshared and see if it compiles.
>>
>> On Jun 30, 2010, at 1:24 PM, Sean Kelly wrote:
>>
>>> Well that was a disaster. I have this:
>>>
>>> class MessageBox
>>> {
>>> this()
>>> {
>>> // this makes m_lock the monitor for the MessageBox instance.
>>> m_lock = new Mutex( this );
>>> m_cond = new Condition( m_lock );
>>> }
>>>
>>> final synchronized void put( Message msg )
>>> {
>>> // m_lock is locked now
>>> m_list.add( msg );
>>> m_cond.notify(); // error: notify () is not callable using argument types () shared
>>> }
>>> }
>>>
>>> struct Tid
>>> {
>>> shared MessageBox mbox;
>>> }
>>>
>>> class Condition
>>> {
>>> void notify()
>>> {
>>> // fancy stuff involving semaphores
>>> }
>>> }
>>>
>>> How do I fix this? Condition.notify() is technically shared, but I don't want to pay the cost for memory barriers that are utterly pointless. Should I change the call to notify() to:
>>>
>>> (cast(Condition)m_cond).notify();
>>>
>>> This should work, but it seems like an even worse subversion of the shared system than I'm already doing for MessageBox. If it helps, MessageBox is a thread-local class instance with put() as its one shared public method, so other threads have a shared reference to MessageBox while the object's owner has a non-shared reference to it. This is functionally correct, though it seems theoretically wrong to have both shared and unshared references to the same instance in the first place.
>>>
>>>
>>> On Jun 30, 2010, at 12:27 PM, Sean Kelly wrote:
>>>
>>>> Looks like it's time I start labeling references as shared in std.concurrency. The static checking is new.
>>>>
>>>> On Jun 30, 2010, at 12:15 PM, Lars Tandle Kyllingstad wrote:
>>>>
>>>>> Great, thanks! I can confirm that receiveTimeout() doesn't hang
>>>>> anymore.
>>>>>
>>>>> I just encountered another problem with the SVN version of std.concurrency. The following code is a simplified version of an idiom which is used in TDPL, namely, sending a Tid as a message:
>>>>>
>>>>> import std.concurrency;
>>>>>
>>>>> void main()
>>>>> {
>>>>> Tid someTid;
>>>>> someTid.send(thisTid);
>>>>> }
>>>>>
>>>>> Upon compilation, I get the following error:
>>>>>
>>>>> /home/lars/code/phobos-trunk/phobos/std/concurrency.d(217): Error:
>>>>> static assert "Aliases to mutable thread-local data not allowed."
>>>>> a.d(6): instantiated from here: send!(Tid)
>>>>>
>>>>> I do not get this message when I compile with the released (2.047)
>>>>> version of std.concurrency.
>>>>>
>>>>> -Lars
>>>>>
>>>>>
>>>>> On Wed, 2010-06-30 at 11:36 -0700, Sean Kelly wrote:
>>>>>> Okay, should be fixed now.
>>>>>>
>>>>>> On Jun 30, 2010, at 8:38 AM, Sean Kelly wrote:
>>>>>>
>>>>>>> Oh well, looks like I have even more fixing to do :-)
>>>>>>>
>>>>>>> On Jun 30, 2010, at 7:35 AM, Lars Tandle Kyllingstad wrote:
>>>>>>>
>>>>>>>> Yeah, I noticed that you committed the fix, but too late. :) Due to some server lag, I got the "phobos commit" message several hours after I sent my e-mail, even though the commit was apparently done before I sent it.
>>>>>>>>
>>>>>>>> In case it's useful, I should mention that even after fixing the tuple issue and changing the return type of receiveTimeout() to void, it still doesn't work. The following code hangs indefinitely:
>>>>>>>>
>>>>>>>> import std.concurrency;
>>>>>>>>
>>>>>>>> void main()
>>>>>>>> {
>>>>>>>> // Should only block for 1ms:
>>>>>>>> receiveTimeout(1, (int i) { });
>>>>>>>> }
>>>>>>>>
>>>>>>>> -Lars
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Tue, 2010-06-29 at 20:47 -0700, Sean Kelly wrote:
>>>>>>>>> The code has changed a ton recently and I hadn't gotten around to testing receiveTimeout yet. I'll take care of it.
>>>>>>>>>
>>>>>>>>> Sent from my iPhone
>>>>>>>>>
>>>>>>>>> On Jun 29, 2010, at 4:09 PM, Lars Tandle Kyllingstad <lars at kyllingen.net> wrote:
>>>>>>>>>
>>>>>>>>>> I'm guessing this error turned up because someone tried to use receiveTimeout(). That's when it happened for me, at least. But when I fixed this, another error occurred:
>>>>>>>>>>
>>>>>>>>>> receiveTimeout() is supposed to return a bool, but it tries to return
>>>>>>>>>> the result of MessageBox.get(), which is void. So get() should, in the
>>>>>>>>>> case when ops[0] is an integer, somehow detect whether a message was
>>>>>>>>>> received within the time limit and return a bool.
>>>>>>>>>>
>>>>>>>>>> Sean, if you aren't working on this already, I can look into it if you like.
>>>>>>>>>>
>>>>>>>>>> -Lars
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Tue, 2010-06-29 at 09:40 -0700, Sean Kelly wrote:
>>>>>>>>>>> Okay I guess that makes sense. Should be easy enough to fix anyway.
>>>>>>>>>>>
>>>>>>>>>>> On Jun 29, 2010, at 8:43 AM, Steve Schveighoffer wrote:
>>>>>>>>>>>
>>>>>>>>>>>> You can't slice a tuple and assign it back to the same tuple type.
>>>>>>>>>>>>
>>>>>>>>>>>> -Steve
>>>>>>>>>>>>
>>>>>>>>>>>> ----- Original Message ----
>>>>>>>>>>>>> From: Sean Kelly <sean at invisibleduck.org>
>>>>>>>>>>>>> To: Discuss the phobos library for D <phobos at puremagic.com>
>>>>>>>>>>>>> Sent: Tue, June 29, 2010 11:39:50 AM
>>>>>>>>>>>>> Subject: Re: [phobos] Typo (bug) in std.concurrency
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Jun 29, 2010, at 7:00 AM, Simen Kjaeraas wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> http://d.puremagic.com/issues/show_bug.cgi?id=4406
>>>>>>>>>>>>>
>>>>>>>>>>>>> Posting it
>>>>>>>>>>>>> here too, to make sure it gets noticed. It's a rather simple fix.
>>>>>>>>>>>>
>>>>>>>>>>>> You
>>>>>>>>>>>>> can't slice a tuple? Seriously? I could have sworn that I tested this and it worked.
>>>>>>>>
>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> phobos mailing list
>>>>>>>> phobos at puremagic.com
>>>>>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> phobos mailing list
>>>>>>> phobos at puremagic.com
>>>>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>>>
>>>>>> _______________________________________________
>>>>>> phobos mailing list
>>>>>> phobos at puremagic.com
>>>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> phobos mailing list
>>>>> phobos at puremagic.com
>>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>
>>>> _______________________________________________
>>>> phobos mailing list
>>>> phobos at puremagic.com
>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>
>>> _______________________________________________
>>> phobos mailing list
>>> phobos at puremagic.com
>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
|
Copyright © 1999-2021 by the D Language Foundation