diff options
author | davidxu <davidxu@FreeBSD.org> | 2008-06-09 01:14:10 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2008-06-09 01:14:10 +0000 |
commit | f4d6ff9c5e2c00dd44c3e39b44c0000351d91c6d (patch) | |
tree | 64448ccd5c1431710c5a1f4513a5128d2db5c444 /lib/libthr/thread/thr_clean.c | |
parent | 7c70b8f716071ee1944fc97021c0857b385b755c (diff) | |
download | FreeBSD-src-f4d6ff9c5e2c00dd44c3e39b44c0000351d91c6d.zip FreeBSD-src-f4d6ff9c5e2c00dd44c3e39b44c0000351d91c6d.tar.gz |
Make pthread_cleanup_push() and pthread_cleanup_pop() as a pair of macros,
use stack space to keep cleanup information, this eliminates overhead of
calling malloc() and free() in thread library.
Discussed on: thread@
Diffstat (limited to 'lib/libthr/thread/thr_clean.c')
-rw-r--r-- | lib/libthr/thread/thr_clean.c | 55 |
1 files changed, 39 insertions, 16 deletions
diff --git a/lib/libthr/thread/thr_clean.c b/lib/libthr/thread/thr_clean.c index 9922798..9cef930 100644 --- a/lib/libthr/thread/thr_clean.c +++ b/lib/libthr/thread/thr_clean.c @@ -38,38 +38,61 @@ #include "thr_private.h" +#undef pthread_cleanup_push +#undef pthread_cleanup_pop + +/* old binary compatible interfaces */ __weak_reference(_pthread_cleanup_push, pthread_cleanup_push); __weak_reference(_pthread_cleanup_pop, pthread_cleanup_pop); void -_pthread_cleanup_push(void (*routine) (void *), void *routine_arg) +__pthread_cleanup_push_imp(void (*routine)(void *), void *arg, + struct _pthread_cleanup_info *info) { struct pthread *curthread = _get_curthread(); - struct pthread_cleanup *new; - - if ((new = (struct pthread_cleanup *) - malloc(sizeof(struct pthread_cleanup))) != NULL) { - new->routine = routine; - new->routine_arg = routine_arg; - new->onstack = 0; - new->next = curthread->cleanup; + struct pthread_cleanup *newbuf; - curthread->cleanup = new; - } + newbuf = (void *)info; + newbuf->routine = routine; + newbuf->routine_arg = arg; + newbuf->onheap = 0; + newbuf->prev = curthread->cleanup; + curthread->cleanup = newbuf; } void -_pthread_cleanup_pop(int execute) +__pthread_cleanup_pop_imp(int execute) { struct pthread *curthread = _get_curthread(); struct pthread_cleanup *old; if ((old = curthread->cleanup) != NULL) { - curthread->cleanup = old->next; - if (execute) { + curthread->cleanup = old->prev; + if (execute) old->routine(old->routine_arg); - } - if (old->onstack == 0) + if (old->onheap) free(old); } } + +void +_pthread_cleanup_push(void (*routine) (void *), void *arg) +{ + struct pthread *curthread = _get_curthread(); + struct pthread_cleanup *newbuf; + + if ((newbuf = (struct pthread_cleanup *) + malloc(sizeof(struct _pthread_cleanup_info))) != NULL) { + newbuf->routine = routine; + newbuf->routine_arg = arg; + newbuf->onheap = 1; + newbuf->prev = curthread->cleanup; + curthread->cleanup = newbuf; + } +} + +void +_pthread_cleanup_pop(int execute) +{ + __pthread_cleanup_pop_imp(execute); +} |