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 | |
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')
-rw-r--r-- | lib/libthr/thread/thr_clean.c | 55 | ||||
-rw-r--r-- | lib/libthr/thread/thr_private.h | 15 |
2 files changed, 48 insertions, 22 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); +} diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h index e84ba23..e336b2c 100644 --- a/lib/libthr/thread/thr_private.h +++ b/lib/libthr/thread/thr_private.h @@ -176,10 +176,10 @@ struct pthread_spinlock { * Cleanup definitions. */ struct pthread_cleanup { - struct pthread_cleanup *next; - void (*routine)(void *args); + struct pthread_cleanup *prev; + void (*routine)(void *); void *routine_arg; - int onstack; + int onheap; }; #define THR_CLEANUP_PUSH(td, func, arg) { \ @@ -187,12 +187,12 @@ struct pthread_cleanup { \ __cup.routine = func; \ __cup.routine_arg = arg; \ - __cup.onstack = 1; \ - __cup.next = (td)->cleanup; \ + __cup.onheap = 0; \ + __cup.prev = (td)->cleanup; \ (td)->cleanup = &__cup; #define THR_CLEANUP_POP(td, exec) \ - (td)->cleanup = __cup.next; \ + (td)->cleanup = __cup.prev; \ if ((exec) != 0) \ __cup.routine(__cup.routine_arg); \ } @@ -661,6 +661,9 @@ void _thread_bp_create(void); void _thread_bp_death(void); int _sched_yield(void); +void _pthread_cleanup_push(void (*)(void *), void *); +void _pthread_cleanup_pop(int); + /* #include <fcntl.h> */ #ifdef _SYS_FCNTL_H_ int __sys_fcntl(int, int, ...); |