# Main POSIX threads support and intro the classes `Thread`, `Mutex` and `Barrier`
module pthreads is
- c_compiler_option("-pthread")
- c_linker_option("-pthread")
+ cflags "-pthread"
+ ldflags "-pthread"
+ pkgconfig "bdw-gc"
end
#
// TODO protect with: #ifdef WITH_LIBGC
// We might have to add the next line to gc_chooser.c too, especially
// if we get an error like "thread not registered with GC".
+ #ifndef ANDROID
#define GC_THREADS
#include <gc.h>
- //#endif
+ #endif
`}
redef class Sys
return (nullable_Object)thread_return;
`}
- fun attr: NativePthreadAttr `{
- pthread_attr_t *pattr = malloc(sizeof(pthread_attr_t));
- pthread_getattr_np(*recv, pattr);
- return pattr;
- `}
-
- fun equal(other: NativePthread): Bool `{ pthread_equal(*recv, *other); `}
+ fun equal(other: NativePthread): Bool `{ return pthread_equal(*recv, *other); `}
fun kill(signal: Int) `{ pthread_kill(*recv, signal); `}
end
# pthread_mutexattr_setrobust_np
end
-private extern class NativePthreadBarrier in "C" `{ pthread_barrier_t * `}
- new(count: Int) `{
- pthread_barrier_t *barrier = malloc(sizeof(pthread_barrier_t));
- int res = pthread_barrier_init(barrier, NULL, count);
- return barrier;
- `}
-
- fun destroy `{ pthread_barrier_destroy(recv); `}
-
- fun wait `{ pthread_barrier_wait(recv); `}
-end
-
private extern class NativePthreadKey in "C" `{ pthread_key_t * `}
new `{
pthread_key_t *key = malloc(sizeof(pthread_key_t));
`}
end
+private extern class NativePthreadCond in "C" `{ pthread_cond_t * `}
+ new `{
+ pthread_cond_t cond;
+ int r = pthread_cond_init(&cond, NULL);
+ if (r == 0) {
+ pthread_cond_t *pcond = malloc(sizeof(pthread_cond_t));
+ memmove(pcond, &cond, sizeof(pthread_cond_t));
+ return pcond;
+ }
+ return NULL;
+ `}
+
+ fun destroy `{ pthread_cond_destroy(recv); `}
+
+ fun signal `{ pthread_cond_signal(recv); `}
+
+ fun broadcast `{ pthread_cond_broadcast(recv); `}
+
+ fun wait(mutex: NativePthreadMutex) `{ pthread_cond_wait(recv, mutex); `}
+end
+
#
## Nity part
#
class Barrier
super Finalizable
+ private var mutex = new Mutex
+ private var cond: nullable NativePthreadCond = new NativePthreadCond
+
# Number of threads that must be waiting for `wait` to unblock
var count: Int
- private var native: nullable NativePthreadBarrier is noinit
-
- init do native = new NativePthreadBarrier(count)
+ private var threads_waiting = 0
# Wait at this barrier and block until there are a `count` threads waiting
- fun wait do native.wait
+ fun wait
+ do
+ mutex.lock
+ threads_waiting += 1
+ if threads_waiting == count then
+ threads_waiting = 0
+ cond.broadcast
+ else
+ cond.wait(mutex.native.as(not null))
+ end
+ mutex.unlock
+ end
redef fun finalize
do
- var native = self.native
- if native != null then
- native.destroy
- native.free
+ var cond = self.cond
+ if cond != null then
+ cond.destroy
+ cond.free
end
- self.native = null
+ self.cond = null
end
end