June 27, 2008
"Walter Bright" <newshound1@digitalmars.com> wrote in message news:g3uqph$2s3n$1@digitalmars.com...
> Right now, if you use a synchronized statement with no argument, it will sync on a mutex unique to that statement.
>
> Does anyone write threading code that depends on this behavior?

Never understood that one, so: no.

But I do think there's a place for synchronized { }: memory barrier.

IIRC a mutex always implies a memory barrier anyway. synchronized without argument could only create a memory barrier. This could then be used to achieve what the Interlocked* functions in Win32 do. It's such a basic operation that I think it warrants a language construct.

static int b;//some global
int a;//local
// native cross-platform InterlockedIncrement
synchronized
{
  a = b++;
}

I should note however that I'm currently having a hard-time implementing some multi-threaded algorithms.. I probably don't know enough about MT to be messing with it :S

L. 

June 27, 2008
"cemiller" wrote
> On Thu, 26 Jun 2008 16:42:32 -0700, BCS wrote:
>
>> Reply to cemiller,
>>
>>> I use it on occasion. It can be useful for singleton:
>>>  if(!foo)
>>> {
>>> synchronized
>>> {
>>> if(!foo)
>>> foo = new Foo();
>>> }
>>> }
>>> return foo;
>>> especially useful because you don't need an object instance.
>>>
>>
>> Hmmm. Slight variation on my last suggestion, Allow synchronized to take any global symbol as the mutex
>>
>> if(!foo)
>> {
>>   synchronized(Foo)  // global mutex on Foo
>>   {
>>     if(!foo)
>>       foo = new Foo();
>>   }
>> }
>>
>> Or if you need more resolution:
>>
>> class Foo
>> {
>>   alias void single;
>> }
>>
>> ...
>>   synchronized(Foo.single)  // global mutex on Foo.single
>> ...
>
>
> I could synchronized(typeid(Foo)) but I don't think D guarantees that each type has its own instance and monitor. This could potentially be a substitute; create a type and lock on it, no runtime allocation, not many language changes needed.

I think this is guaranteed as long as you are not loading D from multiple DLLs.

In any case, Tango avoids needing this statement by making mutexes fully accessible objects.  If you need a mutex without having it attached to an object, it's easy:

Mutex m = new Mutex;

synchronized(m)
{
}

-Steve


June 27, 2008
Steven Schveighoffer wrote:
> In any case, Tango avoids needing this statement by making mutexes fully accessible objects.  If you need a mutex without having it attached to an object, it's easy:
> 
> Mutex m = new Mutex;
> 
> synchronized(m)
> {
> }


Isn't that the same as doing this?

---
Object m = new Object;

synchronized(m)
{
}
---
June 27, 2008
gentoo-pc ~ $ cat test50.d; echo "==="; gdc test50.d -o test50 && ./test5
0
import std.stdio;

template _SyncObject(string KEY) {
  Object obj;
  static this() { obj = new Object; }
}

template SyncObject(string KEY) {
  alias _SyncObject!(KEY).obj SyncObject;
}

void main() {
  writefln(SyncObject!("main_1") is SyncObject!("main_1"));
  writefln(SyncObject!("main_1") !is SyncObject!("main_2"));
  synchronized (SyncObject!("main_1")) {
    writefln("Test");
  }
}
===
true
true
Test
June 27, 2008
"torhu" wrote
> Steven Schveighoffer wrote:
>> In any case, Tango avoids needing this statement by making mutexes fully accessible objects.  If you need a mutex without having it attached to an object, it's easy:
>>
>> Mutex m = new Mutex;
>>
>> synchronized(m)
>> {
>> }
>
>
> Isn't that the same as doing this?
>
> ---
> Object m = new Object;
>
> synchronized(m)
> {
> }

It's close, but in Tango, you have methods for the mutex, plus you can use them with conditions.

Plus, it's not as hackish :)

It would be nice if the language supported conditions based on the Monitor object by default.

-Steve


June 28, 2008
Walter Bright wrote:
> Right now, if you use a synchronized statement with no argument, it will sync on a mutex unique to that statement.
> 
> Does anyone write threading code that depends on this behavior?

Slightly off topic.

Just a thought.  If we had the ability to do block operators, or turn functions with delegates into blocks, or any other incarnation we could have this as a library function.

-Joel
June 29, 2008
== Quote from Walter Bright (newshound1@digitalmars.com)'s article
> Right now, if you use a synchronized statement with no argument, it will
> sync on a mutex unique to that statement.
> Does anyone write threading code that depends on this behavior?

It's certainly convenient in some instances, but obviously not necessary.  Still, I find the current behavior to be easily understandable.


Sean
June 29, 2008
On Thu, 26 Jun 2008 08:15:24 -0400, Michel Fortin wrote:

> On 2008-06-25 21:18:41 -0400, Walter Bright <newshound1@digitalmars.com> said:
> 
>> Right now, if you use a synchronized statement with no argument, it will sync on a mutex unique to that statement.
>> 
>> Does anyone write threading code that depends on this behavior?
> 
> I've used it before, thinking it was equivalent to synchronize(this) {}, an incorrect assumption obviously. If you get rid of it, I won't miss it.

Same.
June 30, 2008
== Quote from torhu (no@spam.invalid)'s article
> Steven Schveighoffer wrote:
> > In any case, Tango avoids needing this statement by making mutexes fully accessible objects.  If you need a mutex without having it attached to an object, it's easy:
> >
> > Mutex m = new Mutex;
> >
> > synchronized(m)
> > {
> > }
> Isn't that the same as doing this?
> ---
> Object m = new Object;
> synchronized(m)
> {
> }
> ---

No.  Mutexes in Tango can be set as the monitor for any object, and are in fact their own monitors.  So synchronized(m) actually locks the Mutex, not a separate monitor object associated with the Mutex object. You can just as easily do this:

class C
{
    this(Mutex x)
    {
        m = x;
        setMonitor(this, m);
    }

    Mutex m;

    void fn()
    {
        // the following are all equivalent
        synchronized {}
        synchronized(this) {}
        synchronized(m) {}
    }
}

Ore read-write mutexes:

ReadWriteMutex m;

synchronized(m.reader) {}
synchronized(m.writer) {}


Sean
June 30, 2008
== Quote from janderson (askme@me.com)'s article
> Walter Bright wrote:
> > Right now, if you use a synchronized statement with no argument, it will sync on a mutex unique to that statement.
> >
> > Does anyone write threading code that depends on this behavior?
> Slightly off topic.
> Just a thought.  If we had the ability to do block operators, or turn
> functions with delegates into blocks, or any other incarnation we could
> have this as a library function.

It is already effectively a library function in Tango.  Tango contains mutexes
which may operate as object monitors and there is no real code dependency
for this between the runtime and library code.


Sean