X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fovs-thread.c;h=b3a87bb12bc9db88630cb59a10f0dde936705a90;hb=69fc54f47bbc35e81bfe2e38e57f5dcfd9858df4;hp=c8b2c15999439a37b530f4ce62556c20d86b6167;hpb=d017eeb9f9ebcb46c24a67fd301b3e36cd26a04e;p=sliver-openvswitch.git diff --git a/lib/ovs-thread.c b/lib/ovs-thread.c index c8b2c1599..b3a87bb12 100644 --- a/lib/ovs-thread.c +++ b/lib/ovs-thread.c @@ -47,6 +47,7 @@ static bool multithreaded; void \ ovs_##TYPE##_##FUN##_at(const struct ovs_##TYPE *l_, \ const char *where) \ + OVS_NO_THREAD_SAFETY_ANALYSIS \ { \ struct ovs_##TYPE *l = CONST_CAST(struct ovs_##TYPE *, l_); \ int error = pthread_##TYPE##_##FUN(&l->lock); \ @@ -63,6 +64,7 @@ LOCK_FUNCTION(rwlock, wrlock); int \ ovs_##TYPE##_##FUN##_at(const struct ovs_##TYPE *l_, \ const char *where) \ + OVS_NO_THREAD_SAFETY_ANALYSIS \ { \ struct ovs_##TYPE *l = CONST_CAST(struct ovs_##TYPE *, l_); \ int error = pthread_##TYPE##_##FUN(&l->lock); \ @@ -81,6 +83,7 @@ TRY_LOCK_FUNCTION(rwlock, trywrlock); #define UNLOCK_FUNCTION(TYPE, FUN) \ void \ ovs_##TYPE##_##FUN(const struct ovs_##TYPE *l_) \ + OVS_NO_THREAD_SAFETY_ANALYSIS \ { \ struct ovs_##TYPE *l = CONST_CAST(struct ovs_##TYPE *, l_); \ int error; \ @@ -114,6 +117,8 @@ UNLOCK_FUNCTION(rwlock, destroy); } \ } +XPTHREAD_FUNC1(pthread_mutex_lock, pthread_mutex_t *); +XPTHREAD_FUNC1(pthread_mutex_unlock, pthread_mutex_t *); XPTHREAD_FUNC1(pthread_mutexattr_init, pthread_mutexattr_t *); XPTHREAD_FUNC1(pthread_mutexattr_destroy, pthread_mutexattr_t *); XPTHREAD_FUNC2(pthread_mutexattr_settype, pthread_mutexattr_t *, int); @@ -124,11 +129,14 @@ XPTHREAD_FUNC1(pthread_cond_destroy, pthread_cond_t *); XPTHREAD_FUNC1(pthread_cond_signal, pthread_cond_t *); XPTHREAD_FUNC1(pthread_cond_broadcast, pthread_cond_t *); +XPTHREAD_FUNC2(pthread_join, pthread_t, void **); + typedef void destructor_func(void *); XPTHREAD_FUNC2(pthread_key_create, pthread_key_t *, destructor_func *); +XPTHREAD_FUNC2(pthread_setspecific, pthread_key_t, const void *); -void -ovs_mutex_init(const struct ovs_mutex *l_, int type) +static void +ovs_mutex_init__(const struct ovs_mutex *l_, int type) { struct ovs_mutex *l = CONST_CAST(struct ovs_mutex *, l_); pthread_mutexattr_t attr; @@ -144,6 +152,20 @@ ovs_mutex_init(const struct ovs_mutex *l_, int type) xpthread_mutexattr_destroy(&attr); } +/* Initializes 'mutex' as a normal (non-recursive) mutex. */ +void +ovs_mutex_init(const struct ovs_mutex *mutex) +{ + ovs_mutex_init__(mutex, PTHREAD_MUTEX_ERRORCHECK); +} + +/* Initializes 'mutex' as a recursive mutex. */ +void +ovs_mutex_init_recursive(const struct ovs_mutex *mutex) +{ + ovs_mutex_init__(mutex, PTHREAD_MUTEX_RECURSIVE); +} + void ovs_rwlock_init(const struct ovs_rwlock *l_) { @@ -166,18 +188,49 @@ ovs_mutex_cond_wait(pthread_cond_t *cond, const struct ovs_mutex *mutex_) ovs_abort(error, "pthread_cond_wait failed"); } } + +DEFINE_EXTERN_PER_THREAD_DATA(ovsthread_id, 0); + +struct ovsthread_aux { + void *(*start)(void *); + void *arg; +}; + +static void * +ovsthread_wrapper(void *aux_) +{ + static atomic_uint next_id = ATOMIC_VAR_INIT(1); + + struct ovsthread_aux *auxp = aux_; + struct ovsthread_aux aux; + unsigned int id; + + atomic_add(&next_id, 1, &id); + *ovsthread_id_get() = id; + + aux = *auxp; + free(auxp); + + return aux.start(aux.arg); +} void xpthread_create(pthread_t *threadp, pthread_attr_t *attr, void *(*start)(void *), void *arg) { + struct ovsthread_aux *aux; pthread_t thread; int error; forbid_forking("multiple threads exist"); multithreaded = true; - error = pthread_create(threadp ? threadp : &thread, attr, start, arg); + aux = xmalloc(sizeof *aux); + aux->start = start; + aux->arg = arg; + + error = pthread_create(threadp ? threadp : &thread, attr, + ovsthread_wrapper, aux); if (error) { ovs_abort(error, "pthread_create failed"); }