struct thread *all_threads;
volatile lispobj all_threads_lock;
extern struct interrupt_data * global_interrupt_data;
+extern int linux_no_threads_p;
int
initial_thread_trampoline(struct thread *th)
if(th->pid < 1) lose("th->pid not set up right");
th->state=STATE_RUNNING;
-#if defined(LISP_FEATURE_X86)
+#if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
return call_into_lisp_first_time(function,args,0);
#else
return funcall0(function);
th->state=STATE_STOPPED;
#ifdef LISP_FEATURE_STACK_GROWS_DOWNWARD_NOT_UPWARD
th->alien_stack_pointer=((void *)th->alien_stack_start
- + ALIEN_STACK_SIZE-4); /* naked 4. FIXME */
+ + ALIEN_STACK_SIZE-N_WORD_BYTES);
#else
th->alien_stack_pointer=((void *)th->alien_stack_start);
#endif
-#ifdef LISP_FEATURE_X86
+#if defined(LISP_FEATURE_X86) || defined (LISP_FEATURE_X86_64)
th->pseudo_atomic_interrupted=0;
th->pseudo_atomic_atomic=0;
#endif
SetSymbolValue(BINDING_STACK_START,(lispobj)th->binding_stack_start,th);
SetSymbolValue(CONTROL_STACK_START,(lispobj)th->control_stack_start,th);
SetSymbolValue(CONTROL_STACK_END,(lispobj)th->control_stack_end,th);
-#ifdef LISP_FEATURE_X86
+#if defined(LISP_FEATURE_X86) || defined (LISP_FEATURE_X86_64)
SetSymbolValue(BINDING_STACK_POINTER,(lispobj)th->binding_stack_pointer,th);
SetSymbolValue(ALIEN_STACK,(lispobj)th->alien_stack_pointer,th);
SetSymbolValue(PSEUDO_ATOMIC_ATOMIC,(lispobj)th->pseudo_atomic_atomic,th);
bind_variable(INTERRUPT_PENDING, NIL,th);
bind_variable(INTERRUPTS_ENABLED,T,th);
- th->interrupt_data=os_validate(0,(sizeof (struct interrupt_data)));
+ th->interrupt_data =
+ os_validate(0,(sizeof (struct interrupt_data)));
if(all_threads)
memcpy(th->interrupt_data,
arch_os_get_current_thread()->interrupt_data,
#ifdef LISP_FEATURE_SB_THREAD
pid_t create_thread(lispobj initial_function) {
- struct thread *th=create_thread_struct(initial_function);
+ struct thread *th;
pid_t kid_pid=0;
+ if(linux_no_threads_p) return 0;
+ th=create_thread_struct(initial_function);
if(th==0) return 0;
kid_pid=clone(new_thread_trampoline,
(((void*)th->control_stack_start)+
#if defined LISP_FEATURE_SB_THREAD
/* This is not needed unless #+SB-THREAD, as there's a trivial null
* unithread definition. */
+
+void mark_dead_threads()
+{
+ pid_t kid;
+ int status;
+ while(1) {
+ kid=waitpid(-1,&status,__WALL|WNOHANG);
+ if(kid<=0) break;
+ if(WIFEXITED(status) || WIFSIGNALED(status)) {
+ struct thread *th=find_thread_by_pid(kid);
+ if(th) th->state=STATE_DEAD;
+ }
+ }
+}
+
void reap_dead_threads()
{
struct thread *th,*next,*prev=0;
int interrupt_thread(pid_t pid, lispobj function)
{
union sigval sigval;
+ struct thread *th;
sigval.sival_int=function;
-
- return sigqueue(pid, SIG_INTERRUPT_THREAD, sigval);
+ for_each_thread(th)
+ if((th->pid==pid) && (th->state != STATE_DEAD))
+ return sigqueue(pid, SIG_INTERRUPT_THREAD, sigval);
+ errno=EPERM; return -1;
}
int signal_thread_to_dequeue (pid_t pid)
if(p==th) continue;
if(p->state==STATE_RUNNING) {
p->state=STATE_STOPPING;
- kill(p->pid,SIG_STOP_FOR_GC);
+ if(kill(p->pid,SIG_STOP_FOR_GC)==-1) {
+ /* we can't kill the process; assume because it
+ * died already (and its parent is dead so never
+ * saw the SIGCHLD) */
+ p->state=STATE_DEAD;
+ }
}
if((p->state!=STATE_STOPPED) &&
(p->state!=STATE_DEAD)) {