From: Martin Baulig Date: Wed, 28 Jun 2006 20:06:07 +0000 (+0000) Subject: 2006-06-28 Martin Baulig X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0a479d109d5ef02aea62c94b9d1cfc3450ab92e1;p=gc 2006-06-28 Martin Baulig * darwin_stop_world.c, pthread_support.c: Committing a patch from Allan Hsu to fix memory leaks; see bug #78628. svn path=/trunk/mono/; revision=62128 --- diff --git a/ChangeLog b/ChangeLog index 10a9354e..fbc3c604 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2006-06-28 Martin Baulig + + * darwin_stop_world.c, pthread_support.c: Committing a patch from + Allan Hsu to fix memory leaks; see bug #78628. + 2006-06-26 Zoltan Varga * solaris_threads.c: And another one. diff --git a/darwin_stop_world.c b/darwin_stop_world.c index 53604450..3c2d8cfa 100644 --- a/darwin_stop_world.c +++ b/darwin_stop_world.c @@ -167,6 +167,7 @@ void GC_push_all_stacks() { void GC_push_all_stacks() { int i; + task_t my_task; kern_return_t r; mach_port_t me; ptr_t lo, hi; @@ -176,7 +177,8 @@ void GC_push_all_stacks() { me = mach_thread_self(); if (!GC_thr_initialized) GC_thr_init(); - r = task_threads(current_task(), &act_list, &listcount); + my_task = current_task(); + r = task_threads(my_task, &act_list, &listcount); if(r != KERN_SUCCESS) ABORT("task_threads failed"); for(i = 0; i < listcount; i++) { thread_act_t thread = act_list[i]; @@ -265,9 +267,11 @@ void GC_push_all_stacks() { (unsigned long) hi ); # endif - GC_push_all_stack(lo, hi); + GC_push_all_stack(lo, hi); + mach_port_deallocate(my_task, thread); } /* for(p=GC_threads[i]...) */ - vm_deallocate(current_task(), (vm_address_t)act_list, sizeof(thread_t) * listcount); + vm_deallocate(my_task, (vm_address_t)act_list, sizeof(thread_t) * listcount); + mach_port_deallocate(my_task, me); } #endif /* !DARWIN_DONT_PARSE_STACK */ @@ -361,6 +365,8 @@ int GC_suspend_thread_list(thread_act_array_t act_list, int count, } if (!found) GC_mach_threads_count++; } + + mach_port_deallocate(current_task(), my_thread); return changed; } @@ -370,6 +376,7 @@ void GC_stop_world() { int i, changes; GC_thread p; + task_t my_task = current_task(); mach_port_t my_thread = mach_thread_self(); kern_return_t kern_result; thread_act_array_t act_list, prev_list; @@ -405,13 +412,21 @@ void GC_stop_world() prevcount = 0; do { int result; - kern_result = task_threads(current_task(), &act_list, &listcount); + kern_result = task_threads(my_task, &act_list, &listcount); result = GC_suspend_thread_list(act_list, listcount, prev_list, prevcount); changes = result; prev_list = act_list; prevcount = listcount; - vm_deallocate(current_task(), (vm_address_t)act_list, sizeof(thread_t) * listcount); + + if(kern_result == KERN_SUCCESS) { + int i; + + for(i = 0; i < listcount; i++) + mach_port_deallocate(my_task, act_list[i]); + + vm_deallocate(my_task, (vm_address_t)act_list, sizeof(thread_t) * listcount); + } } while (changes); @@ -428,12 +443,15 @@ void GC_stop_world() #if DEBUG_THREADS GC_printf1("World stopped from 0x%lx\n", my_thread); #endif + + mach_port_deallocate(my_task, my_thread); } /* Caller holds allocation lock, and has held it continuously since */ /* the world stopped. */ void GC_start_world() { + task_t my_task = current_task(); mach_port_t my_thread = mach_thread_self(); int i, j; GC_thread p; @@ -454,7 +472,7 @@ void GC_start_world() } # endif - kern_result = task_threads(current_task(), &act_list, &listcount); + kern_result = task_threads(my_task, &act_list, &listcount); for(i = 0; i < listcount; i++) { thread_act_t thread = act_list[i]; if (thread != my_thread && @@ -482,8 +500,12 @@ void GC_start_world() } } } + + mach_port_deallocate(my_task, thread); } - vm_deallocate(current_task(), (vm_address_t)act_list, sizeof(thread_t) * listcount); + vm_deallocate(my_task, (vm_address_t)act_list, sizeof(thread_t) * listcount); + + mach_port_deallocate(my_task, my_thread); # if DEBUG_THREADS GC_printf0("World started\n"); # endif diff --git a/pthread_support.c b/pthread_support.c index 8ee8dfd0..9baeeddc 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -659,6 +659,11 @@ void GC_delete_thread(pthread_t id) if (gc_thread_vtable && gc_thread_vtable->thread_exited) gc_thread_vtable->thread_exited (id, &p->stop_info.stack_ptr); #endif + +#ifdef GC_DARWIN_THREADS + mach_port_deallocate(mach_task_self(), p->stop_info.mach_thread); +#endif + GC_INTERNAL_FREE(p); } @@ -681,6 +686,11 @@ void GC_delete_gc_thread(pthread_t id, GC_thread gc_id) } else { prev -> next = p -> next; } + +#ifdef GC_DARWIN_THREADS + mach_port_deallocate(mach_task_self(), p->stop_info.mach_thread); +#endif + GC_INTERNAL_FREE(p); }