/* 
 * 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.
 * Modified by Peter C. for Solaris Posix Threads.
 */

# include "private/gc_priv.h"

# if defined(GC_SOLARIS_PTHREADS)
# include <pthread.h>
# include <thread.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>
# include "private/solaris_threads.h"
# include <stdio.h>

#undef pthread_join
#undef pthread_create

pthread_cond_t GC_prom_join_cv;		/* Broadcast when any thread terminates	*/
pthread_cond_t GC_create_cv;		/* Signalled when a new undetached	*/
				/* thread starts.			*/
				
extern GC_bool GC_multithreaded;

/* 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.						*/



int GC_pthread_join(pthread_t wait_for, void **status)
{
	return GC_thr_join((thread_t)wait_for, NULL, status);
}


int
GC_pthread_create(pthread_t *new_thread,
          const pthread_attr_t *attr_in,
          void * (*thread_execp)(void *), void *arg)
{
    int result;
    GC_thread t;
    pthread_t my_new_thread;
    pthread_attr_t  attr;
    word my_flags = 0;
    int  flag;
    void * stack = 0;
    size_t stack_size = 0;
    int    n;
    struct sched_param schedparam;
   
    (void)pthread_attr_init(&attr);
    if (attr_in != 0) {
	(void)pthread_attr_getstacksize(attr_in, &stack_size);
	(void)pthread_attr_getstackaddr(attr_in, &stack);
    }

    LOCK();
    if (!GC_is_initialized) {
	    GC_init_inner();
    }
    GC_multithreaded++;
	    
    if (stack == 0) {
     	if (stack_size == 0)
		stack_size = 1048576;
			  /* ^-- 1 MB (this was GC_min_stack_sz, but that
			   * violates the pthread_create documentation which
			   * says the default value if none is supplied is
			   * 1MB) */
	else
		stack_size += thr_min_stack();

     	stack = (void *)GC_stack_alloc(&stack_size);
     	if (stack == 0) {
	    GC_multithreaded--;
     	    UNLOCK();
	    errno = ENOMEM;
     	    return -1;
     	}
    } else {
    	my_flags |= CLIENT_OWNS_STACK;
    }
    (void)pthread_attr_setstacksize(&attr, stack_size);
    (void)pthread_attr_setstackaddr(&attr, stack);
    if (attr_in != 0) {
	(void)pthread_attr_getscope(attr_in, &n);
	(void)pthread_attr_setscope(&attr, n);
	(void)pthread_attr_getschedparam(attr_in, &schedparam);
	(void)pthread_attr_setschedparam(&attr, &schedparam);
	(void)pthread_attr_getschedpolicy(attr_in, &n);
	(void)pthread_attr_setschedpolicy(&attr, n);
	(void)pthread_attr_getinheritsched(attr_in, &n);
	(void)pthread_attr_setinheritsched(&attr, n);

	(void)pthread_attr_getdetachstate(attr_in, &flag);
	if (flag == PTHREAD_CREATE_DETACHED) {
		my_flags |= DETACHED;
	}
	(void)pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    }
    /*
     * thr_create can call malloc(), which if redirected will
     * attempt to acquire the allocation lock.
     * Unlock here to prevent deadlock.
     */


#if 0
#ifdef I386
    UNLOCK();
#endif
#endif
    result = 
	    pthread_create(&my_new_thread, &attr, thread_execp, arg);
#if 0
#ifdef I386
    LOCK();
#endif
#endif
    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;
        pthread_cond_signal(&GC_create_cv);
    } else {
	    if (!(my_flags & CLIENT_OWNS_STACK)) {
		    GC_stack_free(stack, stack_size);
	    }        
	    GC_multithreaded--;
    }
    UNLOCK();
    pthread_attr_destroy(&attr);
    return(result);
}

# else

#ifndef LINT
  int GC_no_sunOS_pthreads;
#endif

# endif /* GC_SOLARIS_PTHREADS */

