Plug a memory leak. When a cached thread is reused, don't clear sleep
queue pointers, just reuse it. PR: 164828 MFC after: 1 week
This commit is contained in:
parent
ec1a0f73d0
commit
e7004bf44d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=231106
@ -149,11 +149,16 @@ _thr_alloc(struct pthread *curthread)
|
||||
if (total_threads > MAX_THREADS)
|
||||
return (NULL);
|
||||
atomic_fetchadd_int(&total_threads, 1);
|
||||
thread = malloc(sizeof(struct pthread));
|
||||
thread = calloc(1, sizeof(struct pthread));
|
||||
if (thread == NULL) {
|
||||
atomic_fetchadd_int(&total_threads, -1);
|
||||
return (NULL);
|
||||
}
|
||||
thread->sleepqueue = _sleepq_alloc();
|
||||
thread->wake_addr = _thr_alloc_wake_addr();
|
||||
} else {
|
||||
bzero(&thread->_pthread_startzero,
|
||||
__rangeof(struct pthread, _pthread_startzero, _pthread_endzero));
|
||||
}
|
||||
if (curthread != NULL) {
|
||||
THR_LOCK_ACQUIRE(curthread, &tcb_lock);
|
||||
@ -163,10 +168,7 @@ _thr_alloc(struct pthread *curthread)
|
||||
tcb = _tcb_ctor(thread, 1 /* initial tls */);
|
||||
}
|
||||
if (tcb != NULL) {
|
||||
memset(thread, 0, sizeof(*thread));
|
||||
thread->tcb = tcb;
|
||||
thread->sleepqueue = _sleepq_alloc();
|
||||
thread->wake_addr = _thr_alloc_wake_addr();
|
||||
} else {
|
||||
thr_destroy(curthread, thread);
|
||||
atomic_fetchadd_int(&total_threads, -1);
|
||||
@ -194,8 +196,6 @@ _thr_free(struct pthread *curthread, struct pthread *thread)
|
||||
}
|
||||
thread->tcb = NULL;
|
||||
if ((curthread == NULL) || (free_thread_count >= MAX_CACHED_THREADS)) {
|
||||
_sleepq_free(thread->sleepqueue);
|
||||
_thr_release_wake_addr(thread->wake_addr);
|
||||
thr_destroy(curthread, thread);
|
||||
atomic_fetchadd_int(&total_threads, -1);
|
||||
} else {
|
||||
@ -213,6 +213,10 @@ _thr_free(struct pthread *curthread, struct pthread *thread)
|
||||
static void
|
||||
thr_destroy(struct pthread *curthread __unused, struct pthread *thread)
|
||||
{
|
||||
if (thread->sleepqueue != NULL)
|
||||
_sleepq_free(thread->sleepqueue);
|
||||
if (thread->wake_addr != NULL)
|
||||
_thr_release_wake_addr(thread->wake_addr);
|
||||
free(thread);
|
||||
}
|
||||
|
||||
|
@ -343,6 +343,7 @@ struct pthread_key {
|
||||
* Thread structure.
|
||||
*/
|
||||
struct pthread {
|
||||
#define _pthread_startzero tid
|
||||
/* Kernel thread id. */
|
||||
long tid;
|
||||
#define TID_TERMINATED 1
|
||||
@ -506,12 +507,6 @@ struct pthread {
|
||||
/* Event */
|
||||
td_event_msg_t event_buf;
|
||||
|
||||
struct wake_addr *wake_addr;
|
||||
#define WAKE_ADDR(td) ((td)->wake_addr)
|
||||
|
||||
/* Sleep queue */
|
||||
struct sleepqueue *sleepqueue;
|
||||
|
||||
/* Wait channel */
|
||||
void *wchan;
|
||||
|
||||
@ -526,6 +521,14 @@ struct pthread {
|
||||
|
||||
/* Deferred threads from pthread_cond_signal. */
|
||||
unsigned int *defer_waiters[MAX_DEFER_WAITERS];
|
||||
#define _pthread_endzero wake_addr
|
||||
|
||||
struct wake_addr *wake_addr;
|
||||
#define WAKE_ADDR(td) ((td)->wake_addr)
|
||||
|
||||
/* Sleep queue */
|
||||
struct sleepqueue *sleepqueue;
|
||||
|
||||
};
|
||||
|
||||
#define THR_SHOULD_GC(thrd) \
|
||||
|
Loading…
Reference in New Issue
Block a user