X-Git-Url: http://git.harvie.cz/?a=blobdiff_plain;f=c%2Fpthread_extra%2Fpthread_user_data.c;h=87055127dcd178921e68599a0c970b6f02aa2967;hb=0b8d006aa72c56eff1368c6c69b09547c455a5ed;hp=b86c4a3291a300247e7bd70046eb6d22682fa9f5;hpb=883427014d5349442395c1059af5a1abade951ad;p=mirrors%2FPrograms.git diff --git a/c/pthread_extra/pthread_user_data.c b/c/pthread_extra/pthread_user_data.c index b86c4a3..8705512 100644 --- a/c/pthread_extra/pthread_user_data.c +++ b/c/pthread_extra/pthread_user_data.c @@ -1,32 +1,74 @@ #define __PTHREAD_EXTRA_INTERNAL +#ifndef _GNU_SOURCE +#define _GNU_SOURCE //PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP +#endif //_GNU_SOURCE + +//#include +#include #include #include //Static array with user data for all thread handles //TODO: perhaps use something more sophisticated like linked list? pthread_user_data_internal_t pthread_user_data[PTHREAD_XTHREADS_MAX+1] = {{.tid=PTHREAD_XNULL}}; +pthread_mutex_t pthread_user_data_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; + +int pthread_user_data_lock() { + //pthread_pause_disable(); + return pthread_mutex_lock(&pthread_user_data_mutex); +} + +int pthread_user_data_unlock() { + pthread_mutex_unlock(&pthread_user_data_mutex); + //pthread_pause_enable(); + return 0; +} //Get pointer to internal record tied to specified thread pthread_user_data_internal_t* pthread_user_data_internal(pthread_t thread) { //Return NULL if requested thread handle is NULL if(pthread_equal(thread, PTHREAD_XNULL)) return NULL; + //Lock + pthread_user_data_lock(); //TODO: maybe use R/W locking scheme? + //Find if the thread is already registered, add it if not - //FIXME: recycle slots of destroyed threads!!! + //FIXME: detect overflow of array and cause assert fail! + //FIXME: recycle slots of destroyed threads!!! signaled using pthread_user_data_remove(); pthread_t i; for(i = 0; iusr; @@ -41,3 +83,17 @@ void pthread_user_data_set(pthread_t thread, void *usr) { void* pthread_user_data_get(pthread_t thread) { return *(pthread_user_data_ptr(thread)); } + +//Remove canceled thread from user data registry +int pthread_user_data_remove(pthread_t thread) { + //FIXME: not implemented yet! + (void) thread; + return 0; +} + +//User data cleanup handler to be registered with pthread_cleanup_push() +void pthread_user_data_cleanup( void * arg ) { + pthread_t t = (pthread_t)arg; + assert(pthread_equal(t, pthread_self()) && "Pthread_self() is not working in cleanup context!"); + pthread_user_data_remove(t); +}