From: Daniel B. <da...@us...> - 2003-04-30 00:46:12
|
Update of /cvsroot/sbcl/sbcl/src/runtime In directory sc8-pr-cvs1:/tmp/cvs-serv6353/src/runtime Modified Files: Tag: thread-gc-branch gencgc.c runtime.c Log Message: 0.pre8.119.thread-gc.1 Fix thread GC problems -- at the expense of utterly breaking GC for unithread systems, hence the branch. We can't use the normal mutex support for arbitrating access to SUB-GC, because it may need to cons when it adds threads to queues. So, instead, we make SUB-GC re-entrant. This means making it do essentially nothing more than signal the GC thread, and having all the gc threshold calculations for next time done by the GC thread in C. This also means we've lost the GC pre and post-hooks, and we've broken PURIFY - hnce the branch. This means we also need to make sure it's safe to signal the gc thread multiple times. This is simple enough, though. Index: gencgc.c =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/gencgc.c,v retrieving revision 1.32 retrieving revision 1.32.2.1 diff -u -d -r1.32 -r1.32.2.1 --- gencgc.c 25 Apr 2003 23:43:08 -0000 1.32 +++ gencgc.c 30 Apr 2003 00:46:08 -0000 1.32.2.1 @@ -129,7 +129,8 @@ /* the total bytes allocated. These are seen by Lisp DYNAMIC-USAGE. */ unsigned long bytes_allocated = 0; -static unsigned long auto_gc_trigger = 0; +unsigned long bytes_consed_between_gcs = 4*1024*1024; +unsigned long auto_gc_trigger = 0; /* the source and destination generations. These are set before a GC starts * scavenging. */ @@ -3984,7 +3985,10 @@ gc_alloc_generation = 0; update_x86_dynamic_space_free_pointer(); - + auto_gc_trigger = bytes_allocated + bytes_consed_between_gcs; + if(gencgc_verbose) + fprintf(stderr,"Next gc when %d bytes have been consed\n", + auto_gc_trigger); SHOW("returning from collect_garbage"); } @@ -4220,7 +4224,6 @@ * we should GC in the near future */ if (auto_gc_trigger && bytes_allocated > auto_gc_trigger) { - auto_gc_trigger *= 2; /* set things up so that GC happens when we finish the PA * section. */ maybe_gc_pending=1; @@ -4238,13 +4241,13 @@ void set_auto_gc_trigger(os_vm_size_t dynamic_usage) { - auto_gc_trigger += dynamic_usage; + /* auto_gc_trigger += dynamic_usage; */ } void clear_auto_gc_trigger(void) { - auto_gc_trigger = 0; + /* auto_gc_trigger = 0; */ } /* Find the code object for the given pc, or return NULL on failure. Index: runtime.c =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/runtime.c,v retrieving revision 1.25 retrieving revision 1.25.4.1 diff -u -d -r1.25 -r1.25.4.1 --- runtime.c 19 Apr 2003 20:11:31 -0000 1.25 +++ runtime.c 30 Apr 2003 00:46:08 -0000 1.25.4.1 @@ -418,8 +418,10 @@ * finished being pseudo_atomic. once there it will * signal itself SIGSTOP, which will give us another * event to wait for */ +#if 0 fprintf(stderr, "%d was pseudo-atomic, letting it resume \n", th->pid); +#endif SetTlSymbolValue(PSEUDO_ATOMIC_INTERRUPTED,make_fixnum(1),th); if(ptrace(PTRACE_CONT,th->pid,0,0)) perror("PTRACE_CONT"); @@ -431,7 +433,6 @@ collect_garbage(maybe_gc_pending-1); maybe_gc_pending=0; stop_the_world=0; - /* fprintf(stderr, "gc done\n"); */ for_each_thread(th) if(ptrace(PTRACE_DETACH,th->pid,0,0)) perror("PTRACE_DETACH"); @@ -442,6 +443,7 @@ struct sigaction sa; sigset_t sigset; int status; + pid_t pid=0; sigemptyset(&sigset); @@ -463,29 +465,26 @@ while(!all_threads) { sched_yield(); } - - while(all_threads) { - pid_t pid=0; - while(pid=waitpid(-1,&status,__WALL|WUNTRACED)) { - struct thread *th; - if(pid==-1) { - if(errno == EINTR) { - if(maybe_gc_pending) parent_do_garbage_collect(); - continue; - } - if(errno == ECHILD) break; - fprintf(stderr,"waitpid: %s\n",strerror(errno)); + maybe_gc_pending=0; + while(all_threads && (pid=waitpid(-1,&status,__WALL|WUNTRACED))) { + struct thread *th; + while(maybe_gc_pending) parent_do_garbage_collect(); + if(pid==-1) { + if(errno == EINTR) { continue; } - th=find_thread_by_pid(pid); - if(!th) continue; - if(WIFEXITED(status) || WIFSIGNALED(status)) { - fprintf(stderr,"waitpid : child %d %x exited \n", pid,th); - destroy_thread(th); - /* FIXME arrange to call or fake (free-mutex *session-lock*) - * if necessary */ - if(!all_threads) break; - } + if(errno == ECHILD) break; + fprintf(stderr,"waitpid: %s\n",strerror(errno)); + continue; + } + th=find_thread_by_pid(pid); + if(!th) continue; + if(WIFEXITED(status) || WIFSIGNALED(status)) { + fprintf(stderr,"waitpid : child %d %x exited \n", pid,th); + destroy_thread(th); + /* FIXME arrange to call or fake (free-mutex *session-lock*) + * if necessary */ + if(!all_threads) break; } } exit(WEXITSTATUS(status)); |