From: Daniel B. <da...@us...> - 2003-01-17 03:30:35
|
Update of /cvsroot/sbcl/sbcl/src/runtime In directory sc8-pr-cvs1:/tmp/cvs-serv19926/src/runtime Modified Files: Tag: dan_native_threads_branch gencgc.c interrupt.c run-program.c thread.c Log Message: "0.7.9.54.thread.16" #+angels-fear-to-thread Shortened RUN-PROGRAM considerably: it now does tty mode setting in C, using Posix calls, instead of in Lisp using old BSD sgtty stuff. Introduce (MAKE-LISTENER-THREAD "/path/to/tty"): new function that runs a listener in a thread on the given tty Fix race condition in thread startup that was causing occasional GC assertions Minor loss of debugging printfs (not serious) [To test the listener stuff, you need to give it the name of a tty that is (a) open, readable, writable, (b) not actively being read by any other process that may confuse things. :; cat ./src/runtime/nop.sh #!/bin/sh echo "tty is `tty`" while : ; do sleep 3600; done :; sh ./src/runtime/nop.sh tty is /dev/pts/2 * (make-listener-thread "/dev/pts/2") ] Index: gencgc.c =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/gencgc.c,v retrieving revision 1.24.4.9 retrieving revision 1.24.4.10 diff -u -d -r1.24.4.9 -r1.24.4.10 --- gencgc.c 16 Jan 2003 17:15:20 -0000 1.24.4.9 +++ gencgc.c 17 Jan 2003 03:30:31 -0000 1.24.4.10 @@ -4159,8 +4159,11 @@ /* Check for alignment allocation problems. */ gc_assert((((unsigned)region->free_pointer & 0x7) == 0) && ((nbytes & 0x7) == 0)); - - gc_assert(SymbolValue(PSEUDO_ATOMIC_ATOMIC,th)); + if(all_threads) + /* there are a few places in the C code that allocate data in the + * heap before Lisp starts. This is before interrupts are enabled, + * so we don't need to check for pseudo-atomic */ + gc_assert(SymbolValue(PSEUDO_ATOMIC_ATOMIC,th)); /* maybe we can do this quickly ... */ new_free_pointer = region->free_pointer + nbytes; Index: interrupt.c =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/interrupt.c,v retrieving revision 1.32.4.6 retrieving revision 1.32.4.7 diff -u -d -r1.32.4.6 -r1.32.4.7 --- interrupt.c 16 Jan 2003 17:15:20 -0000 1.32.4.6 +++ interrupt.c 17 Jan 2003 03:30:31 -0000 1.32.4.7 @@ -238,7 +238,6 @@ lispobj context_sap = 0; fake_foreign_function_call(context); - describe_internal_error(context); /* Allocate the SAP object while the interrupts are still * disabled. */ @@ -287,7 +286,6 @@ SetSymbolValue(INTERRUPT_PENDING, NIL,thread); if (maybe_gc_pending) { - fprintf(stderr,"gc pending, %d thread waiting\n",thread->pid); #ifndef __i386__ if (were_in_lisp) #endif Index: run-program.c =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/run-program.c,v retrieving revision 1.4 retrieving revision 1.4.6.1 diff -u -d -r1.4 -r1.4.6.1 --- run-program.c 4 Apr 2002 16:07:51 -0000 1.4 +++ run-program.c 17 Jan 2003 03:30:31 -0000 1.4.6.1 @@ -23,6 +23,34 @@ #include <unistd.h> #endif +#include <sys/ioctl.h> +#include <termios.h> + + +/* borrowed from detachtty's detachtty.c, in turn borrowed from APUE + * example code found at + * http://www.yendor.com/programming/unix/apue/pty/main.c + +-brkint + + */ + +int set_noecho(int fd) +{ + struct termios stermios; + + if (tcgetattr(fd, &stermios) < 0) return 0; + + stermios.c_lflag &= ~( ECHO | /* ECHOE | ECHOK | */ ECHONL); + stermios.c_oflag |= (ONLCR); + stermios.c_iflag &= ~(BRKINT); + stermios.c_iflag |= (ICANON|ICRNL); + + stermios.c_cc[VERASE]=0177; + if (tcsetattr(fd, TCSANOW, &stermios) < 0) return 0; + return 1; +} + int spawn(char *program, char *argv[], char *envp[], char *pty_name, int stdin, int stdout, int stderr) { @@ -50,22 +78,21 @@ close(fd); } #endif - fd = open(pty_name, O_RDWR, 0); dup2(fd, 0); + set_noecho(0); dup2(fd, 1); dup2(fd, 2); close(fd); + } else{ + /* Set up stdin, stdout, and stderr */ + if (stdin >= 0) + dup2(stdin, 0); + if (stdout >= 0) + dup2(stdout, 1); + if (stderr >= 0) + dup2(stderr, 2); } - - /* Set up stdin, stdout, and stderr */ - if (stdin >= 0) - dup2(stdin, 0); - if (stdout >= 0) - dup2(stdout, 1); - if (stderr >= 0) - dup2(stderr, 2); - /* Close all other fds. */ #ifdef SVR4 for (fd = sysconf(_SC_OPEN_MAX)-1; fd >= 3; fd--) Index: thread.c =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/Attic/thread.c,v retrieving revision 1.1.2.10 retrieving revision 1.1.2.11 diff -u -d -r1.1.2.10 -r1.1.2.11 --- thread.c 21 Dec 2002 00:11:09 -0000 1.1.2.10 +++ thread.c 17 Jan 2003 03:30:31 -0000 1.1.2.11 @@ -34,9 +34,11 @@ { lispobj function = th->unbound_marker; th->unbound_marker = UNBOUND_MARKER_WIDETAG; - - FSHOW((stderr, "/pausing 0x%lx(%d) before new_thread_trampoline(0x%lx)\n", - (unsigned long)th,getpid(),(unsigned long)function)); + /* wait here until our thread is linked into all_threads: see below */ + while(th->pid<1) sched_yield(); + + FSHOW((stderr, "/pausing 0x%lx(%d,%d) before new_thread_trampoline(0x%lx)\n", + (unsigned long)th,th->pid,getpid(),(unsigned long)function)); if(go==0) { while(go==0) ; FSHOW((stderr, "/continue\n")); @@ -59,7 +61,8 @@ union per_thread_data *per_thread; struct thread *th=0; /* subdue gcc */ void *spaces=0; - + pid_t kid_pid; + /* may as well allocate all the spaces at once: it saves us from * having to decide what to do if only some of the allocations * succeed */ @@ -111,6 +114,7 @@ (lispobj*)((void*)th->binding_stack_start+BINDING_STACK_SIZE); th->binding_stack_pointer=th->binding_stack_start; th->this=th; + th->pid=0; #ifdef LISP_FEATURE_STACK_GROWS_DOWNWARD_NOT_UPWARD th->alien_stack_pointer=((void *)th->alien_stack_start + ALIEN_STACK_SIZE-4); /* naked 4. FIXME */ @@ -134,18 +138,19 @@ #if defined(LISP_FEATURE_X86) && defined (LISP_FEATURE_LINUX) th->unbound_marker=initial_function; - th->pid= + kid_pid= clone(new_thread_trampoline, (((void*)th->control_stack_start)+THREAD_CONTROL_STACK_SIZE-4), (((getpid()!=parent_pid)?CLONE_PARENT:0) |CLONE_SIGHAND|CLONE_VM),th); - fprintf(stderr,"child pid is %d\n",th->pid); - if(th->pid<=0) goto cleanup; - + fprintf(stderr,"child pid is %d\n",kid_pid); + if(kid_pid<=0) goto cleanup; #else #error this stuff presently only works on x86 Linux #endif all_threads=th; + fprintf(stderr,"all_threads,th = 0x%x, 0x%x\n",all_threads,th); + th->pid=kid_pid; /* child will not start until this is set */ return th; cleanup: /* if(th && th->tls_cookie>=0) os_free_tls_pointer(th); */ |