on master help sign in
Fix leak of ThreadData

Valgrind detected this memory leak amongst others: $ valgrind --leak-check=full --show-leak-kinds=all --trace-children=yes ./coop ==32242== 32 bytes in 1 blocks are still reachable in loss record 1 of 4 ==32242== at 0x483880B: malloc (vg_replace_malloc.c:309) ==32242== by 0x409888: vmThread (idris_rts.c:825) ==32242== by 0x404683: _idris_System_46_Concurrency_46_Channels_46_spawn (in /home/l337/OpenSource/Haskell/Idris-dev/coop) ==32242== by 0x4031A3: _idris_Main_46_main (in /home/l337/OpenSource/Haskell/Idris-dev/coop) ==32242== by 0x4066E9: _idris__123_runMain_95_0_125_ (in /home/l337/OpenSource/Haskell/Idris-dev/coop) ==32242== by 0x408D0C: main (in /home/l337/OpenSource/Haskell/Idris-dev/coop)

commit73e0a9834627c1b9fae6caa49af6d2ad6d509492 authorJonas Claeson <jonas.cl@protonmail.com> dateSat 23 Mar 2019, 10:37 (8 years ago) parent0597159
2 files changed+11−11
rts/idris_rts.c+10−11 rts/idris_rts.h+1
rts/idris_rts.c+10−11
@@ -72,6 +72,7 @@ VM* init_vm(int stack_size, size_t heap_size,
7272
7373 vm->max_threads = max_threads;
7474 vm->processes = 0;
75+ vm->creator = NULL;
7576
7677#else
7778 global_vm = vm;
@@ -784,7 +785,6 @@ VAL idris_systemInfo(VM* vm, VAL index) {
784785#ifdef HAS_PTHREAD
785786typedef struct {
786787 VM* vm; // thread's VM
787− VM* callvm; // calling thread's VM
788788 func fn;
789789 VAL arg;
790790} ThreadData;
@@ -792,21 +792,17 @@ typedef struct {
792792void* runThread(void* arg) {
793793 ThreadData* td = (ThreadData*)arg;
794794 VM* vm = td->vm;
795− VM* callvm = td->callvm;
795+ func fn = td->fn;
796796
797797 init_threaddata(vm);
798798
799799 TOP(0) = td->arg;
800800 BASETOP(0);
801801 ADDTOP(1);
802− td->fn(vm, NULL);
803− callvm->processes--;
804−
805802 free(td);
803+ fn(vm, NULL);
806804
807− // Stats stats =
808− terminate(vm);
809− // aggregate_stats(&(td->vm->stats), &stats);
805+ assert(0); // will not be reached
810806 return NULL;
811807}
812808
@@ -814,6 +810,7 @@ void* vmThread(VM* callvm, func f, VAL arg) {
814810 VM* vm = init_vm(callvm->stack_max - callvm->valstack, callvm->heap.size,
815811 callvm->max_threads);
816812 vm->processes=1; // since it can send and receive messages
813+ vm->creator = callvm;
817814 pthread_t t;
818815 pthread_attr_t attr;
819816// size_t stacksize;
@@ -822,9 +819,8 @@ void* vmThread(VM* callvm, func f, VAL arg) {
822819// pthread_attr_getstacksize (&attr, &stacksize);
823820// pthread_attr_setstacksize (&attr, stacksize*64);
824821
825− ThreadData *td = malloc(sizeof(ThreadData));
822+ ThreadData *td = malloc(sizeof(ThreadData)); // free'd in runThread
826823 td->vm = vm;
827− td->callvm = callvm;
828824 td->fn = f;
829825 td->arg = copyTo(vm, arg);
830826
@@ -841,7 +837,10 @@ void* vmThread(VM* callvm, func f, VAL arg) {
841837}
842838
843839void* idris_stopThread(VM* vm) {
844− close_vm(vm);
840+ if (vm->creator != NULL) {
841+ vm->creator->processes--;
842+ }
843+ terminate(vm);
845844 pthread_exit(NULL);
846845 return NULL;
847846}
rts/idris_rts.h+1
@@ -152,6 +152,7 @@ struct VM {
152152
153153 int processes; // Number of child processes
154154 int max_threads; // maximum number of threads to run in parallel
155+ struct VM* creator; // The VM that created this VM, NULL for root VM
155156#endif
156157 Stats stats;
157158