/* 
 * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
 *
 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
 * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
 *
 * Permission is hereby granted to use or copy this program
 * for any purpose,  provided the above notices are retained on all copies.
 * Permission to modify the code and to distribute modified code is granted,
 * provided the above notices are retained, and a notice that the code was
 * modified is included with the above copyright notice.
 */
/*
 * Support code for Solaris threads.  Provides functionality we wish Sun
 * had provided.  Relies on some information we probably shouldn't rely on.
 */
/* Boehm, September 14, 1994 4:44 pm PDT */

# include "private/gc_priv.h"

# if defined(GC_SOLARIS_THREADS) || defined(GC_SOLARIS_PTHREADS)
# include "private/solaris_threads.h"
# include <thread.h>
# include <synch.h>
# include <signal.h>
# include <fcntl.h>
# include <sys/types.h>
# include <sys/mman.h>
# include <sys/time.h>
# include <sys/resource.h>
# include <sys/stat.h>
# include <sys/syscall.h>
# include <sys/procfs.h>
# include <sys/lwp.h>
# include <sys/reg.h>
# define _CLASSIC_XOPEN_TYPES
# include <unistd.h>
# include <errno.h>

#ifdef HANDLE_FORK
  --> Not yet supported.  Try porting the code from linux_threads.c.
#endif

/*
 * This is the default size of the LWP arrays. If there are more LWPs
 * than this when a stop-the-world GC happens, set_max_lwps will be
 * called to cope.
 * This must be higher than the number of LWPs at startup time.
 * The threads library creates a thread early on, so the min. is 3
 */
# define DEFAULT_MAX_LWPS	4

#undef thr_join
#undef thr_create
#undef thr_suspend
#undef thr_continue

cond_t GC_prom_join_cv;		/* Broadcast when any thread terminates	*/
cond_t GC_create_cv;		/* Signalled when a new undetached	*/
				/* thread starts.			*/
				

#ifdef MMAP_STACKS
static int GC_zfd;
#endif /* MMAP_STACKS */

/* We use the allocation lock to protect thread-related data structures. */

/* We stop the world using /proc primitives.  This makes some	*/
/* minimal assumptions about the threads implementation.	*/
/* We don't play by the rules, since the rules make this	*/
/* impossible (as of Solaris 2.3).  Also note that as of	*/
/* Solaris 2.3 the various thread and lwp suspension		*/
/* primitives failed to stop threads by the time the request	*/
/* is completed.						*/


static sigset_t old_mask;

/* Sleep for n milliseconds, n < 1000	*/
void GC_msec_sleep(int n)
{
    struct timespec ts;
                            
    ts.tv_sec = 0;
    ts.tv_nsec = 1000000*n;
    if (syscall(SYS_nanosleep, &ts, 0) < 0) {
	ABORT("nanosleep failed");
    }
}
/* Turn off preemption;  gross but effective.  		*/
/* Caller has allocation lock.				*/
/* Actually this is not needed under Solaris 2.3 and	*/
/* 2.4, but hopefully that'll change.			*/
void preempt_off()
{
    sigset_t set;

    (void)sigfillset(&set);
    sigdelset(&set, SIGABRT);
    syscall(SYS_sigprocmask, SIG_SETMASK, &set, &old_mask);
}

void preempt_on()
{
    syscall(SYS_sigprocmask, SIG_SETMASK, &old_mask, NULL);
}

int GC_main_proc_fd = -1;


struct lwp_cache_entry {
    lwpid_t lc_id;
    int lc_descr;	/* /proc file descriptor.	*/
}  GC_lwp_cache_default[DEFAULT_MAX_LWPS];

static int max_lwps = DEFAULT_MAX_LWPS;
static struct lwp_cache_entry *GC_lwp_cache = GC_lwp_cache_default;

static prgregset_t GC_lwp_registers_default[DEFAULT_MAX_LWPS];
static prgregset_t *GC_lwp_registers = GC_lwp_registers_default;

/* Return a file descriptor for the /proc entry corresponding	*/
/* to the given lwp.  The file descriptor may be stale if the	*/
/* lwp exited and a new one was forked.				*/
static int open_lwp(lwpid_t id)
{
    int result;
    static int next_victim = 0;
    register int i;
    
    for (i = 0; i < max_lwps; i++) {
    	if (GC_lwp_cache[i].lc_id == id) return(GC_lwp_cache[i].lc_descr);
    }
    result = syscall(SYS_ioctl, GC_main_proc_fd, PIOCOPENLWP, &id);
    /*
     * If PIOCOPENLWP fails, try closing fds in the cache until it succeeds.
     */
    if (result < 0 && errno == EMFILE) {
	    for (i = 0; i < max_lwps; i++) {
		if (GC_lwp_cache[i].lc_id != 0) {
        		(void)syscall(SYS_close, GC_lwp_cache[i].lc_descr);
			result = syscall(SYS_ioctl, GC_main_proc_fd, PIOCOPENLWP, &id);
			if (result >= 0 || (result < 0 && errno != EMFILE))
				break;
		}
	    }
    }
    if (result < 0) {
	if (errno == EMFILE) {
		ABORT("Too many open files");
	}
        return(-1) /* exited? */;
    }
    if (GC_lwp_cache[next_victim].lc_id != 0)
        (void)syscall(SYS_close, GC_lwp_cache[next_victim].lc_descr);
    GC_lwp_cache[next_victim].lc_id = id;
    GC_lwp_cache[next_victim].lc_descr = result;
    if (++next_victim >= max_lwps)
	next_victim = 0;
    return(result);
}

static void uncache_lwp(lwpid_t id)
{
    register int i;
    
    for (i = 0; i < max_lwps; i++) {
    	if (GC_lwp_cache[i].lc_id == id) {
    	    (void)syscall(SYS_close, GC_lwp_cache[id].lc_descr);
    	    GC_lwp_cache[i].lc_id = 0;
    	    break;
    	}
    }
}
	/* Sequence of current lwp ids	*/
static lwpid_t GC_current_ids_default[DEFAULT_MAX_LWPS + 1];
static lwpid_t *GC_current_ids = GC_current_ids_default;

	/* Temporary used below (can be big if large number of LWPs) */
static lwpid_t last_ids_default[DEFAULT_MAX_LWPS + 1];
static lwpid_t *last_ids = last_ids_default;


#define ROUNDUP(n)    WORDS_TO_BYTES(ROUNDED_UP_WORDS(n))

static void set_max_lwps(GC_word n)
{
    char *mem;
    char *oldmem;
    int required_bytes = ROUNDUP(n * sizeof(struct lwp_cache_entry))
	+ ROUNDUP(n * sizeof(prgregset_t))
	+ ROUNDUP((n + 1) * sizeof(lwpid_t))
	+ ROUNDUP((n + 1) * sizeof(lwpid_t));

    GC_expand_hp_inner(divHBLKSZ((word)required_bytes));
    oldmem = mem = GC_scratch_alloc(required_bytes);
    if (0 == mem) ABORT("No space for lwp data structures");

    /*
     * We can either flush the old lwp cache or copy it over. Do the latter.
     */
    memcpy(mem, GC_lwp_cache, max_lwps * sizeof(struct lwp_cache_entry));
    GC_lwp_cache = (struct lwp_cache_entry*)mem;
    mem += ROUNDUP(n * sizeof(struct lwp_cache_entry));

    BZERO(GC_lwp_registers, max_lwps * sizeof(GC_lwp_registers[0]));
    GC_lwp_registers = (prgregset_t *)mem;
    mem += ROUNDUP(n * sizeof(prgregset_t));


    GC_current_ids = (lwpid_t *)mem;
    mem += ROUNDUP((n + 1) * sizeof(lwpid_t));

    last_ids = (lwpid_t *)mem;
    mem += ROUNDUP((n + 1)* sizeof(lwpid_t));

    if (mem > oldmem + required_bytes)
	ABORT("set_max_lwps buffer overflow");

    max_lwps = n;
}


/* Stop all lwps in process.  Assumes preemption is off.	*/
/* Caller has allocation lock (and any other locks he may	*/
/* need).							*/
static void stop_all_lwps()
{
    int lwp_fd;
    char buf[30];
    prstatus_t status;
    register int i;
    GC_bool changed;
    lwpid_t me = _lwp_self();

    if (GC_main_proc_fd == -1) {
    	sprintf(buf, "/proc/%d", getpid());
    	GC_main_proc_fd = syscall(SYS_open, buf, O_RDONLY);
        if (GC_main_proc_fd < 0) {
		if (errno == EMFILE)
			ABORT("/proc open failed: too many open files");
		GC_printf1("/proc open failed: errno %d", errno);
		abort();
        }
    }
    BZERO(GC_lwp_registers, sizeof (prgregset_t) * max_lwps);
    for (i = 0; i < max_lwps; i++)
	last_ids[i] = 0;
    for (;;) {
        if (syscall(SYS_ioctl, GC_main_proc_fd, PIOCSTATUS, &status) < 0)
    	    ABORT("Main PIOCSTATUS failed");
    	if (status.pr_nlwp < 1)
    		ABORT("Invalid number of lwps returned by PIOCSTATUS");
    	if (status.pr_nlwp >= max_lwps) {
    		set_max_lwps(status.pr_nlwp*2 + 10);
		/*
		 * The data in the old GC_current_ids and
		 * GC_lwp_registers has been trashed. Cleaning out last_ids
		 * will make sure every LWP gets re-examined.
		 */
        	for (i = 0; i < max_lwps; i++)
			last_ids[i] = 0;
		continue;
    	}
        if (syscall(SYS_ioctl, GC_main_proc_fd, PIOCLWPIDS, GC_current_ids) < 0)
            ABORT("PIOCLWPIDS failed");
        changed = FALSE;
        for (i = 0; GC_current_ids[i] != 0 && i < max_lwps; i++) {
            if (GC_current_ids[i] != last_ids[i]) {
                changed = TRUE;
                if (GC_current_ids[i] != me) {
		    /* PIOCSTOP doesn't work without a writable		*/
		    /* descriptor.  And that makes the process		*/
		    /* undebuggable.					*/
                    if (_lwp_suspend(GC_current_ids[i]) < 0) {
                        /* Could happen if the lwp exited */
                        uncache_lwp(GC_current_ids[i]);
                        GC_current_ids[i] = me; /* ignore */
                    }
                }
            }
        }
        /*
         * In the unlikely event something does a fork between the
	 * PIOCSTATUS and the PIOCLWPIDS. 
         */
        if (i >= max_lwps)
		continue;
        /* All lwps in GC_current_ids != me have been suspended.  Note	*/
        /* that _lwp_suspend is idempotent.				*/
        for (i = 0; GC_current_ids[i] != 0; i++) {
            if (GC_current_ids[i] != last_ids[i]) {
                if (GC_current_ids[i] != me) {
                    lwp_fd = open_lwp(GC_current_ids[i]);
		    if (lwp_fd == -1)
		    {
			    GC_current_ids[i] = me;
			    continue;
		    }
		    /* LWP should be stopped.  Empirically it sometimes	*/
		    /* isn't, and more frequently the PR_STOPPED flag	*/
		    /* is not set.  Wait for PR_STOPPED.		*/
                    if (syscall(SYS_ioctl, lwp_fd,
                                PIOCSTATUS, &status) < 0) {
			/* Possible if the descriptor was stale, or */
			/* we encountered the 2.3 _lwp_suspend bug. */
			uncache_lwp(GC_current_ids[i]);
                        GC_current_ids[i] = me; /* handle next time. */
                    } else {
                        while (!(status.pr_flags & PR_STOPPED)) {
                            GC_msec_sleep(1);
			    if (syscall(SYS_ioctl, lwp_fd,
				    	PIOCSTATUS, &status) < 0) {
                            	ABORT("Repeated PIOCSTATUS failed");
			    }
			    if (status.pr_flags & PR_STOPPED) break;
			    
			    GC_msec_sleep(20);
			    if (syscall(SYS_ioctl, lwp_fd,
				    	PIOCSTATUS, &status) < 0) {
                            	ABORT("Repeated PIOCSTATUS failed");
			    }
                        }
                        if (status.pr_who !=  GC_current_ids[i]) {
				/* can happen if thread was on death row */
				uncache_lwp(GC_current_ids[i]);
				GC_current_ids[i] = me; /* handle next time. */
				continue;	
                        }
                        /* Save registers where collector can */
			/* find them.			  */
			    BCOPY(status.pr_reg, GC_lwp_registers[i],
				  sizeof (prgregset_t));
                    }
                }
            }
        }
        if (!changed) break;
        for (i = 0; i < max_lwps; i++) last_ids[i] = GC_current_ids[i];
    }
}

/* Restart all lwps in process.  Assumes preemption is off.	*/
static void restart_all_lwps()
{
    int lwp_fd;
    register int i;
    GC_bool changed;
    lwpid_t me = _lwp_self();
#   define PARANOID

    for (i = 0; GC_current_ids[i] != 0; i++) {
#	ifdef PARANOID
	  if (GC_current_ids[i] != me) {
	    int lwp_fd = open_lwp(GC_current_ids[i]);
	    prstatus_t status;
	    
	    if (lwp_fd < 0) ABORT("open_lwp failed");
	    if (syscall(SYS_ioctl, lwp_fd,
			PIOCSTATUS, &status) < 0) {
                ABORT("PIOCSTATUS failed in restart_all_lwps");
	    }
	    if (memcmp(status.pr_reg, GC_lwp_registers[i],
		       sizeof (prgregset_t)) != 0) {
		    int j;

		    for(j = 0; j < NPRGREG; j++)
		    {
			    GC_printf3("%i: %x -> %x\n", j,
				       GC_lwp_registers[i][j],
				       status.pr_reg[j]);
		    }
		ABORT("Register contents changed");
	    }
	    if (!status.pr_flags & PR_STOPPED) {
	    	ABORT("lwp no longer stopped");
	    }
#ifdef SPARC
	    {
		    gwindows_t windows;
	      if (syscall(SYS_ioctl, lwp_fd,
			PIOCGWIN, &windows) < 0) {
                ABORT("PIOCSTATUS failed in restart_all_lwps");
	      }
	      if (windows.wbcnt > 0) ABORT("unsaved register windows");
	    }
#endif
	  }
#	endif /* PARANOID */
	if (GC_current_ids[i] == me) continue;
        if (_lwp_continue(GC_current_ids[i]) < 0) {
            ABORT("Failed to restart lwp");
        }
    }
    if (i >= max_lwps) ABORT("Too many lwps");
}

GC_bool GC_multithreaded = 0;

void GC_stop_world()
{
    preempt_off();
    if (GC_multithreaded)
        stop_all_lwps();
}

void GC_start_world()
{
    if (GC_multithreaded)
        restart_all_lwps();
    preempt_on();
}

void GC_thr_init(void);

GC_bool GC_thr_initialized = FALSE;

size_t GC_min_stack_sz;


/*
 * stack_head is stored at the top of free stacks
 */
struct stack_head {
	struct stack_head	*next;
	ptr_t			base;
	thread_t		owner;
};

# define N_FREE_LISTS 25
struct stack_head *GC_stack_free_lists[N_FREE_LISTS] = { 0 };
		/* GC_stack_free_lists[i] is free list for stacks of 	*/
		/* size GC_min_stack_sz*2**i.				*/
		/* Free lists are linked through stack_head stored	*/			/* at top of stack.					*/

/* Return a stack of size at least *stack_size.  *stack_size is	*/
/* replaced by the actual stack size.				*/
/* Caller holds allocation lock.				*/
ptr_t GC_stack_alloc(size_t * stack_size)
{
    register size_t requested_sz = *stack_size;
    register size_t search_sz = GC_min_stack_sz;
    register int index = 0;	/* = log2(search_sz/GC_min_stack_sz) */
    register ptr_t base;
    register struct stack_head *result;
    
    while (search_sz < requested_sz) {
        search_sz *= 2;
        index++;
    }
    if ((result = GC_stack_free_lists[index]) == 0
        && (result = GC_stack_free_lists[index+1]) != 0) {
        /* Try next size up. */
        search_sz *= 2; index++;
    }
    if (result != 0) {
        base =  GC_stack_free_lists[index]->base;
        GC_stack_free_lists[index] = GC_stack_free_lists[index]->next;
    } else {
#ifdef MMAP_STACKS
        base = (ptr_t)mmap(0, search_sz + GC_page_size,
			     PROT_READ|PROT_WRITE, MAP_PRIVATE |MAP_NORESERVE,
			     GC_zfd, 0);
	if (base == (ptr_t)-1)
	{
		*stack_size = 0;
		return NULL;
	}

	mprotect(base, GC_page_size, PROT_NONE);
	/* Should this use divHBLKSZ(search_sz + GC_page_size) ? -- cf */
	GC_is_fresh((struct hblk *)base, divHBLKSZ(search_sz));
	base += GC_page_size;

#else
        base = (ptr_t) GC_scratch_alloc(search_sz + 2*GC_page_size);
	if (base == NULL)
	{
		*stack_size = 0;
		return NULL;
	}

        base = (ptr_t)(((word)base + GC_page_size) & ~(GC_page_size - 1));
        /* Protect hottest page to detect overflow. */
#	ifdef SOLARIS23_MPROTECT_BUG_FIXED
            mprotect(base, GC_page_size, PROT_NONE);
#	endif
        GC_is_fresh((struct hblk *)base, divHBLKSZ(search_sz));

        base += GC_page_size;
#endif
    }
    *stack_size = search_sz;
    return(base);
}

/* Caller holds  allocationlock.					*/
void GC_stack_free(ptr_t stack, size_t size)
{
    register int index = 0;
    register size_t search_sz = GC_min_stack_sz;
    register struct stack_head *head;
    
#ifdef MMAP_STACKS
    /* Zero pointers */
    mmap(stack, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_NORESERVE|MAP_FIXED,
	 GC_zfd, 0);
#endif
    while (search_sz < size) {
        search_sz *= 2;
        index++;
    }
    if (search_sz != size) ABORT("Bad stack size");

    head = (struct stack_head *)(stack + search_sz - sizeof(struct stack_head));
    head->next = GC_stack_free_lists[index];
    head->base = stack;
    GC_stack_free_lists[index] = head;
}

void GC_my_stack_limits();

/* Notify virtual dirty bit implementation that known empty parts of	*/
/* stacks do not contain useful data.					*/ 
/* Caller holds allocation lock.					*/
void GC_old_stacks_are_fresh()
{
/* No point in doing this for MMAP stacks - and pointers are zero'd out */
/* by the mmap in GC_stack_free */
#ifndef MMAP_STACKS
    register int i;
    register struct stack_head *s;
    register ptr_t p;
    register size_t sz;
    register struct hblk * h;
    int dummy;
    
    for (i = 0, sz= GC_min_stack_sz; i < N_FREE_LISTS;
         i++, sz *= 2) {
         for (s = GC_stack_free_lists[i]; s != 0; s = s->next) {
             p = s->base;
             h = (struct hblk *)(((word)p + HBLKSIZE-1) & ~(HBLKSIZE-1));
             if ((ptr_t)h == p) {
                 GC_is_fresh((struct hblk *)p, divHBLKSZ(sz));
             } else {
                 GC_is_fresh((struct hblk *)p, divHBLKSZ(sz) - 1);
                 BZERO(p, (ptr_t)h - p);
             }
         }
    }
#endif /* MMAP_STACKS */
    GC_my_stack_limits();
}

/* The set of all known threads.  We intercept thread creation and 	*/
/* joins.  We never actually create detached threads.  We allocate all 	*/
/* new thread stacks ourselves.  These allow us to maintain this	*/
/* data structure.							*/

# define THREAD_TABLE_SZ 128	/* Must be power of 2	*/
volatile GC_thread GC_threads[THREAD_TABLE_SZ];

void GC_push_thread_structures GC_PROTO((void))
{
    GC_push_all((ptr_t)(GC_threads), (ptr_t)(GC_threads)+sizeof(GC_threads));
}

/* Add a thread to GC_threads.  We assume it wasn't already there.	*/
/* Caller holds allocation lock.					*/
GC_thread GC_new_thread(thread_t id)
{
    int hv = ((word)id) % THREAD_TABLE_SZ;
    GC_thread result;
    static struct GC_Thread_Rep first_thread;
    static GC_bool first_thread_used = FALSE;
    
    if (!first_thread_used) {
    	result = &first_thread;
    	first_thread_used = TRUE;
    	/* Dont acquire allocation lock, since we may already hold it. */
    } else {
        result = (struct GC_Thread_Rep *)
        	 GC_INTERNAL_MALLOC(sizeof(struct GC_Thread_Rep), NORMAL);
    }
    if (result == 0) return(0);
    result -> id = id;
    result -> next = GC_threads[hv];
    GC_threads[hv] = result;
    /* result -> finished = 0; */
    (void) cond_init(&(result->join_cv), USYNC_THREAD, 0);
    return(result);
}

/* Delete a thread from GC_threads.  We assume it is there.	*/
/* (The code intentionally traps if it wasn't.)			*/
/* Caller holds allocation lock.				*/
void GC_delete_thread(thread_t id)
{
    int hv = ((word)id) % THREAD_TABLE_SZ;
    register GC_thread p = GC_threads[hv];
    register GC_thread prev = 0;
    
    while (p -> id != id) {
        prev = p;
        p = p -> next;
    }
    if (prev == 0) {
        GC_threads[hv] = p -> next;
    } else {
        prev -> next = p -> next;
    }
}

/* Return the GC_thread correpsonding to a given thread_t.	*/
/* Returns 0 if it's not there.					*/
/* Caller holds  allocation lock.				*/
GC_thread GC_lookup_thread(thread_t id)
{
    int hv = ((word)id) % THREAD_TABLE_SZ;
    register GC_thread p = GC_threads[hv];
    
    while (p != 0 && p -> id != id) p = p -> next;
    return(p);
}

/* Solaris 2/Intel uses an initial stack size limit slightly bigger than the
   SPARC default of 8 MB.  Account for this to warn only if the user has
   raised the limit beyond the default.

   This is identical to DFLSSIZ defined in <sys/vm_machparam.h>.  This file
   is installed in /usr/platform/`uname -m`/include, which is not in the
   default include directory list, so copy the definition here.  */
#ifdef I386
# define MAX_ORIG_STACK_SIZE (8 * 1024 * 1024 + ((USRSTACK) & 0x3FFFFF))
#else
# define MAX_ORIG_STACK_SIZE (8 * 1024 * 1024)
#endif

word GC_get_orig_stack_size() {
    struct rlimit rl;
    static int warned = 0;
    int result;

    if (getrlimit(RLIMIT_STACK, &rl) != 0) ABORT("getrlimit failed");
    result = (word)rl.rlim_cur & ~(HBLKSIZE-1);
    if (result > MAX_ORIG_STACK_SIZE) {
	if (!warned) {
	    WARN("Large stack limit(%ld): only scanning 8 MB\n", result);
	    warned = 1;
	}
	result = MAX_ORIG_STACK_SIZE;
    }
    return result;
}

/* Notify dirty bit implementation of unused parts of my stack. */
/* Caller holds allocation lock.				*/
void GC_my_stack_limits()
{
    int dummy;
    register ptr_t hottest = (ptr_t)((word)(&dummy) & ~(HBLKSIZE-1));
    register GC_thread me = GC_lookup_thread(thr_self());
    register size_t stack_size = me -> stack_size;
    register ptr_t stack;
    
    if (stack_size == 0) {
      /* original thread */
        /* Empirically, what should be the stack page with lowest	*/
        /* address is actually inaccessible.				*/
        stack_size = GC_get_orig_stack_size() - GC_page_size;
        stack = GC_stackbottom - stack_size + GC_page_size;
    } else {
        stack = me -> stack;
    }
    if (stack > hottest || stack + stack_size < hottest) {
    	ABORT("sp out of bounds");
    }
    GC_is_fresh((struct hblk *)stack, divHBLKSZ(hottest - stack));
}


/* We hold allocation lock.  Should do exactly the right thing if the	*/
/* world is stopped.  Should not fail if it isn't.			*/
void GC_push_all_stacks()
{
    register int i;
    register GC_thread p;
    register ptr_t sp = GC_approx_sp();
    register ptr_t bottom, top;
    struct rlimit rl;
    
#   define PUSH(bottom,top) \
      if (GC_dirty_maintained) { \
	GC_push_selected((bottom), (top), GC_page_was_ever_dirty, \
		      GC_push_all_stack); \
      } else { \
        GC_push_all_stack((bottom), (top)); \
      }
    GC_push_all_stack((ptr_t)GC_lwp_registers,
		      (ptr_t)GC_lwp_registers
		      + max_lwps * sizeof(GC_lwp_registers[0]));
    for (i = 0; i < THREAD_TABLE_SZ; i++) {
      for (p = GC_threads[i]; p != 0; p = p -> next) {
        if (p -> stack_size != 0) {
            bottom = p -> stack;
            top = p -> stack + p -> stack_size;
        } else {
            /* The original stack. */
            bottom = GC_stackbottom - GC_get_orig_stack_size() + GC_page_size;
            top = GC_stackbottom;
        }
        if ((word)sp > (word)bottom && (word)sp < (word)top) bottom = sp;
        PUSH(bottom, top);
      }
    }
}


int GC_is_thread_stack(ptr_t addr)
{
    register int i;
    register GC_thread p;
    register ptr_t bottom, top;
    
    for (i = 0; i < THREAD_TABLE_SZ; i++) {
      for (p = GC_threads[i]; p != 0; p = p -> next) {
        if (p -> stack_size != 0) {
            if (p -> stack <= addr &&
		addr < p -> stack + p -> stack_size)
		    return 1;
	}
      }
    }
    return 0;
}

/* The only thread that ever really performs a thr_join.	*/
void * GC_thr_daemon(void * dummy)
{
    void *status;
    thread_t departed;
    register GC_thread t;
    register int i;
    register int result;
    
    for(;;) {
      start:
        result = thr_join((thread_t)0, &departed, &status);
    	LOCK();
    	if (result != 0) {
    	    /* No more threads; wait for create. */
    	    for (i = 0; i < THREAD_TABLE_SZ; i++) {
    	        for (t = GC_threads[i]; t != 0; t = t -> next) {
                    if (!(t -> flags & (DETACHED | FINISHED))) {
                      UNLOCK();
                      goto start; /* Thread started just before we */
                      		  /* acquired the lock.		   */
                    }
                }
            }
            cond_wait(&GC_create_cv, &GC_allocate_ml);
            UNLOCK();
    	} else {
    	    t = GC_lookup_thread(departed);
	    GC_multithreaded--;
    	    if (!(t -> flags & CLIENT_OWNS_STACK)) {
    	    	GC_stack_free(t -> stack, t -> stack_size);
    	    }
    	    if (t -> flags & DETACHED) {
    	    	GC_delete_thread(departed);
    	    } else {
    	        t -> status = status;
    	    	t -> flags |= FINISHED;
    	    	cond_signal(&(t -> join_cv));
    	    	cond_broadcast(&GC_prom_join_cv);
    	    }
    	    UNLOCK();
    	}
    }
}

/* We hold the allocation lock, or caller ensures that 2 instances	*/
/* cannot be invoked concurrently.					*/
void GC_thr_init(void)
{
    GC_thread t;
    thread_t tid;
    int ret;

    if (GC_thr_initialized)
	    return;
    GC_thr_initialized = TRUE;
    GC_min_stack_sz = ((thr_min_stack() + 32*1024 + HBLKSIZE-1)
    		       & ~(HBLKSIZE - 1));
#ifdef MMAP_STACKS
    GC_zfd = open("/dev/zero", O_RDONLY);
    if (GC_zfd == -1)
	    ABORT("Can't open /dev/zero");
#endif /* MMAP_STACKS */
    cond_init(&GC_prom_join_cv, USYNC_THREAD, 0);
    cond_init(&GC_create_cv, USYNC_THREAD, 0);
    /* Add the initial thread, so we can stop it.	*/
      t = GC_new_thread(thr_self());
      t -> stack_size = 0;
      t -> flags = DETACHED | CLIENT_OWNS_STACK;
    ret = thr_create(0 /* stack */, 0 /* stack_size */, GC_thr_daemon,
    		     0 /* arg */, THR_DETACHED | THR_DAEMON,
    		     &tid /* thread_id */);
    if (ret != 0) {
	GC_err_printf1("Thr_create returned %ld\n", ret);
    	ABORT("Cant fork daemon");
    }
    thr_setprio(tid, 126);
}

/* We acquire the allocation lock to prevent races with 	*/
/* stopping/starting world.					*/
/* This is no more correct than the underlying Solaris 2.X	*/
/* implementation.  Under 2.3 THIS IS BROKEN.			*/
int GC_thr_suspend(thread_t target_thread)
{
    GC_thread t;
    int result;
    
    LOCK();
    result = thr_suspend(target_thread);
    if (result == 0) {
    	t = GC_lookup_thread(target_thread);
    	if (t == 0) ABORT("thread unknown to GC");
        t -> flags |= SUSPNDED;
    }
    UNLOCK();
    return(result);
}

int GC_thr_continue(thread_t target_thread)
{
    GC_thread t;
    int result;
    
    LOCK();
    result = thr_continue(target_thread);
    if (result == 0) {
    	t = GC_lookup_thread(target_thread);
    	if (t == 0) ABORT("thread unknown to GC");
        t -> flags &= ~SUSPNDED;
    }
    UNLOCK();
    return(result);
}

int GC_thr_join(thread_t wait_for, thread_t *departed, void **status)
{
    register GC_thread t;
    int result = 0;
    
    LOCK();
    if (wait_for == 0) {
        register int i;
        register GC_bool thread_exists;
    
    	for (;;) {
    	  thread_exists = FALSE;
    	  for (i = 0; i < THREAD_TABLE_SZ; i++) {
    	    for (t = GC_threads[i]; t != 0; t = t -> next) {
              if (!(t -> flags & DETACHED)) {
                if (t -> flags & FINISHED) {
                  goto found;
                }
                thread_exists = TRUE;
              }
            }
          }
          if (!thread_exists) {
              result = ESRCH;
    	      goto out;
          }
          cond_wait(&GC_prom_join_cv, &GC_allocate_ml);
        }
    } else {
        t = GC_lookup_thread(wait_for);
    	if (t == 0 || t -> flags & DETACHED) {
    	    result = ESRCH;
    	    goto out;
    	}
    	if (wait_for == thr_self()) {
    	    result = EDEADLK;
    	    goto out;
    	}
    	while (!(t -> flags & FINISHED)) {
            cond_wait(&(t -> join_cv), &GC_allocate_ml);
    	}
    	
    }
  found:
    if (status) *status = t -> status;
    if (departed) *departed = t -> id;
    cond_destroy(&(t -> join_cv));
    GC_delete_thread(t -> id);
  out:
    UNLOCK();
    return(result);
}


int
GC_thr_create(void *stack_base, size_t stack_size,
              void *(*start_routine)(void *), void *arg, long flags,
              thread_t *new_thread)
{
    int result;
    GC_thread t;
    thread_t my_new_thread;
    word my_flags = 0;
    void * stack = stack_base;
   
    LOCK();
    if (!GC_is_initialized) GC_init_inner();
    GC_multithreaded++;
    if (stack == 0) {
     	if (stack_size == 0) stack_size = 1024*1024;
     	stack = (void *)GC_stack_alloc(&stack_size);
     	if (stack == 0) {
	    GC_multithreaded--;
     	    UNLOCK();
     	    return(ENOMEM);
     	}
    } else {
    	my_flags |= CLIENT_OWNS_STACK;
    }
    if (flags & THR_DETACHED) my_flags |= DETACHED;
    if (flags & THR_SUSPENDED) my_flags |= SUSPNDED;
    result = thr_create(stack, stack_size, start_routine,
   		        arg, flags & ~THR_DETACHED, &my_new_thread);
    if (result == 0) {
        t = GC_new_thread(my_new_thread);
        t -> flags = my_flags;
        if (!(my_flags & DETACHED)) cond_init(&(t -> join_cv), USYNC_THREAD, 0);
        t -> stack = stack;
        t -> stack_size = stack_size;
        if (new_thread != 0) *new_thread = my_new_thread;
        cond_signal(&GC_create_cv);
    } else {
	GC_multithreaded--;
        if (!(my_flags & CLIENT_OWNS_STACK)) {
      	    GC_stack_free(stack, stack_size);
	}
    }        
    UNLOCK();  
    return(result);
}

# else /* !GC_SOLARIS_THREADS */

#ifndef LINT
  int GC_no_sunOS_threads;
#endif
#endif
