www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Question about std.bind

reply Russel Winder <russel russel.org.uk> writes:
I have a function with signature:

        void partialSum ( immutable long start , immutable long end , immut=
able real delta )

(it turns out the immutable is not a factor here I tried without it and
with const.)

I have a thread creation loop:

        foreach ( i ; 0 .. numberOfThreads ) { threads[i] =3D new Thread ( =
bind ( & partialSum , 1 + i * sliceSize , ( i + 1 ) * sliceSize , delta ) )=
 ; }

but this does not work.  I get the error message as below.  I really
haven't a clue what I am doing wrong, but I bet it is something
trivially simple.

        dmd -I. -O -release -inline -c -ofpi_d2_threads.o pi_d2_threads.d
        /home/users/russel/lib.Linux.x86_64/DMD2/bin/../../src/phobos/std/t=
raits.d(185): Error: static assert  "argument has no parameters"
        /home/users/russel/lib.Linux.x86_64/DMD2/bin/../../src/phobos/std/b=
ind.d(977):        instantiated from here: ParameterTypeTuple!(const(EmptyS=
lot)*)
        /home/users/russel/lib.Linux.x86_64/DMD2/bin/../../src/phobos/std/b=
ind.d(1003):        instantiated from here: FuncReferenceParamsAsPointers_i=
mpl!(NullAlias)
        /home/users/russel/lib.Linux.x86_64/DMD2/bin/../../src/phobos/std/b=
ind.d(338):        instantiated from here: FuncReferenceParamsAsPointers!(N=
ullAlias)
        /home/users/russel/lib.Linux.x86_64/DMD2/bin/../../src/phobos/std/b=
ind.d(660):        instantiated from here: BoundFunc!(void function(immutab=
le immutable(long) start, immutable immutable(long) end, immutable immutabl=
e(real) delta),NullAlias,Tuple!(long,long,immutable(double)))
        pi_d2_threads.d(31):        instantiated from here: bind!(void func=
tion(immutable immutable(long) start, immutable immutable(long) end, immuta=
ble immutable(real) delta),long,long,immutable(double))
       =20
--=20
Russel.
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D
Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder ekiga.n=
et
41 Buckmaster Road    m: +44 7770 465 077   xmpp: russel russel.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder
Nov 12 2010
parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 12.11.2010 22:05, Russel Winder wrote:
 I have a function with signature:

          void partialSum ( immutable long start , immutable long end ,
immutable real delta )

 (it turns out the immutable is not a factor here I tried without it and
 with const.)

 I have a thread creation loop:

          foreach ( i ; 0 .. numberOfThreads ) { threads[i] = new Thread ( bind
(&  partialSum , 1 + i * sliceSize , ( i + 1 ) * sliceSize , delta ) ) ; }
I'd try to replace bind with delegate: threads[i] = new Thread( (){ return partialSum(1 + i * sliceSize, (i + 1) * sliceSize, delta); } ); I'm not sure if std.bind works now, and why we even need it in D2 since it's functionality is completely superseded by delegates. Well if Q was about D1...
 but this does not work.  I get the error message as below.  I really
 haven't a clue what I am doing wrong, but I bet it is something
 trivially simple.

          dmd -I. -O -release -inline -c -ofpi_d2_threads.o pi_d2_threads.d
          /home/users/russel/lib.Linux.x86_64/DMD2/bin/../../src/phobo
/std/traits.d(185): Error: static assert  "argument has no parameters"
          /home/users/russel/lib.Linux.x86_64/DMD2/bin/../../src/pho
os/std/bind.d(977):        instantiated from here:
ParameterTypeTuple!(const(EmptySlot)*)
          /home/users/russel/lib.Linux.x86_64/DMD2/bin/../../src/phob
s/std/bind.d(1003):        instantiated from here:
FuncReferenceParamsAsPointers_impl!(NullAlias)
          /home/users/russel/lib.Linux.x86_64/DMD2/bin/../../src/pho
os/std/bind.d(338):        instantiated from here:
FuncReferenceParamsAsPointers!(NullAlias)
          /home/users/russel/lib.Linux.x86_64/DMD2/bin/../../src/pho
os/std/bind.d(660):        instantiated from here: BoundFunc!(void
function(immutable immutable(long) start, immutable immutable(long) end,
immutable immutable(real) delta),NullAlias,Tuple!(long,long,immutable(double)))
          pi_d2_threads.d(31):        instantiated from here: bind!(void
function(immutable immutable(long) start, immutable immutable(long) end,
immutable immutable(real) delta),long,long,immutable(double))
-- Dmitry Olshansky
Nov 12 2010
parent reply Russel Winder <russel russel.org.uk> writes:
On Fri, 2010-11-12 at 23:14 +0300, Dmitry Olshansky wrote:
[ . . . ]
 I have a thread creation loop:

          foreach ( i ; 0 .. numberOfThreads ) { threads[i] =3D new Thre=
ad ( bind (& partialSum , 1 + i * sliceSize , ( i + 1 ) * sliceSize , delt= a ) ) ; }

 I'd try to replace bind with delegate:
 threads[i] =3D new Thread( (){ return partialSum(1 + i * sliceSize, (i +=
=20
 1) * sliceSize, delta); } );
=20
 I'm not sure if std.bind works now, and why we even need it in D2 since=
=20
 it's functionality is completely superseded by delegates.
 Well if Q was about D1...
[ . . . ] I will certainly give using an anonymous function in this way a go, but if partial application is a part of the language (and I am using D 2.050), then it ought to work.=20 Sadly, using an anonymous function my code compiles, but on execution just gives a segmentation fault. [Thread debugging using libthread_db enabled] [New Thread 0xf7d1fb70 (LWP 13922)] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0xf7d1fb70 (LWP 13922)] 0x0804ee0a in _d_monitorenter () --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel russel.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Nov 13 2010
parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 13.11.2010 11:12, Russel Winder wrote:
 On Fri, 2010-11-12 at 23:14 +0300, Dmitry Olshansky wrote:
 [ . . . ]
 I have a thread creation loop:

           foreach ( i ; 0 .. numberOfThreads ) { threads[i] = new Thread (
bind (&   partialSum , 1 + i * sliceSize , ( i + 1 ) * sliceSize , delta ) ) ; }
I'd try to replace bind with delegate: threads[i] = new Thread( (){ return partialSum(1 + i * sliceSize, (i + 1) * sliceSize, delta); } ); I'm not sure if std.bind works now, and why we even need it in D2 since it's functionality is completely superseded by delegates. Well if Q was about D1...
[ . . . ] I will certainly give using an anonymous function in this way a go, but if partial application is a part of the language (and I am using D 2.050), then it ought to work. Sadly, using an anonymous function my code compiles, but on execution just gives a segmentation fault. [Thread debugging using libthread_db enabled] [New Thread 0xf7d1fb70 (LWP 13922)] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0xf7d1fb70 (LWP 13922)] 0x0804ee0a in _d_monitorenter ()
Well at least the Thread starts ) I'd search for the clues by replacing all complicated logic with writeln("Func x executed"); where x identifies functions. If it prints all successfully, then it's bug in your code. My best guess - you are not aware of "Thread-local by default", i.e. any thread you spawn won't have access to parent's thread global data. Anyway, I'd suggest posting it on D.learn with full source code, guys there are quite helpful. -- Dmitry Olshansky
Nov 13 2010
parent reply Russel Winder <russel russel.org.uk> writes:
On Sat, 2010-11-13 at 12:49 +0300, Dmitry Olshansky wrote:
[ . . . ]
 Well at least the Thread starts )
Indeed :-)
 I'd search for the clues by replacing all complicated logic with=20
 writeln("Func x executed"); where x identifies functions.
 If it prints all successfully, then it's bug in your code.
 My best guess - you are not aware of "Thread-local by default", i.e. any=
=20
 thread you spawn won't have access to parent's thread global data.
 Anyway, I'd suggest posting it on D.learn with full source code, guys=20
 there are quite helpful.
Using gdb I get: (gdb) bt 999998051260704522807e-10, end=3D4294967296, start=3D1000000001) at pi_d2_t= hreads.d:25 4ce0) at pi_d2_threads.d:35 .c:304 .S:130 (gdb)=20 OK, so now I know I am trying to do things the wrong way, explicit threads, shared global data, and synchronized statements, but that is the whole point of my examples. Segementation fault is not though the error message I think this should result in. Anyway I have global objects: shared real sum ; shared Object sumMutex ; then in the function partialSum that is being executed by each of the threads: synchronized ( sumMutex ) { sum +=3D localSum ; } It compiles, it executes, it seg faults. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel russel.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Nov 13 2010
next sibling parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 13.11.2010 14:11, Russel Winder wrote:
 On Sat, 2010-11-13 at 12:49 +0300, Dmitry Olshansky wrote:
 [ . . . ]
 Well at least the Thread starts )
Indeed :-)
 I'd search for the clues by replacing all complicated logic with
 writeln("Func x executed"); where x identifies functions.
 If it prints all successfully, then it's bug in your code.
 My best guess - you are not aware of "Thread-local by default", i.e. any
 thread you spawn won't have access to parent's thread global data.
 Anyway, I'd suggest posting it on D.learn with full source code, guys
 there are quite helpful.
Using gdb I get: (gdb) bt (delta=9.9999999999999999998051260704522807e-10, end=4294967296, start=1000000001) at pi_d2_threads.d:25
Strange values you have in there :) Is it intended? Again consider providing the full code of failing example.

(this=0xf7d24ce0) at pi_d2_threads.d:35



pthread_create..c:304

../sysdeps/unix/sysv/linux/i386/clone..S:130
          (gdb)
 OK, so now I know I am trying to do things the wrong way, explicit
 threads, shared global data, and synchronized statements, but that is
 the whole point of my examples.  Segementation fault is not though the
 error message I think this should result in.
Unchecked null pointer still causes segfault, and you could easily code yourself into one when you are not aware of this default. If you are porting some existing code that expects global sharing, then I may also suggest using __gshared attribute instead of shared on all globals, and see how that swims.
 Anyway I have global
 objects:

          shared real sum ;
          shared Object sumMutex ;

 then in the function partialSum that is being executed by each of the
 threads:

          synchronized ( sumMutex ) { sum += localSum ; }

 It compiles, it executes, it seg faults.
-- Dmitry Olshansky
Nov 13 2010
prev sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 13.11.2010 14:11, Russel Winder wrote:
 On Sat, 2010-11-13 at 12:49 +0300, Dmitry Olshansky wrote:
 [ . . . ]
 Well at least the Thread starts )
Indeed :-)
 I'd search for the clues by replacing all complicated logic with
 writeln("Func x executed"); where x identifies functions.
 If it prints all successfully, then it's bug in your code.
 My best guess - you are not aware of "Thread-local by default", i.e. any
 thread you spawn won't have access to parent's thread global data.
 Anyway, I'd suggest posting it on D.learn with full source code, guys
 there are quite helpful.
Using gdb I get: (gdb) bt (delta=9.9999999999999999998051260704522807e-10, end=4294967296, start=1000000001) at pi_d2_threads.d:25 (this=0xf7d24ce0) at pi_d2_threads.d:35 pthread_create..c:304 ../sysdeps/unix/sysv/linux/i386/clone..S:130 (gdb) OK, so now I know I am trying to do things the wrong way, explicit threads, shared global data, and synchronized statements, but that is the whole point of my examples. Segementation fault is not though the error message I think this should result in. Anyway I have global objects: shared real sum ; shared Object sumMutex ;
Ah, another guess - you didn't initialize that sumMutex ? Then put this somewhere before using it: sumMutex = new shared(Object);
 then in the function partialSum that is being executed by each of the
 threads:

          synchronized ( sumMutex ) { sum += localSum ; }

 It compiles, it executes, it seg faults.
-- Dmitry Olshansky
Nov 13 2010
parent Russel Winder <russel russel.org.uk> writes:
Dmitry, you are a hero, thanks muchly :-))

On Sun, 2010-11-14 at 02:37 +0300, Dmitry Olshansky wrote:
[ . . . ]
          shared Object sumMutex ;
Ah, another guess - you didn't initialize that sumMutex ? Then put this somewhere before using it: =20 sumMutex =3D new shared(Object);
I managed to delete the line from my code and didn't notice it. Moral of story: read your code, don't assume you know what it says when you look at it. Thanks again. std.bind.bind is still broken though, but I have an example that now works. =20 --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel russel.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Nov 14 2010