[M3devel] pthreads efficiency

mika at async.caltech.edu mika at async.caltech.edu
Mon Aug 25 08:13:35 CEST 2014


Hi again m3devel,

This is my promised email about "issues" with the pthreads library.

My application is an optimization program that operates basically as
follows: it simulates an electronic circuit until it finds a problem,
then it aborts the simulation, makes an adjustment to the circuit,
and re-simulate.  The adjustment and simulation loop is inherently
sequential.

But Einstein teaches that physics is parallel.  That means that any 
physical simulation, at the limit, can be parallelized.  Although the
size of the system that is being simulated can put limits on how much
parallelism you can extract.  

My chosen architecture for the simulation (mentioned in previous email)
is a master thread that acts as a "conductor" for N "worker" threads
(well call them musicians if you want to).  The code is structured as
a little bit of computation (workers running, mater waiting for them),
followed by a barrier synchronization (all workers stopped, master
performing some status computations).  Each of the N+1 threads is a
Modula-3 thread, thus in practice a pthread.

I fairly quickly realized that one of the problems with my implementation
was that the pthreads synchronization primitives and the Modula-3 primitives
built on top of them are not a perfect match.  I wound up using POSIX
semaphores instead (sem_wait, sem_post).  Not a big deal but will require
work if I ever want to port back to user threads (hope not, let's get 
pthreads working everywhere???)

So my code now uses semaphores and runs fairly well.  I get about 600%
CPU at best (on a 12-core machine---well maybe it's just 6 cores but they
are hyperthreaded up to 12 and in C you can get 1200%).

I think the performance issue now is with the garbage collector, and I'd
like some advice on how to proceed.

I'm attaching a backtrace from a run of my program.  Noteworthy is that my
program generates VERY little garbage.  I have coded it very carefully
to recycle all its memory.

The program has noticeable hangs while running.  The backtrace was
captured during one of these hangs.

We see a lot of this stuff:

#0  __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
#1  0x00002aaaac1b9339 in _L_lock_926 () from /lib/x86_64-linux-gnu/libpthread.so.0
#2  0x00002aaaac1b915b in __pthread_mutex_lock (mutex=0xf96880) at pthread_mutex_lock.c:61
#3  0x00000000004df034 in ThreadPThread__pthread_mutex_lock (mutex=0xf96880) at ../src/thread/PTHREAD/ThreadPThreadC.c:506
#4  0x00000000004de22a in RTOS__LockHeap () at ../src/thread/PTHREAD/ThreadPThread.m3:1375
#5  0x00000000004ca120 in RTHooks__CheckLoadTracedRef (M3_Af40ku_ref=<error reading variable>) at ../src/runtime/common/RTCollector.m3:2234
#6  0x000000000041b78a in PllERS__DoOneTimestep (M3_De1Q5p_cl=<error reading variable>, M3_CiABk7_fi=<error reading variable>) at ../src/PllERS.m3:712
#7  0x000000000041c81e in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:653
#8  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#9  0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#10 0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#11 0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#12 0x0000000000000000 in ?? ()

This is not really acceptable for my application.  I anticipate I have
100-fold parallelism in it.  I can get a machine with 50 cores, I should
be able to get 5,000% CPU out of it no problem.

I think I am limited to about threefold speedup with the garbage collector
mutex locking as above.

But at the same time I realize that if your application is performing
arbitrary memory references and you are in a garbage-collected
environment, there is an implicit dependency on the garbage collector for
heap references.  I'm not asking for the impossible.

Here's what I'd like to propose and I'd like to hear (from Tony or anyone else)
whether what I'm proposing is sensible at all:

My application is structed as worker threads-barrier
synchronization-worker threads-etc.  This is a common pattern in physical
simulations in high-performance computing.

Can I turn off the garbage collector while the worker threads are running and
somehow dispense with the "CheckLoadTracedRef", or at least with the mutex lock?
I will do whatever is necessry to ensure that the system doesn't need to lock
while the workers are running.  I don't care if it locks when they are stopped...

Worst case maybe we can push updates from the worker threads on to a queue to be 
sorted out during the barrier interval.  Or something.  The locks do need to be
avoided somehow.

And yes I have looked at what it is that is being loaded by my program.  It is an
almost entirely static structure that changes very slowly---it is only updated BETWEEN
runs of the simulation, not during simulation itself.  And it never shrinks, so it
never garbage collected.  Does that help somehow?

     Mika

P.S. I'm also attaching the Semaphore code if anyone finds that interesting.
-------------- next part --------------

Thread 20 (Thread 0x2aaab118e700 (LWP 5191)):
#0  sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86
#1  0x0000000000420a30 in SemaphoreC__sem_wait (sem=0xfaf4c0) at ../src/SemaphoreC.c:16
#2  0x0000000000420bac in Semaphore (M3_Cfdzoy_t=<error reading variable>) at ../src/Semaphore.m3:34
#3  0x000000000041c7fa in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:649
#4  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#5  0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#6  0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#7  0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#8  0x0000000000000000 in ?? ()

Thread 19 (Thread 0x2aaab0f8d700 (LWP 5190)):
#0  sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86
#1  0x0000000000420a30 in SemaphoreC__sem_wait (sem=0xfaf4c0) at ../src/SemaphoreC.c:16
#2  0x0000000000420bac in Semaphore (M3_Cfdzoy_t=<error reading variable>) at ../src/Semaphore.m3:34
#3  0x000000000041c7fa in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:649
#4  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#5  0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#6  0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#7  0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#8  0x0000000000000000 in ?? ()

Thread 18 (Thread 0x2aaab0d8c700 (LWP 5189)):
#0  sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86
#1  0x0000000000420a30 in SemaphoreC__sem_wait (sem=0xfaf4c0) at ../src/SemaphoreC.c:16
#2  0x0000000000420bac in Semaphore (M3_Cfdzoy_t=<error reading variable>) at ../src/Semaphore.m3:34
#3  0x000000000041c7fa in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:649
#4  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#5  0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#6  0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#7  0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#8  0x0000000000000000 in ?? ()

Thread 17 (Thread 0x2aaab0b8b700 (LWP 5188)):
#0  sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86
#1  0x0000000000420a30 in SemaphoreC__sem_wait (sem=0xfaf4c0) at ../src/SemaphoreC.c:16
#2  0x0000000000420bac in Semaphore (M3_Cfdzoy_t=<error reading variable>) at ../src/Semaphore.m3:34
#3  0x000000000041c7fa in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:649
#4  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#5  0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#6  0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#7  0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#8  0x0000000000000000 in ?? ()

Thread 16 (Thread 0x2aaab098a700 (LWP 5187)):
#0  sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86
#1  0x0000000000420a30 in SemaphoreC__sem_wait (sem=0xfaf4c0) at ../src/SemaphoreC.c:16
#2  0x0000000000420bac in Semaphore (M3_Cfdzoy_t=<error reading variable>) at ../src/Semaphore.m3:34
#3  0x000000000041c7fa in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:649
#4  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#5  0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#6  0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#7  0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#8  0x0000000000000000 in ?? ()

Thread 15 (Thread 0x2aaab0789700 (LWP 5186)):
#0  sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86
#1  0x0000000000420a30 in SemaphoreC__sem_wait (sem=0xfaf4c0) at ../src/SemaphoreC.c:16
#2  0x0000000000420bac in Semaphore (M3_Cfdzoy_t=<error reading variable>) at ../src/Semaphore.m3:34
#3  0x000000000041c7fa in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:649
#4  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#5  0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#6  0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#7  0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#8  0x0000000000000000 in ?? ()

Thread 14 (Thread 0x2aaab0588700 (LWP 5185)):
#0  sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86
#1  0x0000000000420a30 in SemaphoreC__sem_wait (sem=0xfaf4c0) at ../src/SemaphoreC.c:16
#2  0x0000000000420bac in Semaphore (M3_Cfdzoy_t=<error reading variable>) at ../src/Semaphore.m3:34
#3  0x000000000041c7fa in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:649
#4  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#5  0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#6  0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#7  0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#8  0x0000000000000000 in ?? ()

Thread 13 (Thread 0x2aaab0387700 (LWP 5184)):
#0  sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86
#1  0x0000000000420a30 in SemaphoreC__sem_wait (sem=0xfaf4c0) at ../src/SemaphoreC.c:16
#2  0x0000000000420bac in Semaphore (M3_Cfdzoy_t=<error reading variable>) at ../src/Semaphore.m3:34
#3  0x000000000041c7fa in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:649
#4  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#5  0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#6  0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#7  0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#8  0x0000000000000000 in ?? ()

Thread 12 (Thread 0x2aaab0186700 (LWP 5183)):
#0  sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86
#1  0x0000000000420a30 in SemaphoreC__sem_wait (sem=0xfaf4c0) at ../src/SemaphoreC.c:16
#2  0x0000000000420bac in Semaphore (M3_Cfdzoy_t=<error reading variable>) at ../src/Semaphore.m3:34
#3  0x000000000041c7fa in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:649
#4  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#5  0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#6  0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#7  0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#8  0x0000000000000000 in ?? ()

Thread 11 (Thread 0x2aaaaff85700 (LWP 5182)):
#0  __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
#1  0x00002aaaac1b9339 in _L_lock_926 () from /lib/x86_64-linux-gnu/libpthread.so.0
#2  0x00002aaaac1b915b in __pthread_mutex_lock (mutex=0xf96880) at pthread_mutex_lock.c:61
#3  0x00000000004df034 in ThreadPThread__pthread_mutex_lock (mutex=0xf96880) at ../src/thread/PTHREAD/ThreadPThreadC.c:506
#4  0x00000000004de22a in RTOS__LockHeap () at ../src/thread/PTHREAD/ThreadPThread.m3:1375
#5  0x00000000004ca27f in RTHooks__CheckStoreTraced (M3_Af40ku_dst=<error reading variable>) at ../src/runtime/common/RTCollector.m3:2255
#6  0x000000000041c55f in PllERS__HandleFanout (M3_De1Q5p_cl=<error reading variable>, M3_BZemAb_f=...) at ../src/PllERS.m3:403
#7  0x000000000041c78d in PllERS__FlushFanouts (M3_De1Q5p_cl=<error reading variable>, M3_CiABk7_fi=<error reading variable>) at ../src/PllERS.m3:438
#8  0x000000000041c810 in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:652
#9  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#10 0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#11 0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#12 0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#13 0x0000000000000000 in ?? ()

Thread 10 (Thread 0x2aaaafd84700 (LWP 5181)):
#0  __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
#1  0x00002aaaac1b9339 in _L_lock_926 () from /lib/x86_64-linux-gnu/libpthread.so.0
#2  0x00002aaaac1b915b in __pthread_mutex_lock (mutex=0xf96880) at pthread_mutex_lock.c:61
#3  0x00000000004df034 in ThreadPThread__pthread_mutex_lock (mutex=0xf96880) at ../src/thread/PTHREAD/ThreadPThreadC.c:506
#4  0x00000000004de22a in RTOS__LockHeap () at ../src/thread/PTHREAD/ThreadPThread.m3:1375
#5  0x00000000004ca120 in RTHooks__CheckLoadTracedRef (M3_Af40ku_ref=<error reading variable>) at ../src/runtime/common/RTCollector.m3:2234
#6  0x000000000041b48a in PllERS__DoOneTimestep (M3_De1Q5p_cl=<error reading variable>, M3_CiABk7_fi=<error reading variable>) at ../src/PllERS.m3:701
#7  0x000000000041c81e in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:653
#8  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#9  0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#10 0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#11 0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#12 0x0000000000000000 in ?? ()

Thread 9 (Thread 0x2aaaafb83700 (LWP 5180)):
#0  __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
#1  0x00002aaaac1b9339 in _L_lock_926 () from /lib/x86_64-linux-gnu/libpthread.so.0
#2  0x00002aaaac1b915b in __pthread_mutex_lock (mutex=0xf96880) at pthread_mutex_lock.c:61
#3  0x00000000004df034 in ThreadPThread__pthread_mutex_lock (mutex=0xf96880) at ../src/thread/PTHREAD/ThreadPThreadC.c:506
#4  0x00000000004de22a in RTOS__LockHeap () at ../src/thread/PTHREAD/ThreadPThread.m3:1375
#5  0x00000000004ca120 in RTHooks__CheckLoadTracedRef (M3_Af40ku_ref=<error reading variable>) at ../src/runtime/common/RTCollector.m3:2234
#6  0x000000000041b78a in PllERS__DoOneTimestep (M3_De1Q5p_cl=<error reading variable>, M3_CiABk7_fi=<error reading variable>) at ../src/PllERS.m3:712
#7  0x000000000041c81e in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:653
#8  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#9  0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#10 0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#11 0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#12 0x0000000000000000 in ?? ()

Thread 8 (Thread 0x2aaaaf982700 (LWP 5179)):
#0  sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86
#1  0x0000000000420a30 in SemaphoreC__sem_wait (sem=0xfadaf0) at ../src/SemaphoreC.c:16
#2  0x0000000000420bac in Semaphore (M3_Cfdzoy_t=<error reading variable>) at ../src/Semaphore.m3:34
#3  0x000000000041c846 in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:660
#4  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#5  0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#6  0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#7  0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#8  0x0000000000000000 in ?? ()

Thread 7 (Thread 0x2aaaaf781700 (LWP 5178)):
#0  __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
#1  0x00002aaaac1b9339 in _L_lock_926 () from /lib/x86_64-linux-gnu/libpthread.so.0
#2  0x00002aaaac1b915b in __pthread_mutex_lock (mutex=0xf96880) at pthread_mutex_lock.c:61
#3  0x00000000004df034 in ThreadPThread__pthread_mutex_lock (mutex=0xf96880) at ../src/thread/PTHREAD/ThreadPThreadC.c:506
#4  0x00000000004de22a in RTOS__LockHeap () at ../src/thread/PTHREAD/ThreadPThread.m3:1375
#5  0x00000000004ca27f in RTHooks__CheckStoreTraced (M3_Af40ku_dst=<error reading variable>) at ../src/runtime/common/RTCollector.m3:2255
#6  0x000000000041c55f in PllERS__HandleFanout (M3_De1Q5p_cl=<error reading variable>, M3_BZemAb_f=...) at ../src/PllERS.m3:403
#7  0x000000000041c78d in PllERS__FlushFanouts (M3_De1Q5p_cl=<error reading variable>, M3_CiABk7_fi=<error reading variable>) at ../src/PllERS.m3:438
#8  0x000000000041c810 in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:652
#9  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#10 0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#11 0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#12 0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#13 0x0000000000000000 in ?? ()

Thread 6 (Thread 0x2aaaaf580700 (LWP 5177)):
#0  __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
#1  0x00002aaaac1b9339 in _L_lock_926 () from /lib/x86_64-linux-gnu/libpthread.so.0
#2  0x00002aaaac1b915b in __pthread_mutex_lock (mutex=0xf96880) at pthread_mutex_lock.c:61
#3  0x00000000004df034 in ThreadPThread__pthread_mutex_lock (mutex=0xf96880) at ../src/thread/PTHREAD/ThreadPThreadC.c:506
#4  0x00000000004de22a in RTOS__LockHeap () at ../src/thread/PTHREAD/ThreadPThread.m3:1375
#5  0x00000000004ca27f in RTHooks__CheckStoreTraced (M3_Af40ku_dst=<error reading variable>) at ../src/runtime/common/RTCollector.m3:2255
#6  0x000000000041c55f in PllERS__HandleFanout (M3_De1Q5p_cl=<error reading variable>, M3_BZemAb_f=...) at ../src/PllERS.m3:403
#7  0x000000000041c78d in PllERS__FlushFanouts (M3_De1Q5p_cl=<error reading variable>, M3_CiABk7_fi=<error reading variable>) at ../src/PllERS.m3:438
#8  0x000000000041c810 in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:652
#9  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#10 0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#11 0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#12 0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#13 0x0000000000000000 in ?? ()

Thread 5 (Thread 0x2aaaaf37f700 (LWP 5176)):
#0  __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
#1  0x00002aaaac1b9339 in _L_lock_926 () from /lib/x86_64-linux-gnu/libpthread.so.0
#2  0x00002aaaac1b915b in __pthread_mutex_lock (mutex=0xf96880) at pthread_mutex_lock.c:61
#3  0x00000000004df034 in ThreadPThread__pthread_mutex_lock (mutex=0xf96880) at ../src/thread/PTHREAD/ThreadPThreadC.c:506
#4  0x00000000004de22a in RTOS__LockHeap () at ../src/thread/PTHREAD/ThreadPThread.m3:1375
#5  0x00000000004ca120 in RTHooks__CheckLoadTracedRef (M3_Af40ku_ref=<error reading variable>) at ../src/runtime/common/RTCollector.m3:2234
#6  0x000000000041b78a in PllERS__DoOneTimestep (M3_De1Q5p_cl=<error reading variable>, M3_CiABk7_fi=<error reading variable>) at ../src/PllERS.m3:712
#7  0x000000000041c81e in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:653
#8  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#9  0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#10 0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#11 0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#12 0x0000000000000000 in ?? ()

Thread 4 (Thread 0x2aaaaf17e700 (LWP 5175)):
#0  __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
#1  0x00002aaaac1b9339 in _L_lock_926 () from /lib/x86_64-linux-gnu/libpthread.so.0
#2  0x00002aaaac1b915b in __pthread_mutex_lock (mutex=0xf96880) at pthread_mutex_lock.c:61
#3  0x00000000004df034 in ThreadPThread__pthread_mutex_lock (mutex=0xf96880) at ../src/thread/PTHREAD/ThreadPThreadC.c:506
#4  0x00000000004de22a in RTOS__LockHeap () at ../src/thread/PTHREAD/ThreadPThread.m3:1375
#5  0x00000000004ca120 in RTHooks__CheckLoadTracedRef (M3_Af40ku_ref=<error reading variable>) at ../src/runtime/common/RTCollector.m3:2234
#6  0x000000000041b48a in PllERS__DoOneTimestep (M3_De1Q5p_cl=<error reading variable>, M3_CiABk7_fi=<error reading variable>) at ../src/PllERS.m3:701
#7  0x000000000041c81e in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:653
#8  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#9  0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#10 0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#11 0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#12 0x0000000000000000 in ?? ()

Thread 3 (Thread 0x2aaaaef7d700 (LWP 5174)):
#0  sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86
#1  0x0000000000420a30 in SemaphoreC__sem_wait (sem=0xfadaf0) at ../src/SemaphoreC.c:16
#2  0x0000000000420bac in Semaphore (M3_Cfdzoy_t=<error reading variable>) at ../src/Semaphore.m3:34
#3  0x000000000041c846 in PllERS__CApply (M3_De1Q5p_cl=<error reading variable>) at ../src/PllERS.m3:660
#4  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#5  0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#6  0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#7  0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#8  0x0000000000000000 in ?? ()

Thread 2 (Thread 0x2aaaaed7c700 (LWP 5173)):
#0  pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:162
#1  0x00000000004deeda in ThreadPThread__pthread_cond_wait (i=0xf968c0, j=0xf96880) at ../src/thread/PTHREAD/ThreadPThreadC.c:454
#2  0x00000000004de3ce in RTOS__WaitHeap () at ../src/thread/PTHREAD/ThreadPThread.m3:1397
#3  0x00000000004c9d54 in RTCollector__WeakCleaner (M3_EMTrVz_closure=<error reading variable>) at ../src/runtime/common/RTCollector.m3:2185
#4  0x00000000004db633 in ThreadPThread__RunThread (M3_DMxDjQ_me=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:518
#5  0x00000000004db2f0 in ThreadPThread__ThreadBase (M3_AJWxb1_param=<error reading variable>) at ../src/thread/PTHREAD/ThreadPThread.m3:491
#6  0x00002aaaac1b6b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#7  0x00002aaaac4a6a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#8  0x0000000000000000 in ?? ()

Thread 1 (Thread 0x2aaaaeb7a2a0 (LWP 5163)):
#0  sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86
#1  0x0000000000420a30 in SemaphoreC__sem_wait (sem=0xfadb50) at ../src/SemaphoreC.c:16
#2  0x0000000000420bac in Semaphore (M3_Cfdzoy_t=<error reading variable>) at ../src/Semaphore.m3:34
#3  0x000000000041a998 in PllERS__WaitForWorkers (M3_Cfdzoy_s=<error reading variable>) at ../src/PllERS.m3:522
#4  0x000000000041c238 in PllERS__DoVisits (M3_De1Q5o_iter=<error reading variable>) at ../src/PllERS.m3:545
#5  0x000000000041223c in Main__DoDumpAll (M3_CIrmEi_dMode=<error reading variable>) at ../src/Main.m3:147
#6  0x0000000000419fb9 in Main_M3 (M3_AcxOUs_mode=<error reading variable>) at ../src/Main.m3:1244
#7  0x00000000004ce4d9 in RTLinker__RunMainBody (M3_DjPxE3_m=<error reading variable>) at ../src/runtime/common/RTLinker.m3:408
#8  0x00000000004cd864 in RTLinker__AddUnitI (M3_DjPxE3_m=<error reading variable>) at ../src/runtime/common/RTLinker.m3:115
#9  0x00000000004cd8f8 in RTLinker__AddUnit (M3_DjPxE5_b=<error reading variable>) at ../src/runtime/common/RTLinker.m3:124
#10 0x0000000000406278 in main (argc=5, argv=0x7fffffffe308, envp=0x7fffffffe338) at _m3main.c:22
-------------- next part --------------
(* $Id: Semaphore.m3,v 1.3 2014/08/23 05:50:51 mika Exp $ *)

UNSAFE MODULE Semaphore;
FROM SemaphoreC IMPORT 
  sem_init, sem_destroy, sem_post, sem_wait, sem_getvalue, sem_alloc;
IMPORT WeakRef;
FROM Ctypes IMPORT int;

REVEAL 
  T = BRANDED Brand REF RECORD
    sem : ADDRESS;
  END;

PROCEDURE New() : T =
  BEGIN
    WITH q = sem_alloc(),
         r = sem_init(q),
         n = NEW(T, sem := q) DO
      <*ASSERT r = 0*>
      EVAL WeakRef.FromRef(n, Cleanup);
      RETURN n
    END
  END New;

PROCEDURE Cleanup(<*UNUSED*>READONLY self : WeakRef.T; ref : REFANY) =
  VAR 
    d : T := ref;
  BEGIN
    WITH r = sem_destroy(d.sem) DO <*ASSERT r = 0*> END
  END Cleanup;

PROCEDURE P(t : T) =
  BEGIN
    WITH r = sem_wait(t.sem) DO <*ASSERT r=0*> END
  END P;

PROCEDURE V(t : T) =
  VAR r : INTEGER;
  BEGIN
    REPEAT r := sem_post(t.sem) UNTIL r = 0
  END V;

PROCEDURE Value(t : T) : INTEGER =
  VAR res : int;
  BEGIN 
    WITH r = sem_getvalue(t.sem, res) DO <*ASSERT r=0*> END;
    RETURN res
  END Value;

BEGIN END Semaphore.
-------------- next part --------------
(* $Id: Semaphore.i3,v 1.1 2014/08/23 02:50:54 mika Exp $ *)

INTERFACE Semaphore;

TYPE T <: REFANY;

PROCEDURE New() : T;

PROCEDURE P(t : T);

PROCEDURE V(t : T);

PROCEDURE Value(t : T) : INTEGER;

CONST Brand = "Semaphore";

END Semaphore.
-------------- next part --------------
(* $Id: SemaphoreC.i3,v 1.1 2014/08/23 02:50:54 mika Exp $ *)

INTERFACE SemaphoreC;
FROM Ctypes IMPORT int;

<*EXTERNAL "SemaphoreC__sem_alloc"*>
PROCEDURE sem_alloc() : ADDRESS;

<*EXTERNAL "SemaphoreC__sem_init"*>
PROCEDURE sem_init(sem : ADDRESS) : int;

<*EXTERNAL "SemaphoreC__sem_destroy"*>
PROCEDURE sem_destroy(sem : ADDRESS) : int;

<*EXTERNAL "SemaphoreC__sem_post"*>
PROCEDURE sem_post(sem : ADDRESS) : int;

<*EXTERNAL "SemaphoreC__sem_wait"*>
PROCEDURE sem_wait(sem : ADDRESS) : int;

<*EXTERNAL "SemaphoreC__sem_getvalue"*>
PROCEDURE sem_getvalue(sem : ADDRESS; VAR value : int) : int;

END SemaphoreC.
-------------- next part --------------
#include <semaphore.h>
#include <malloc.h>
#include <assert.h>
#include <stdio.h>
/* $Id: SemaphoreC.c,v 1.2 2014/08/23 05:50:51 mika Exp $ */

/* Author : Mika Nystrom <mika at alum.mit.edu> */

#define DEBUG 0
int 
SemaphoreC__sem_wait(void *sem)           
{ 
  int r;

  if(DEBUG)fprintf(stderr, "sem_wait(0x%x)--->\n", sem);
  r = sem_wait(sem); 
  if(DEBUG)fprintf(stderr, "<---sem_wait(0x%x)\n", sem);

  return r;
}

int 
SemaphoreC__sem_post(void * sem)           
{ 
  int r;
  if(DEBUG)fprintf(stderr, "sem_post(0x%x)\n", sem);
  r = sem_post(sem); 
  return r;
}

int 
SemaphoreC__sem_getvalue(void *sem, int *value) 
{ 
  int r = sem_getvalue(sem, value); 
  return r;
}

void *
SemaphoreC__sem_alloc(void) { 
  void *a=malloc(sizeof(sem_t)); 
  assert(a);
  return a;
}

int 
SemaphoreC__sem_init(void *sem)           
{ 
  return sem_init(sem, 0, 0); 
}

int 
SemaphoreC__sem_destroy(void *sem)           
{ 
  int r = sem_destroy(sem); 
  free(sem);
  return r;
}


More information about the M3devel mailing list