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:
parent
e14e342b14
commit
83a0758789
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=179662
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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, ...);
|
||||
|
Loading…
Reference in New Issue
Block a user