* files for more information.
*/
+#include "sbcl.h"
+
#include <stdio.h>
#include <string.h>
#include <libgen.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <signal.h>
+#ifdef LISP_FEATURE_SB_THREAD
#include <sys/ptrace.h>
+#endif
#include <sched.h>
#include <errno.h>
#include "signal.h"
#include "runtime.h"
-#include "sbcl.h"
#include "alloc.h"
#include "vars.h"
#include "globals.h"
}
/* Convert a null-terminated array of null-terminated strings (e.g.
- * argv or envp) into a Lisp list of Lisp strings. */
+ * argv or envp) into a Lisp list of Lisp base-strings. */
static lispobj
-alloc_string_list(char *array_ptr[])
+alloc_base_string_list(char *array_ptr[])
{
if (*array_ptr) {
- return alloc_cons(alloc_string(*array_ptr),
- alloc_string_list(1 + array_ptr));
+ return alloc_cons(alloc_base_string(*array_ptr),
+ alloc_base_string_list(1 + array_ptr));
} else {
return NIL;
}
/* Convert remaining argv values to something that Lisp can grok. */
SHOW("setting POSIX-ARGV symbol value");
- SetSymbolValue(POSIX_ARGV, alloc_string_list(argv),0);
+ SetSymbolValue(POSIX_ARGV, alloc_base_string_list(argv),0);
/* Install a handler to pick off SIGINT until the Lisp system gets
* far enough along to install its own handler. */
}
#ifdef LISP_FEATURE_SB_THREAD
-static void parent_do_garbage_collect(void)
-{
- int waiting_threads=0;
- struct thread *th;
- int status,p;
-
- for_each_thread(th) {
- if(ptrace(PTRACE_ATTACH,th->pid,0,0)) {
- fprintf(stderr,"attaching to %d ...",th->pid);
- perror("PTRACE_ATTACH");
- }
- else waiting_threads++;
- }
- stop_the_world=1;
-
- do {
- /* not sure if we have to wait for PTRACE_ATTACH to finish
- * before we can send PTRACE_CONT, so let's play it safe
- */
- while(waiting_threads>0) {
- if((p=waitpid(-1,&status, WUNTRACED|__WALL))>0) {
- if(WIFEXITED(status) || WIFSIGNALED(status))
- destroy_thread(find_thread_by_pid(p));
- else {
-#if 0
- fprintf(stderr, "wait returned pid %d signal %x\n",
- p,WSTOPSIG(status));
-#endif
- if(WSTOPSIG(status)==SIGTRAP) {
- if(ptrace(PTRACE_CONT,p,0,SIGTRAP))
- perror("PTRACE_CONT");
- }
- else waiting_threads--;
- }
- }
- }
- for_each_thread(th) {
- if(SymbolTlValue(PSEUDO_ATOMIC_ATOMIC,th)) {
- /* restart the child, setting *p-a-i* which will cause it
- * to go into interrupt_handle_pending as soon as it's
- * finished being pseudo_atomic. once there it will
- * signal itself SIGSTOP, which will give us another
- * event to wait for */
- fprintf(stderr, "%d was pseudo-atomic, letting it resume \n",
- th->pid);
- SetTlSymbolValue(PSEUDO_ATOMIC_INTERRUPTED,1,th) ;
- if(ptrace(PTRACE_CONT,th->pid,0,0))
- perror("PTRACE_CONT");
- waiting_threads++;
- }
- }
- } while (waiting_threads>0);
-
- 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");
-}
static void /* noreturn */ parent_loop(void)
{
struct sigaction sa;
sigset_t sigset;
int status;
+ pid_t pid=0;
sigemptyset(&sigset);
while(!all_threads) {
sched_yield();
}
-
- while(all_threads) {
- pid_t pid=0;
- while(pid=waitpid(-1,&status,__WALL|WUNTRACED)) {
- struct thread *th;
- fprintf(stderr,"waitpid pid %d\n",pid);
- 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));
+ while(all_threads && (pid=waitpid(-1,&status,__WALL|WUNTRACED))) {
+ struct thread *th;
+ int real_errno=errno;
+ if(pid==-1) {
+ if(real_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(real_errno == ECHILD) break;
+ fprintf(stderr,"waitpid: %s\n",strerror(real_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);
+ if(!all_threads) break;
}
}
exit(WEXITSTATUS(status));