|  | #ifndef GCC_GTHR_AKAROS_H | 
|  | #define GCC_GTHR_AKAROS_H | 
|  |  | 
|  | /* Akaros threads specific definitions. | 
|  | * | 
|  | * See gthr.h for more info. */ | 
|  |  | 
|  | #define __GTHREADS 1 | 
|  | #define __GTHREAD_HAS_COND 1 | 
|  | #define __GTHREADS_CXX0X 1 | 
|  |  | 
|  | #include <parlib/uthread.h> | 
|  | #include <parlib/dtls.h> | 
|  | #include <ros/errno.h> | 
|  |  | 
|  | typedef dtls_key_t __gthread_key_t; | 
|  | typedef parlib_once_t __gthread_once_t; | 
|  | #define __GTHREAD_ONCE_INIT PARLIB_ONCE_INIT | 
|  | typedef uth_mutex_t __gthread_mutex_t; | 
|  | typedef uth_recurse_mutex_t __gthread_recursive_mutex_t; | 
|  | typedef uth_cond_var_t __gthread_cond_t; | 
|  | typedef struct uthread * __gthread_t; | 
|  | typedef struct timespec __gthread_time_t; | 
|  |  | 
|  | /* It'd be nice to be able to use these static initializers, and they work in | 
|  | * C, but thanks to C++ not being able to do things that C can | 
|  | * (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55606), these give us errors. | 
|  | * We should be OK if we use the INIT functions.  Incidentally, I think you | 
|  | * need the INIT functions even if you have the macros defined, contrary to the | 
|  | * guidance. */ | 
|  | //#define __GTHREAD_MUTEX_INIT UTH_MUTEX_INIT | 
|  | //#define __GTHREAD_RECURSIVE_MUTEX_INIT UTH_RECURSE_MUTEX_INIT | 
|  | //#define __GTHREAD_COND_INIT UTH_COND_VAR_INIT | 
|  |  | 
|  | static inline int __gthread_active_p(void) | 
|  | { | 
|  | return uth_2ls_is_multithreaded() ? 1 : 0; | 
|  | } | 
|  |  | 
|  | static inline int __gthread_once(__gthread_once_t *once, void (*func)(void)) | 
|  | { | 
|  | parlib_run_once(once, (void (*)(void *))func, NULL); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline void __gthread_mutex_init_function(__gthread_mutex_t *gth_mtx) | 
|  | { | 
|  | uth_mutex_init(gth_mtx); | 
|  | } | 
|  | #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function | 
|  |  | 
|  | static inline int __gthread_mutex_destroy(__gthread_mutex_t *gth_mtx) | 
|  | { | 
|  | uth_mutex_destroy(gth_mtx); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline int __gthread_mutex_lock(__gthread_mutex_t *gth_mtx) | 
|  | { | 
|  | uth_mutex_lock(gth_mtx); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline int __gthread_mutex_trylock(__gthread_mutex_t *gth_mtx) | 
|  | { | 
|  | return uth_mutex_trylock(gth_mtx) ? 0 : EBUSY; | 
|  | } | 
|  |  | 
|  | static inline int __gthread_mutex_unlock(__gthread_mutex_t *gth_mtx) | 
|  | { | 
|  | uth_mutex_unlock(gth_mtx); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline void | 
|  | __gthread_recursive_mutex_init_function(__gthread_recursive_mutex_t *gth_r_mtx) | 
|  | { | 
|  | uth_recurse_mutex_init(gth_r_mtx); | 
|  | } | 
|  | #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION \ | 
|  | __gthread_recursive_mutex_init_function | 
|  |  | 
|  | static inline int | 
|  | __gthread_recursive_mutex_destroy(__gthread_recursive_mutex_t *gth_r_mtx) | 
|  | { | 
|  | uth_recurse_mutex_destroy(gth_r_mtx); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline int | 
|  | __gthread_recursive_mutex_lock(__gthread_recursive_mutex_t *gth_r_mtx) | 
|  | { | 
|  | uth_recurse_mutex_lock(gth_r_mtx); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline int | 
|  | __gthread_recursive_mutex_trylock(__gthread_recursive_mutex_t *gth_r_mtx) | 
|  | { | 
|  | return uth_recurse_mutex_trylock(gth_r_mtx) ? 0 : EBUSY; | 
|  | } | 
|  |  | 
|  | static inline int | 
|  | __gthread_recursive_mutex_unlock(__gthread_recursive_mutex_t *gth_r_mtx) | 
|  | { | 
|  | uth_recurse_mutex_unlock(gth_r_mtx); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline int __gthread_key_create(__gthread_key_t *keyp, | 
|  | void (*dtor)(void *)) | 
|  | { | 
|  | *keyp = dtls_key_create(dtor); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline int __gthread_key_delete(__gthread_key_t key) | 
|  | { | 
|  | dtls_key_delete(key); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline void *__gthread_getspecific(__gthread_key_t key) | 
|  | { | 
|  | return get_dtls(key); | 
|  | } | 
|  |  | 
|  | static inline int __gthread_setspecific(__gthread_key_t key, const void *ptr) | 
|  | { | 
|  | set_dtls(key, ptr); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline void __gthread_cond_init_function(__gthread_cond_t *cond) | 
|  | { | 
|  | uth_cond_var_init(cond); | 
|  | } | 
|  | #define __GTHREAD_COND_INIT_FUNCTION __gthread_cond_init_function | 
|  |  | 
|  | static inline int __gthread_cond_destroy(__gthread_cond_t *cond) | 
|  | { | 
|  | uth_cond_var_destroy(cond); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline int __gthread_cond_broadcast(__gthread_cond_t *cond) | 
|  | { | 
|  | uth_cond_var_broadcast(cond); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline int __gthread_cond_wait(__gthread_cond_t *cond, | 
|  | __gthread_mutex_t *mutex) | 
|  | { | 
|  | uth_cond_var_wait(cond, mutex); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline int | 
|  | __gthread_cond_wait_recursive(__gthread_cond_t *cond, | 
|  | __gthread_recursive_mutex_t *mutex) | 
|  | { | 
|  | uth_cond_var_wait_recurse(cond, mutex); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline int __gthread_create(__gthread_t *thread, void *(*func) (void*), | 
|  | void *args) | 
|  | { | 
|  | *thread = uthread_create(func, args); | 
|  | return *thread ? 0 : -1; | 
|  | } | 
|  |  | 
|  | static inline int __gthread_join(__gthread_t thread, void **value_ptr) | 
|  | { | 
|  | uthread_join(thread, value_ptr); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline int __gthread_detach(__gthread_t thread) | 
|  | { | 
|  | uthread_detach(thread); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline int __gthread_equal(__gthread_t t1, __gthread_t t2) | 
|  | { | 
|  | return t1 == t2; | 
|  | } | 
|  |  | 
|  | static inline __gthread_t __gthread_self(void) | 
|  | { | 
|  | return uthread_self(); | 
|  | } | 
|  |  | 
|  | static inline int __gthread_yield(void) | 
|  | { | 
|  | uthread_sched_yield(); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline int __gthread_mutex_timedlock(__gthread_mutex_t *m, | 
|  | const __gthread_time_t *abs_timeout) | 
|  | { | 
|  | return uth_mutex_timed_lock(m, abs_timeout) ? 0 : -ETIMEDOUT; | 
|  | } | 
|  |  | 
|  | static inline int | 
|  | __gthread_recursive_mutex_timedlock(__gthread_recursive_mutex_t *m, | 
|  | const __gthread_time_t *abs_timeout) | 
|  | { | 
|  | return uth_recurse_mutex_timed_lock(m, abs_timeout) ? 0 : -ETIMEDOUT; | 
|  | } | 
|  |  | 
|  | static inline int __gthread_cond_signal(__gthread_cond_t *cond) | 
|  | { | 
|  | uth_cond_var_signal(cond); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static inline int __gthread_cond_timedwait(__gthread_cond_t *cond, | 
|  | __gthread_mutex_t *mutex, | 
|  | const __gthread_time_t *abs_timeout) | 
|  | { | 
|  | return uth_cond_var_timed_wait(cond, mutex, abs_timeout) ? 0 : -ETIMEDOUT; | 
|  | } | 
|  |  | 
|  | #endif /* GCC_GTHR_AKAROS_H */ |