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@
This commit is contained in:
David Xu 2008-06-09 01:14:10 +00:00
parent e14e342b14
commit 83a0758789
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=179662
6 changed files with 75 additions and 32 deletions

View File

@ -135,6 +135,10 @@ enum pthread_mutextype {
#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_ERRORCHECK
struct _pthread_cleanup_info {
__uintptr_t pthread_cleanup_pad[8];
};
/*
* Thread function prototype definitions:
*/
@ -162,8 +166,19 @@ int pthread_barrierattr_getpshared(const pthread_barrierattr_t *,
int *);
int pthread_barrierattr_init(pthread_barrierattr_t *);
int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int);
void pthread_cleanup_pop(int);
void pthread_cleanup_push(void (*) (void *), void *);
#define pthread_cleanup_push(cleanup_routine, cleanup_arg) \
{ \
struct _pthread_cleanup_info __cleanup_info__; \
__pthread_cleanup_push_imp(cleanup_routine, cleanup_arg,\
&__cleanup_info__); \
{
#define pthread_cleanup_pop(execute) \
} \
__pthread_cleanup_pop_imp(execute); \
}
int pthread_condattr_destroy(pthread_condattr_t *);
int pthread_condattr_getclock(const pthread_condattr_t *,
clockid_t *);
@ -268,6 +283,10 @@ int pthread_setschedparam(pthread_t, int,
const struct sched_param *);
int pthread_getconcurrency(void);
int pthread_setconcurrency(int);
void __pthread_cleanup_push_imp(void (*)(void *), void *,
struct _pthread_cleanup_info *);
void __pthread_cleanup_pop_imp(int);
__END_DECLS
#endif

View File

@ -114,8 +114,6 @@
#define pthread_barrierattr_init _pthread_barrierattr_init
#define pthread_barrierattr_setpshared _pthread_barrierattr_setpshared
#define pthread_cancel _pthread_cancel
#define pthread_cleanup_pop _pthread_cleanup_pop
#define pthread_cleanup_push _pthread_cleanup_push
#define pthread_cond_broadcast _pthread_cond_broadcast
#define pthread_cond_destroy _pthread_cond_destroy
#define pthread_cond_init _pthread_cond_init

View File

@ -95,8 +95,6 @@
#undef pthread_barrierattr_init
#undef pthread_barrierattr_setpshared
#undef pthread_cancel
#undef pthread_cleanup_pop
#undef pthread_cleanup_push
#undef pthread_cond_broadcast
#undef pthread_cond_destroy
#undef pthread_cond_init

View File

@ -393,6 +393,8 @@ FBSDprivate_1.0 {
};
FBSD_1.1 {
__pthread_cleanup_pop_imp;
__pthread_cleanup_push_imp;
pthread_attr_getaffinity_np;
pthread_attr_setaffinity_np;
pthread_getaffinity_np;

View File

@ -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;
struct pthread_cleanup *newbuf;
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;
newbuf = (void *)info;
newbuf->routine = routine;
newbuf->routine_arg = arg;
newbuf->onheap = 0;
newbuf->prev = curthread->cleanup;
curthread->cleanup = newbuf;
}
curthread->cleanup = new;
void
__pthread_cleanup_pop_imp(int execute)
{
struct pthread *curthread = _get_curthread();
struct pthread_cleanup *old;
if ((old = curthread->cleanup) != NULL) {
curthread->cleanup = old->prev;
if (execute)
old->routine(old->routine_arg);
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)
{
struct pthread *curthread = _get_curthread();
struct pthread_cleanup *old;
if ((old = curthread->cleanup) != NULL) {
curthread->cleanup = old->next;
if (execute) {
old->routine(old->routine_arg);
}
if (old->onstack == 0)
free(old);
}
__pthread_cleanup_pop_imp(execute);
}

View File

@ -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, ...);