X-Git-Url: http://nitlanguage.org diff --git a/lib/pthreads/pthreads.nit b/lib/pthreads/pthreads.nit index 900063f..91ebb94 100644 --- a/lib/pthreads/pthreads.nit +++ b/lib/pthreads/pthreads.nit @@ -16,7 +16,7 @@ # Main POSIX threads support and intro the classes `Thread`, `Mutex` and `Barrier` module pthreads is - cflags "-pthread" + cflags "-pthread -Wno-unknown-attributes" ldflags "-pthread" pkgconfig "bdw-gc" new_annotation threaded @@ -33,13 +33,13 @@ in "C Header" `{ `} in "C" `{ + #include + // 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 - #endif + #define GC_THREADS + #include `} redef class Sys @@ -81,6 +81,61 @@ redef class Sys end end + +# An atomic Int +extern class AtomicInt in "C" `{ int* `} + new(i: Int)`{ + int* v = malloc(sizeof(int)); + return v; + `} + + # Get the value and increment it by `i` + fun get_and_increment_by(i: Int): Int `{ + return __sync_fetch_and_add(self, i); + `} + + # Get the value and decrement it by `i` + fun get_and_decrement_by(i: Int): Int `{ + return __sync_fetch_and_sub(self, i); + `} + + # Get the value and increment it + fun get_and_increment: Int `{ + return __sync_fetch_and_add(self, 1); + `} + + # Get the value and decrement it + fun get_and_decrement: Int `{ + return __sync_fetch_and_sub(self, 1); + `} + + # Increment by `i` and get the new value + fun increment_by_and_get(i: Int): Int `{ + return __sync_add_and_fetch(self, i); + `} + + # Decrement by `i` and get the new value + fun decrement_by_and_get(i: Int): Int `{ + return __sync_sub_and_fetch(self, i); + `} + + # Increment the value and get the new one + fun increment_and_get: Int `{ + return __sync_add_and_fetch(self, 1); + `} + + # Decrement the value and get the new one + fun decrement_and_get: Int `{ + return __sync_sub_and_fetch(self,1); + `} + + # Get the current value + fun value: Int `{ + return *self; + `} + +end + private extern class NativePthread in "C" `{ pthread_t * `} new create(nit_thread: Thread) import Thread.main_intern `{ @@ -119,7 +174,7 @@ private extern class NativePthread in "C" `{ pthread_t * `} fun equal(other: NativePthread): Bool `{ return pthread_equal(*self, *other); `} - fun kill(signal: Int) `{ pthread_kill(*self, signal); `} + fun kill(signal: Int): Int `{ return pthread_kill(*self, (int)signal); `} end private extern class NativePthreadAttr in "C" `{ pthread_attr_t * `} @@ -155,7 +210,11 @@ end private extern class NativePthreadMutex in "C" `{ pthread_mutex_t * `} new (attr: NativePthreadMutexAttr) `{ pthread_mutex_t *mutex = malloc(sizeof(pthread_mutex_t)); - int res = pthread_mutex_init(mutex, attr); + int r = pthread_mutex_init(mutex, attr); + if (r != 0) { + free(mutex); + return NULL; + } return mutex; `} @@ -169,7 +228,11 @@ end private extern class NativePthreadMutexAttr in "C" `{ pthread_mutexattr_t * `} new `{ pthread_mutexattr_t *attr = malloc(sizeof(pthread_mutexattr_t)); - int res = pthread_mutexattr_init(attr); + int r = pthread_mutexattr_init(attr); + if (r != 0) { + free(attr); + return NULL; + } return attr; `} @@ -188,7 +251,11 @@ end private extern class NativePthreadKey in "C" `{ pthread_key_t * `} new `{ pthread_key_t *key = malloc(sizeof(pthread_key_t)); - int res = pthread_key_create(key, NULL); + int r = pthread_key_create(key, NULL); + if (r != 0) { + free(key); + return NULL; + } return key; `} @@ -217,7 +284,7 @@ private extern class NativePthreadCond in "C" `{ pthread_cond_t * `} fun destroy `{ pthread_cond_destroy(self); `} - fun signal `{ pthread_cond_signal(self); `} + fun signal: Int `{ return pthread_cond_signal(self); `} fun broadcast `{ pthread_cond_broadcast(self); `} @@ -356,6 +423,25 @@ class Mutex end end +# Condition variable +class PthreadCond + super FinalizableOnce + + private var native = new NativePthreadCond + + # Destroy `self` + redef fun finalize_once do native.destroy + + # Signal at least one thread waiting to wake up + fun signal: Int do return native.signal + + # Signal all the waiting threads to wake up + fun broadcast do native.broadcast + + # Make the current thread waiting for a signal ( `mutex` should be locked) + fun wait(mutex: Mutex) do native.wait(mutex.native.as(not null)) +end + # Barrier synchronization tool # # Ensures that `count` threads call and block on `wait` before releasing them.