std.parallelism + alloc = deadlock

Antoche N at A.c
Tue Nov 26 19:55:18 PST 2013


I'm trying to use taskPool.asyncBuf from std.parallelism since 
std.concurrency seems broken 
(http://forum.dlang.org/thread/wpxygsxveghehdptjfzj@forum.dlang.org).

I have a class that creates a custom Range and loops over it 
through a taskPool.asyncBuf inside its constructor. The elements 
returned by the Range are new class instances holding arrays, and 
those arrays are filled and resized at construction times.

I'm seeing a deadlock happening due to allocation. Stacktrace for 
the main thread shows:

Thread 1 (Thread 0x7ffff7fbb000 (LWP 19956)):
#0  0x00007ffff74a3fd0 in sem_wait () from 
/lib/x86_64-linux-gnu/libpthread.so.0
#1  0x00000000006e3f9f in core.thread.suspend() ()
#2  0x00000000006e2f8c in thread_suspendAll ()
#3  0x00000000006dc987 in gc.gcx.Gcx.fullcollect() ()
#4  0x00000000006d998a in gc.gcx.GC.mallocNoSync() ()
#5  0x00000000006d9873 in gc.gcx.GC.malloc() ()
#6  0x00000000006ba660 in gc_qalloc ()
#7  0x00000000006c0819 in _d_arrayliteralTX ()
#8  0x000000000057098c in mymodule.MyClass.someMethod() ()
#9  0x0000000000570274 in mymodule.MyClass.__ctor() ()
#10 0x00000000004efe2d in D main ()
#11 0x00000000006bc59c in rt.dmain2._d_run_main() ()
#12 0x00000000006bc0ce in rt.dmain2._d_run_main() ()
#13 0x00000000006bc5ec in rt.dmain2._d_run_main() ()
#14 0x00000000006bc0ce in rt.dmain2._d_run_main() ()
#15 0x00000000006bc08a in _d_run_main ()
#16 0x00000000006bbed7 in main ()

Stacktrace for the Range call:

Thread 5 (Thread 0x7fffed2b1700 (LWP 19986)):
#0  0x00007ffff74a489c in __lll_lock_wait () from 
/lib/x86_64-linux-gnu/libpthread.so.0
#1  0x00007ffff74a0080 in _L_lock_903 () from 
/lib/x86_64-linux-gnu/libpthread.so.0
#2  0x00007ffff749ff19 in pthread_mutex_lock () from 
/lib/x86_64-linux-gnu/libpthread.so.0
#3  0x00000000006d8eed in core.sync.mutex.Mutex.lock() ()
#4  0x00000000006d985f in gc.gcx.GC.malloc() ()
#5  0x00000000006ba660 in gc_qalloc ()
#6  0x00000000006bf273 in _d_arraysetlengthiT ()
[...]
#13 0x000000000053e227 in mymodule.MyElt.__ctor() ()
#14 0x000000000053ed3f in mymodule.MyRange.front() ()
#15 0x0000000000521118 in 
std.parallelism.TaskPool.[...].asyncBuf() ()
#16 0x000000000052187b in std.parallelism.[...].run() ()
#17 0x000000000052131e in std.parallelism.[...].Task.impl() ()
#18 0x00000000006ccff3 in std.parallelism.AbstractTask.job() ()
#19 0x00000000006cd0a5 in std.parallelism.TaskPool.doJob() ()
#20 0x00000000006cd1de in 
std.parallelism.TaskPool.executeWorkLoop() ()
#21 0x00000000006cd186 in 
std.parallelism.TaskPool.startWorkLoop() ()
#22 0x00000000006e2bce in core.thread.Thread.run() ()
#23 0x00000000006e2a02 in thread_entryPoint ()
#24 0x00007ffff749de9a in start_thread () from 
/lib/x86_64-linux-gnu/libpthread.so.0
#25 0x00007ffff6ab0cbd in clone () from 
/lib/x86_64-linux-gnu/libc.so.6
#26 0x0000000000000000 in ?? ()

My impression is that the main thread, going through the 
constructor, goes through gc.gcx.GC.malloc(). The second thread, 
resizing an array, also calls gc.gcx.GC.malloc(), which seems to 
be trying to lock a mutex. I'm guessing that mutex was locked by 
the first one? Or am I mistaken?


More information about the Digitalmars-d-learn mailing list