/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the Netscape Portable Runtime (NSPR).
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998-2000
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include "primpl.h"

#include <signal.h>

#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/syssgi.h>
#include <sys/time.h>
#include <sys/immu.h>
#include <sys/utsname.h>
#include <sys/sysmp.h>
#include <sys/pda.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/procfs.h>
#include <task.h>
#include <dlfcn.h>

static void _MD_IrixIntervalInit(void);

#if defined(_PR_PTHREADS)
/*
 * for compatibility with classic nspr
 */
void _PR_IRIX_CHILD_PROCESS()
{
}
#else  /* defined(_PR_PTHREADS) */

static void irix_detach_sproc(void);
char *_nspr_sproc_private;    /* ptr. to private region in every sproc */

extern PRUintn    _pr_numCPU;

typedef struct nspr_arena {
	PRCList links;
	usptr_t *usarena;
} nspr_arena;

#define ARENA_PTR(qp) \
	((nspr_arena *) ((char*) (qp) - offsetof(nspr_arena , links)))

static usptr_t *alloc_new_arena(void);

PRCList arena_list = PR_INIT_STATIC_CLIST(&arena_list);
ulock_t arena_list_lock;
nspr_arena first_arena;
int	_nspr_irix_arena_cnt = 1;

PRCList sproc_list = PR_INIT_STATIC_CLIST(&sproc_list);
ulock_t sproc_list_lock;

typedef struct sproc_data {
	void (*entry) (void *, size_t);
	unsigned inh;
	void *arg;
	caddr_t sp;
	size_t len;
	int *pid;
	int creator_pid;
} sproc_data;

typedef struct sproc_params {
	PRCList links;
	sproc_data sd;
} sproc_params;

#define SPROC_PARAMS_PTR(qp) \
	((sproc_params *) ((char*) (qp) - offsetof(sproc_params , links)))

long	_nspr_irix_lock_cnt = 0;
long	_nspr_irix_sem_cnt = 0;
long	_nspr_irix_pollsem_cnt = 0;

usptr_t *_pr_usArena;
ulock_t _pr_heapLock;

usema_t *_pr_irix_exit_sem;
PRInt32 _pr_irix_exit_now = 0;
PRInt32 _pr_irix_process_exit_code = 0;	/* exit code for PR_ProcessExit */
PRInt32 _pr_irix_process_exit = 0; /* process exiting due to call to
										   PR_ProcessExit */

int _pr_irix_primoridal_cpu_fd[2] = { -1, -1 };
static void (*libc_exit)(int) = NULL;
static void *libc_handle = NULL;

#define _NSPR_DEF_INITUSERS		100	/* default value of CONF_INITUSERS */
#define _NSPR_DEF_INITSIZE		(4 * 1024 * 1024)	/* 4 MB */

int _irix_initusers = _NSPR_DEF_INITUSERS;
int _irix_initsize = _NSPR_DEF_INITSIZE;

PRIntn _pr_io_in_progress, _pr_clock_in_progress;

PRInt32 _pr_md_irix_sprocs_created, _pr_md_irix_sprocs_failed;
PRInt32 _pr_md_irix_sprocs = 1;
PRCList _pr_md_irix_sproc_list =
PR_INIT_STATIC_CLIST(&_pr_md_irix_sproc_list);

sigset_t ints_off;
extern sigset_t timer_set;

#if !defined(PR_SETABORTSIG)
#define PR_SETABORTSIG 18
#endif
/*
 * terminate the entire application if any sproc exits abnormally
 */
PRBool _nspr_terminate_on_error = PR_TRUE;

/*
 * exported interface to set the shared arena parameters
 */
void _PR_Irix_Set_Arena_Params(PRInt32 initusers, PRInt32 initsize)
{
    _irix_initusers = initusers;
    _irix_initsize = initsize;
}

static usptr_t *alloc_new_arena()
{
    return(usinit("/dev/zero"));
}

static PRStatus new_poll_sem(struct _MDThread *mdthr, int val)
{
PRIntn _is;
PRStatus rv = PR_SUCCESS;
usema_t *sem = NULL;
PRCList *qp;
nspr_arena *arena;
usptr_t *irix_arena;
PRThread *me = _MD_GET_ATTACHED_THREAD();	

	if (me && !_PR_IS_NATIVE_THREAD(me))
		_PR_INTSOFF(_is); 
	_PR_LOCK(arena_list_lock);
	for (qp = arena_list.next; qp != &arena_list; qp = qp->next) {
		arena = ARENA_PTR(qp);
		sem = usnewpollsema(arena->usarena, val);
		if (sem != NULL) {
			mdthr->cvar_pollsem = sem;
			mdthr->pollsem_arena = arena->usarena;
			break;
		}
	}
	if (sem == NULL) {
		/*
		 * If no space left in the arena allocate a new one.
		 */
		if (errno == ENOMEM) {
			arena = PR_NEWZAP(nspr_arena);
			if (arena != NULL) {
				irix_arena = alloc_new_arena();
				if (irix_arena) {
					PR_APPEND_LINK(&arena->links, &arena_list);
					_nspr_irix_arena_cnt++;
					arena->usarena = irix_arena;
					sem = usnewpollsema(arena->usarena, val);
					if (sem != NULL) {
						mdthr->cvar_pollsem = sem;
						mdthr->pollsem_arena = arena->usarena;
					} else
						rv = PR_FAILURE;
				} else {
					PR_DELETE(arena);
					rv = PR_FAILURE;
				}

			} else
				rv = PR_FAILURE;
		} else
			rv = PR_FAILURE;
	}
	_PR_UNLOCK(arena_list_lock);
	if (me && !_PR_IS_NATIVE_THREAD(me))
		_PR_FAST_INTSON(_is);
	if (rv == PR_SUCCESS)
		_MD_ATOMIC_INCREMENT(&_nspr_irix_pollsem_cnt);
	return rv;
}

static void free_poll_sem(struct _MDThread *mdthr)
{
PRIntn _is;
PRThread *me = _MD_GET_ATTACHED_THREAD();	

	if (me && !_PR_IS_NATIVE_THREAD(me))
		_PR_INTSOFF(_is); 
	usfreepollsema(mdthr->cvar_pollsem, mdthr->pollsem_arena);
	if (me && !_PR_IS_NATIVE_THREAD(me))
		_PR_FAST_INTSON(_is);
	_MD_ATOMIC_DECREMENT(&_nspr_irix_pollsem_cnt);
}

static PRStatus new_lock(struct _MDLock *lockp)
{
PRIntn _is;
PRStatus rv = PR_SUCCESS;
ulock_t lock = NULL;
PRCList *qp;
nspr_arena *arena;
usptr_t *irix_arena;
PRThread *me = _MD_GET_ATTACHED_THREAD();	

	if (me && !_PR_IS_NATIVE_THREAD(me))
		_PR_INTSOFF(_is); 
	_PR_LOCK(arena_list_lock);
	for (qp = arena_list.next; qp != &arena_list; qp = qp->next) {
		arena = ARENA_PTR(qp);
		lock = usnewlock(arena->usarena);
		if (lock != NULL) {
			lockp->lock = lock;
			lockp->arena = arena->usarena;
			break;
		}
	}
	if (lock == NULL) {
		/*
		 * If no space left in the arena allocate a new one.
		 */
		if (errno == ENOMEM) {
			arena = PR_NEWZAP(nspr_arena);
			if (arena != NULL) {
				irix_arena = alloc_new_arena();
				if (irix_arena) {
					PR_APPEND_LINK(&arena->links, &arena_list);
					_nspr_irix_arena_cnt++;
					arena->usarena = irix_arena;
					lock = usnewlock(irix_arena);
					if (lock != NULL) {
						lockp->lock = lock;
						lockp->arena = arena->usarena;
					} else
						rv = PR_FAILURE;
				} else {
					PR_DELETE(arena);
					rv = PR_FAILURE;
				}

			} else
				rv = PR_FAILURE;
		} else
			rv = PR_FAILURE;
	}
	_PR_UNLOCK(arena_list_lock);
	if (me && !_PR_IS_NATIVE_THREAD(me))
		_PR_FAST_INTSON(_is);
	if (rv == PR_SUCCESS)
		_MD_ATOMIC_INCREMENT(&_nspr_irix_lock_cnt);
	return rv;
}

static void free_lock(struct _MDLock *lockp)
{
PRIntn _is;
PRThread *me = _MD_GET_ATTACHED_THREAD();	

	if (me && !_PR_IS_NATIVE_THREAD(me))
		_PR_INTSOFF(_is); 
	usfreelock(lockp->lock, lockp->arena);
	if (me && !_PR_IS_NATIVE_THREAD(me))
		_PR_FAST_INTSON(_is);
	_MD_ATOMIC_DECREMENT(&_nspr_irix_lock_cnt);
}

void _MD_FREE_LOCK(struct _MDLock *lockp)
{
	PRIntn _is;
	PRThread *me = _MD_GET_ATTACHED_THREAD();	

	if (me && !_PR_IS_NATIVE_THREAD(me))
		_PR_INTSOFF(_is); 
	free_lock(lockp);
	if (me && !_PR_IS_NATIVE_THREAD(me))
		_PR_FAST_INTSON(_is);
}

/*
 * _MD_get_attached_thread
 *		Return the thread pointer of the current thread if it is attached.
 *
 *		This function is needed for Irix because the thread-local-storage is
 *		implemented by mmapin'g a page with the MAP_LOCAL flag. This causes the
 *		sproc-private page to inherit contents of the page of the caller of sproc().
 */
PRThread *_MD_get_attached_thread(void)
{

	if (_MD_GET_SPROC_PID() == get_pid())
		return _MD_THIS_THREAD();
	else
		return 0;
}

/*
 * _MD_get_current_thread
 *		Return the thread pointer of the current thread (attaching it if
 *		necessary)
 */
PRThread *_MD_get_current_thread(void)
{
PRThread *me;

	me = _MD_GET_ATTACHED_THREAD();
    if (NULL == me) {
        me = _PRI_AttachThread(
            PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0);
    }
    PR_ASSERT(me != NULL);
	return(me);
}

/*
 * irix_detach_sproc
 *		auto-detach a sproc when it exits
 */
void irix_detach_sproc(void)
{
PRThread *me;

	me = _MD_GET_ATTACHED_THREAD();
	if ((me != NULL) && (me->flags & _PR_ATTACHED)) {
		_PRI_DetachThread();
	}
}


PRStatus _MD_NEW_LOCK(struct _MDLock *lockp)
{
    PRStatus rv;
    PRIntn is;
    PRThread *me = _MD_GET_ATTACHED_THREAD();	

	if (me && !_PR_IS_NATIVE_THREAD(me))
		_PR_INTSOFF(is);
	rv = new_lock(lockp);
	if (me && !_PR_IS_NATIVE_THREAD(me))
		_PR_FAST_INTSON(is);
	return rv;
}

static void
sigchld_handler(int sig)
{
    pid_t pid;
    int status;

    /*
     * If an sproc exited abnormally send a SIGKILL signal to all the
     * sprocs in the process to terminate the application
     */
    while ((pid = waitpid(0, &status, WNOHANG)) > 0) {
        if (WIFSIGNALED(status) && ((WTERMSIG(status) == SIGSEGV) ||
            (WTERMSIG(status) == SIGBUS) ||
            (WTERMSIG(status) == SIGABRT) ||
            (WTERMSIG(status) == SIGILL))) {

				prctl(PR_SETEXITSIG, SIGKILL);
				_exit(status);
			}
    }
}

static void save_context_and_block(int sig)
{
PRThread *me = _PR_MD_CURRENT_THREAD();
_PRCPU *cpu = _PR_MD_CURRENT_CPU();

	/*
	 * save context
	 */
	(void) setjmp(me->md.jb);
	/*
	 * unblock the suspending thread
	 */
	if (me->cpu) {
		/*
		 * I am a cpu thread, not a user-created GLOBAL thread
		 */
		unblockproc(cpu->md.suspending_id);	
	} else {
		unblockproc(me->md.suspending_id);	
	}
	/*
	 * now, block current thread
	 */
	blockproc(getpid());
}

/*
** The irix kernel has a bug in it which causes async connect's which are
** interrupted by a signal to fail terribly (EADDRINUSE is returned). 
** We work around the bug by blocking signals during the async connect
** attempt.
*/
PRInt32 _MD_irix_connect(
    PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen, PRIntervalTime timeout)
{
    PRInt32 rv;
    sigset_t oldset;

    sigprocmask(SIG_BLOCK, &ints_off, &oldset);
    rv = connect(osfd, addr, addrlen);
    sigprocmask(SIG_SETMASK, &oldset, 0);

    return(rv);
}

#include "prprf.h"

/********************************************************************/
/********************************************************************/
/*************** Various thread like things for IRIX ****************/
/********************************************************************/
/********************************************************************/

void *_MD_GetSP(PRThread *t)
{
    PRThread *me = _PR_MD_CURRENT_THREAD();
    void *sp;

    if (me == t)
        (void) setjmp(t->md.jb);

    sp = (void *)(t->md.jb[JB_SP]);
    PR_ASSERT((sp >= (void *) t->stack->stackBottom) &&
        (sp <= (void *) (t->stack->stackBottom + t->stack->stackSize)));
    return(sp);
}

void _MD_InitLocks()
{
    char buf[200];
    char *init_users, *init_size;

    PR_snprintf(buf, sizeof(buf), "/dev/zero");

    if (init_users = getenv("_NSPR_IRIX_INITUSERS"))
        _irix_initusers = atoi(init_users);

    if (init_size = getenv("_NSPR_IRIX_INITSIZE"))
        _irix_initsize = atoi(init_size);

    usconfig(CONF_INITUSERS, _irix_initusers);
    usconfig(CONF_INITSIZE, _irix_initsize);
    usconfig(CONF_AUTOGROW, 1);
    usconfig(CONF_AUTORESV, 1);
	if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0) {
		perror("PR_Init: unable to config mutex arena");
		exit(-1);
	}

    _pr_usArena = usinit(buf);
    if (!_pr_usArena) {
        fprintf(stderr,
            "PR_Init: Error - unable to create lock/monitor arena\n");
        exit(-1);
    }
    _pr_heapLock = usnewlock(_pr_usArena);
	_nspr_irix_lock_cnt++;

    arena_list_lock = usnewlock(_pr_usArena);
	_nspr_irix_lock_cnt++;

    sproc_list_lock = usnewlock(_pr_usArena);
	_nspr_irix_lock_cnt++;

	_pr_irix_exit_sem = usnewsema(_pr_usArena, 0);
	_nspr_irix_sem_cnt = 1;

	first_arena.usarena = _pr_usArena;
	PR_INIT_CLIST(&first_arena.links);
	PR_APPEND_LINK(&first_arena.links, &arena_list);
}

/* _PR_IRIX_CHILD_PROCESS is a private API for Server group */
void _PR_IRIX_CHILD_PROCESS()
{
extern PRUint32 _pr_global_threads;

    PR_ASSERT(_PR_MD_CURRENT_CPU() == _pr_primordialCPU);
    PR_ASSERT(_pr_numCPU == 1);
    PR_ASSERT(_pr_global_threads == 0);
    /*
     * save the new pid
     */
    _pr_primordialCPU->md.id = getpid();
	_MD_SET_SPROC_PID(getpid());	
}

static PRStatus pr_cvar_wait_sem(PRThread *thread, PRIntervalTime timeout)
{
    int rv;

#ifdef _PR_USE_POLL
	struct pollfd pfd;
	int msecs;

	if (timeout == PR_INTERVAL_NO_TIMEOUT)
		msecs = -1;
	else
		msecs  = PR_IntervalToMilliseconds(timeout);
#else
    struct timeval tv, *tvp;
    fd_set rd;

	if(timeout == PR_INTERVAL_NO_TIMEOUT)
		tvp = NULL;
	else {
		tv.tv_sec = PR_IntervalToSeconds(timeout);
		tv.tv_usec = PR_IntervalToMicroseconds(
		timeout - PR_SecondsToInterval(tv.tv_sec));
		tvp = &tv;
	}
	FD_ZERO(&rd);
	FD_SET(thread->md.cvar_pollsemfd, &rd);
#endif

    /*
     * call uspsema only if a previous select call on this semaphore
     * did not timeout
     */
    if (!thread->md.cvar_pollsem_select) {
        rv = _PR_WAIT_SEM(thread->md.cvar_pollsem);
		PR_ASSERT(rv >= 0);
	} else
        rv = 0;
again:
    if(!rv) {
#ifdef _PR_USE_POLL
		pfd.events = POLLIN;
		pfd.fd = thread->md.cvar_pollsemfd;
		rv = _MD_POLL(&pfd, 1, msecs);
#else
		rv = _MD_SELECT(thread->md.cvar_pollsemfd + 1, &rd, NULL,NULL,tvp);
#endif
        if ((rv == -1) && (errno == EINTR)) {
			rv = 0;
			goto again;
		}
		PR_ASSERT(rv >= 0);
	}

    if (rv > 0) {
        /*
         * acquired the semaphore, call uspsema next time
         */
        thread->md.cvar_pollsem_select = 0;
        return PR_SUCCESS;
    } else {
        /*
         * select timed out; must call select, not uspsema, when trying
         * to acquire the semaphore the next time
         */
        thread->md.cvar_pollsem_select = 1;
        return PR_FAILURE;
    }
}

PRStatus _MD_wait(PRThread *thread, PRIntervalTime ticks)
{
    if ( thread->flags & _PR_GLOBAL_SCOPE ) {
	_MD_CHECK_FOR_EXIT();
        if (pr_cvar_wait_sem(thread, ticks) == PR_FAILURE) {
	    _MD_CHECK_FOR_EXIT();
            /*
             * wait timed out
             */
            _PR_THREAD_LOCK(thread);
            if (thread->wait.cvar) {
                /*
                 * The thread will remove itself from the waitQ
                 * of the cvar in _PR_WaitCondVar
                 */
                thread->wait.cvar = NULL;
                thread->state =  _PR_RUNNING;
                _PR_THREAD_UNLOCK(thread);
            }  else {
                _PR_THREAD_UNLOCK(thread);
                /*
             * This thread was woken up by a notifying thread
             * at the same time as a timeout; so, consume the
             * extra post operation on the semaphore
             */
	        _MD_CHECK_FOR_EXIT();
            pr_cvar_wait_sem(thread, PR_INTERVAL_NO_TIMEOUT);
            }
	    _MD_CHECK_FOR_EXIT();
        }
    } else {
        _PR_MD_SWITCH_CONTEXT(thread);
    }
    return PR_SUCCESS;
}

PRStatus _MD_WakeupWaiter(PRThread *thread)
{
    PRThread *me = _PR_MD_CURRENT_THREAD();
    PRIntn is;

	PR_ASSERT(_pr_md_idle_cpus >= 0);
    if (thread == NULL) {
		if (_pr_md_idle_cpus)
        	_MD_Wakeup_CPUs();
    } else if (!_PR_IS_NATIVE_THREAD(thread)) {
		if (_pr_md_idle_cpus)
       		_MD_Wakeup_CPUs();
    } else {
		PR_ASSERT(_PR_IS_NATIVE_THREAD(thread));
		if (!_PR_IS_NATIVE_THREAD(me))
			_PR_INTSOFF(is);
		_MD_CVAR_POST_SEM(thread);
		if (!_PR_IS_NATIVE_THREAD(me))
			_PR_FAST_INTSON(is);
    } 
    return PR_SUCCESS;
}

void create_sproc (void (*entry) (void *, size_t), unsigned inh,
					void *arg, caddr_t sp, size_t len, int *pid)
{
sproc_params sparams;
char data;
int rv;
PRThread *me = _PR_MD_CURRENT_THREAD();

	if (!_PR_IS_NATIVE_THREAD(me) && (_PR_MD_CURRENT_CPU()->id == 0)) {
		*pid = sprocsp(entry,		/* startup func		*/
						inh,        /* attribute flags	*/
						arg,     	/* thread param		*/
						sp,         /* stack address	*/
						len);       /* stack size		*/
	} else {
		sparams.sd.entry = entry;
		sparams.sd.inh = inh;
		sparams.sd.arg = arg;
		sparams.sd.sp = sp;
		sparams.sd.len = len;
		sparams.sd.pid = pid;
		sparams.sd.creator_pid = getpid();
		_PR_LOCK(sproc_list_lock);
		PR_APPEND_LINK(&sparams.links, &sproc_list);
		rv = write(_pr_irix_primoridal_cpu_fd[1], &data, 1);
		PR_ASSERT(rv == 1);
		_PR_UNLOCK(sproc_list_lock);
		blockproc(getpid());
	}
}

/*
 * _PR_MD_WAKEUP_PRIMORDIAL_CPU
 *
 *		wakeup cpu 0
 */

void _PR_MD_WAKEUP_PRIMORDIAL_CPU()
{
char data = '0';
int rv;

	rv = write(_pr_irix_primoridal_cpu_fd[1], &data, 1);
	PR_ASSERT(rv == 1);
}

/*
 * _PR_MD_primordial_cpu
 *
 *		process events that need to executed by the primordial cpu on each
 *		iteration through the idle loop
 */

void _PR_MD_primordial_cpu()
{
PRCList *qp;
sproc_params *sp;
int pid;

	_PR_LOCK(sproc_list_lock);
	while ((qp = sproc_list.next) != &sproc_list) {
		sp = SPROC_PARAMS_PTR(qp);
		PR_REMOVE_LINK(&sp->links);
		pid = sp->sd.creator_pid;
		(*(sp->sd.pid)) = sprocsp(sp->sd.entry,		/* startup func    */
							sp->sd.inh,            	/* attribute flags     */
							sp->sd.arg,     		/* thread param     */
							sp->sd.sp,             	/* stack address    */
							sp->sd.len);         	/* stack size     */
		unblockproc(pid);
	}
	_PR_UNLOCK(sproc_list_lock);
}

PRStatus _MD_CreateThread(PRThread *thread, 
void (*start)(void *), 
PRThreadPriority priority, 
PRThreadScope scope, 
PRThreadState state, 
PRUint32 stackSize)
{
    typedef void (*SprocEntry) (void *, size_t);
    SprocEntry spentry = (SprocEntry)start;
    PRIntn is;
	PRThread *me = _PR_MD_CURRENT_THREAD();	
	PRInt32 pid;
	PRStatus rv;

	if (!_PR_IS_NATIVE_THREAD(me))
		_PR_INTSOFF(is);
    thread->md.cvar_pollsem_select = 0;
    thread->flags |= _PR_GLOBAL_SCOPE;

	thread->md.cvar_pollsemfd = -1;
	if (new_poll_sem(&thread->md,0) == PR_FAILURE) {
		if (!_PR_IS_NATIVE_THREAD(me))
			_PR_FAST_INTSON(is);
		return PR_FAILURE;
	}
	thread->md.cvar_pollsemfd =
		_PR_OPEN_POLL_SEM(thread->md.cvar_pollsem);
	if ((thread->md.cvar_pollsemfd < 0)) {
		free_poll_sem(&thread->md);
		if (!_PR_IS_NATIVE_THREAD(me))
			_PR_FAST_INTSON(is);
		return PR_FAILURE;
	}

    create_sproc(spentry,            /* startup func    */
    			PR_SALL,            /* attribute flags     */
    			(void *)thread,     /* thread param     */
    			NULL,               /* stack address    */
    			stackSize, &pid);         /* stack size     */
    if (pid > 0) {
        _MD_ATOMIC_INCREMENT(&_pr_md_irix_sprocs_created);
        _MD_ATOMIC_INCREMENT(&_pr_md_irix_sprocs);
		rv = PR_SUCCESS;
		if (!_PR_IS_NATIVE_THREAD(me))
			_PR_FAST_INTSON(is);
        return rv;
    } else {
        close(thread->md.cvar_pollsemfd);
        thread->md.cvar_pollsemfd = -1;
		free_poll_sem(&thread->md);
        thread->md.cvar_pollsem = NULL;
        _MD_ATOMIC_INCREMENT(&_pr_md_irix_sprocs_failed);
		if (!_PR_IS_NATIVE_THREAD(me))
			_PR_FAST_INTSON(is);
        return PR_FAILURE;
    }
}

void _MD_CleanThread(PRThread *thread)
{
    if (thread->flags & _PR_GLOBAL_SCOPE) {
        close(thread->md.cvar_pollsemfd);
        thread->md.cvar_pollsemfd = -1;
		free_poll_sem(&thread->md);
        thread->md.cvar_pollsem = NULL;
    }
}

void _MD_SetPriority(_MDThread *thread, PRThreadPriority newPri)
{
    return;
}

extern void _MD_unix_terminate_waitpid_daemon(void);

void
_MD_CleanupBeforeExit(void)
{
    extern PRInt32    _pr_cpus_exit;

    _MD_unix_terminate_waitpid_daemon();

	_pr_irix_exit_now = 1;
    if (_pr_numCPU > 1) {
        /*
         * Set a global flag, and wakeup all cpus which will notice the flag
         * and exit.
         */
        _pr_cpus_exit = getpid();
        _MD_Wakeup_CPUs();
        while(_pr_numCPU > 1) {
            _PR_WAIT_SEM(_pr_irix_exit_sem);
            _pr_numCPU--;
        }
    }
    /*
     * cause global threads on the recycle list to exit
     */
     _PR_DEADQ_LOCK;
     if (_PR_NUM_DEADNATIVE != 0) {
	PRThread *thread;
    	PRCList *ptr;

        ptr = _PR_DEADNATIVEQ.next;
        while( ptr != &_PR_DEADNATIVEQ ) {
        	thread = _PR_THREAD_PTR(ptr);
		_MD_CVAR_POST_SEM(thread);
                ptr = ptr->next;
        } 
     }
     _PR_DEADQ_UNLOCK;
     while(_PR_NUM_DEADNATIVE > 1) {
	_PR_WAIT_SEM(_pr_irix_exit_sem);
	_PR_DEC_DEADNATIVE;
     }
}

#ifdef _PR_HAVE_SGI_PRDA_PROCMASK
extern void __sgi_prda_procmask(int);
#endif

PRStatus
_MD_InitAttachedThread(PRThread *thread, PRBool wakeup_parent)
{
	PRStatus rv = PR_SUCCESS;

    if (thread->flags & _PR_GLOBAL_SCOPE) {
		if (new_poll_sem(&thread->md,0) == PR_FAILURE) {
			return PR_FAILURE;
		}
		thread->md.cvar_pollsemfd =
			_PR_OPEN_POLL_SEM(thread->md.cvar_pollsem);
		if ((thread->md.cvar_pollsemfd < 0)) {
			free_poll_sem(&thread->md);
			return PR_FAILURE;
		}
		if (_MD_InitThread(thread, PR_FALSE) == PR_FAILURE) {
			close(thread->md.cvar_pollsemfd);
			thread->md.cvar_pollsemfd = -1;
			free_poll_sem(&thread->md);
			thread->md.cvar_pollsem = NULL;
			return PR_FAILURE;
		}
    }
	return rv;
}

PRStatus
_MD_InitThread(PRThread *thread, PRBool wakeup_parent)
{
    struct sigaction sigact;
	PRStatus rv = PR_SUCCESS;

    if (thread->flags & _PR_GLOBAL_SCOPE) {
		thread->md.id = getpid();
        setblockproccnt(thread->md.id, 0);
		_MD_SET_SPROC_PID(getpid());	
#ifdef _PR_HAVE_SGI_PRDA_PROCMASK
		/*
		 * enable user-level processing of sigprocmask(); this is an
		 * undocumented feature available in Irix 6.2, 6.3, 6.4 and 6.5
		 */
		__sgi_prda_procmask(USER_LEVEL);
#endif
		/*
		 * set up SIGUSR1 handler; this is used to save state
		 */
		sigact.sa_handler = save_context_and_block;
		sigact.sa_flags = SA_RESTART;
		/*
		 * Must mask clock interrupts
		 */
		sigact.sa_mask = timer_set;
		sigaction(SIGUSR1, &sigact, 0);


		/*
		 * PR_SETABORTSIG is a new command implemented in a patch to
		 * Irix 6.2, 6.3 and 6.4. This causes a signal to be sent to all
		 * sprocs in the process when one of them terminates abnormally
		 *
		 */
		if (prctl(PR_SETABORTSIG, SIGKILL) < 0) {
			/*
			 *  if (errno == EINVAL)
			 *
			 *	PR_SETABORTSIG not supported under this OS.
			 *	You may want to get a recent kernel rollup patch that
			 *	supports this feature.
			 */
		}
		/*
		 * SIGCLD handler for detecting abormally-terminating
		 * sprocs and for reaping sprocs
		 */
		sigact.sa_handler = sigchld_handler;
		sigact.sa_flags = SA_RESTART;
		sigact.sa_mask = ints_off;
		sigaction(SIGCLD, &sigact, NULL);
    }
	return rv;
}

/*
 * PR_Cleanup should be executed on the primordial sproc; migrate the thread
 * to the primordial cpu
 */

void _PR_MD_PRE_CLEANUP(PRThread *me)
{
PRIntn is;
_PRCPU *cpu = _pr_primordialCPU;

	PR_ASSERT(cpu);

	me->flags |= _PR_BOUND_THREAD;	

	if (me->cpu->id != 0) {
		_PR_INTSOFF(is);
		_PR_RUNQ_LOCK(cpu);
		me->cpu = cpu;
		me->state = _PR_RUNNABLE;
		_PR_ADD_RUNQ(me, cpu, me->priority);
		_PR_RUNQ_UNLOCK(cpu);
		_MD_Wakeup_CPUs();

		_PR_MD_SWITCH_CONTEXT(me);

		_PR_FAST_INTSON(is);
		PR_ASSERT(me->cpu->id == 0);
	}
}

/*
 * process exiting
 */
PR_EXTERN(void ) _MD_exit(PRIntn status)
{
PRThread *me = _PR_MD_CURRENT_THREAD();

	/*
	 * the exit code of the process is the exit code of the primordial
	 * sproc
	 */
	if (!_PR_IS_NATIVE_THREAD(me) && (_PR_MD_CURRENT_CPU()->id == 0)) {
		/*
		 * primordial sproc case: call _exit directly
		 * Cause SIGKILL to be sent to other sprocs
		 */
		prctl(PR_SETEXITSIG, SIGKILL);
		_exit(status);
	} else {
		int rv;
		char data;
		sigset_t set;

		/*
		 * non-primordial sproc case: cause the primordial sproc, cpu 0,
		 * to wakeup and call _exit
		 */
		_pr_irix_process_exit = 1;
		_pr_irix_process_exit_code = status;
		rv = write(_pr_irix_primoridal_cpu_fd[1], &data, 1);
		PR_ASSERT(rv == 1);
		/*
		 * block all signals and wait for SIGKILL to terminate this sproc
		 */
		sigfillset(&set);
		sigsuspend(&set);
		/*
		 * this code doesn't (shouldn't) execute
		 */
		prctl(PR_SETEXITSIG, SIGKILL);
		_exit(status);
	}
}

/*
 * Override the exit() function in libc to cause the process to exit
 * when the primodial/main nspr thread calls exit. Calls to exit by any
 * other thread simply result in a call to the exit function in libc.
 * The exit code of the process is the exit code of the primordial
 * sproc.
 */

void exit(int status)
{
PRThread *me, *thr;
PRCList *qp;

	if (!_pr_initialized)  {
		if (!libc_exit) {

			if (!libc_handle)
				libc_handle = dlopen("libc.so",RTLD_NOW);
			if (libc_handle)
				libc_exit = (void (*)(int)) dlsym(libc_handle, "exit");
		}
		if (libc_exit)
			(*libc_exit)(status);
		else
			_exit(status);
	}

	me = _PR_MD_CURRENT_THREAD();

	if (me == NULL) 		/* detached thread */
		(*libc_exit)(status);

	PR_ASSERT(_PR_IS_NATIVE_THREAD(me) ||
						(_PR_MD_CURRENT_CPU())->id == me->cpu->id);

	if (me->flags & _PR_PRIMORDIAL) {

		me->flags |= _PR_BOUND_THREAD;	

		PR_ASSERT((_PR_MD_CURRENT_CPU())->id == me->cpu->id);
		if (me->cpu->id != 0) {
			_PRCPU *cpu = _pr_primordialCPU;
			PRIntn is;

			_PR_INTSOFF(is);
			_PR_RUNQ_LOCK(cpu);
			me->cpu = cpu;
			me->state = _PR_RUNNABLE;
			_PR_ADD_RUNQ(me, cpu, me->priority);
			_PR_RUNQ_UNLOCK(cpu);
			_MD_Wakeup_CPUs();

			_PR_MD_SWITCH_CONTEXT(me);

			_PR_FAST_INTSON(is);
		}

		PR_ASSERT((_PR_MD_CURRENT_CPU())->id == 0);

		if (prctl(PR_GETNSHARE) > 1) {
#define SPROC_EXIT_WAIT_TIME 5
			int sleep_cnt = SPROC_EXIT_WAIT_TIME;

			/*
			 * sprocs still running; caue cpus and recycled global threads
			 * to exit
			 */
			_pr_irix_exit_now = 1;
			if (_pr_numCPU > 1) {
				_MD_Wakeup_CPUs();
			}
			 _PR_DEADQ_LOCK;
			 if (_PR_NUM_DEADNATIVE != 0) {
				PRThread *thread;
				PRCList *ptr;

				ptr = _PR_DEADNATIVEQ.next;
				while( ptr != &_PR_DEADNATIVEQ ) {
					thread = _PR_THREAD_PTR(ptr);
					_MD_CVAR_POST_SEM(thread);
					ptr = ptr->next;
				} 
			 }

			while (sleep_cnt-- > 0) {
				if (waitpid(0, NULL, WNOHANG) >= 0) 
					sleep(1);
				else
					break;
			}
			prctl(PR_SETEXITSIG, SIGKILL);
		}
		(*libc_exit)(status);
	} else {
		/*
		 * non-primordial thread; simply call exit in libc.
		 */
		(*libc_exit)(status);
	}
}


void
_MD_InitRunningCPU(_PRCPU *cpu)
{
    extern int _pr_md_pipefd[2];

    _MD_unix_init_running_cpu(cpu);
    cpu->md.id = getpid();
	_MD_SET_SPROC_PID(getpid());	
	if (_pr_md_pipefd[0] >= 0) {
    	_PR_IOQ_MAX_OSFD(cpu) = _pr_md_pipefd[0];
#ifndef _PR_USE_POLL
    	FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(cpu));
#endif
	}
}

void
_MD_ExitThread(PRThread *thread)
{
    if (thread->flags & _PR_GLOBAL_SCOPE) {
        _MD_ATOMIC_DECREMENT(&_pr_md_irix_sprocs);
        _MD_CLEAN_THREAD(thread);
        _MD_SET_CURRENT_THREAD(NULL);
    }
}

void
_MD_SuspendCPU(_PRCPU *cpu)
{
    PRInt32 rv;

	cpu->md.suspending_id = getpid();
	rv = kill(cpu->md.id, SIGUSR1);
	PR_ASSERT(rv == 0);
	/*
	 * now, block the current thread/cpu until woken up by the suspended
	 * thread from it's SIGUSR1 signal handler
	 */
	blockproc(getpid());

}

void
_MD_ResumeCPU(_PRCPU *cpu)
{
    unblockproc(cpu->md.id);
}

#if 0
/*
 * save the register context of a suspended sproc
 */
void get_context(PRThread *thr)
{
    int len, fd;
    char pidstr[24];
    char path[24];

    /*
     * open the file corresponding to this process in procfs
     */
    sprintf(path,"/proc/%s","00000");
    len = strlen(path);
    sprintf(pidstr,"%d",thr->md.id);
    len -= strlen(pidstr);
    sprintf(path + len,"%s",pidstr);
    fd = open(path,O_RDONLY);
    if (fd >= 0) {
        (void) ioctl(fd, PIOCGREG, thr->md.gregs);
        close(fd);
    }
    return;
}
#endif	/* 0 */

void
_MD_SuspendThread(PRThread *thread)
{
    PRInt32 rv;

    PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) &&
        _PR_IS_GCABLE_THREAD(thread));

	thread->md.suspending_id = getpid();
	rv = kill(thread->md.id, SIGUSR1);
	PR_ASSERT(rv == 0);
	/*
	 * now, block the current thread/cpu until woken up by the suspended
	 * thread from it's SIGUSR1 signal handler
	 */
	blockproc(getpid());
}

void
_MD_ResumeThread(PRThread *thread)
{
    PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) &&
        _PR_IS_GCABLE_THREAD(thread));
    (void)unblockproc(thread->md.id);
}

/*
 * return the set of processors available for scheduling procs in the
 * "mask" argument
 */
PRInt32 _MD_GetThreadAffinityMask(PRThread *unused, PRUint32 *mask)
{
    PRInt32 nprocs, rv;
    struct pda_stat *pstat;
#define MAX_PROCESSORS    32

    nprocs = sysmp(MP_NPROCS);
    if (nprocs < 0)
        return(-1);
    pstat = (struct pda_stat*)PR_MALLOC(sizeof(struct pda_stat) * nprocs);
    if (pstat == NULL)
        return(-1);
    rv = sysmp(MP_STAT, pstat);
    if (rv < 0) {
        PR_DELETE(pstat);
        return(-1);
    }
    /*
     * look at the first 32 cpus
     */
    nprocs = (nprocs > MAX_PROCESSORS) ? MAX_PROCESSORS : nprocs;
    *mask = 0;
    while (nprocs) {
        if ((pstat->p_flags & PDAF_ENABLED) &&
            !(pstat->p_flags & PDAF_ISOLATED)) {
            *mask |= (1 << pstat->p_cpuid);
        }
        nprocs--;
        pstat++;
    }
    return 0;
}

static char *_thr_state[] = {
    "UNBORN",
    "RUNNABLE",
    "RUNNING",
    "LOCK_WAIT",
    "COND_WAIT",
    "JOIN_WAIT",
    "IO_WAIT",
    "SUSPENDED",
    "DEAD"
};

void _PR_List_Threads()
{
    PRThread *thr;
    void *handle;
    struct _PRCPU *cpu;
    PRCList *qp;
    int len, fd;
    char pidstr[24];
    char path[24];
    prpsinfo_t pinfo;


    printf("\n%s %-s\n"," ","LOCAL Threads");
    printf("%s %-s\n"," ","----- -------");
    printf("%s %-14s %-10s %-12s %-3s %-10s %-10s %-12s\n\n"," ",
        "Thread", "State", "Wait-Handle",
        "Cpu","Stk-Base","Stk-Sz","SP");
    for (qp = _PR_ACTIVE_LOCAL_THREADQ().next;
        qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp->next) {
        thr = _PR_ACTIVE_THREAD_PTR(qp);
        printf("%s 0x%-12x %-10s "," ",thr,_thr_state[thr->state]);
        if (thr->state == _PR_LOCK_WAIT)
            handle = thr->wait.lock;
        else if (thr->state == _PR_COND_WAIT)
            handle = thr->wait.cvar;
        else
            handle = NULL;
        if (handle)
            printf("0x%-10x ",handle);
        else
            printf("%-12s "," ");
        printf("%-3d ",thr->cpu->id);
        printf("0x%-8x ",thr->stack->stackBottom);
        printf("0x%-8x ",thr->stack->stackSize);
        printf("0x%-10x\n",thr->md.jb[JB_SP]);
    }

    printf("\n%s %-s\n"," ","GLOBAL Threads");
    printf("%s %-s\n"," ","------ -------");
    printf("%s %-14s %-6s %-12s %-12s %-12s %-12s\n\n"," ","Thread",
        "Pid","State","Wait-Handle",
        "Stk-Base","Stk-Sz");

    for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next;
        qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp->next) {
        thr = _PR_ACTIVE_THREAD_PTR(qp);
        if (thr->cpu != NULL)
            continue;        /* it is a cpu thread */
        printf("%s 0x%-12x %-6d "," ",thr,thr->md.id);
        /*
         * check if the sproc is still running
         * first call prctl(PR_GETSHMASK,pid) to check if
         * the process is part of the share group (the pid
         * could have been recycled by the OS)
         */
        if (prctl(PR_GETSHMASK,thr->md.id) < 0) {
            printf("%-12s\n","TERMINATED");
            continue;
        }
        /*
         * Now, check if the sproc terminated and is in zombie
         * state
         */
        sprintf(path,"/proc/pinfo/%s","00000");
        len = strlen(path);
        sprintf(pidstr,"%d",thr->md.id);
        len -= strlen(pidstr);
        sprintf(path + len,"%s",pidstr);
        fd = open(path,O_RDONLY);
        if (fd >= 0) {
            if (ioctl(fd, PIOCPSINFO, &pinfo) < 0)
                printf("%-12s ","TERMINATED");
            else if (pinfo.pr_zomb)
                printf("%-12s ","TERMINATED");
            else
                printf("%-12s ",_thr_state[thr->state]);
            close(fd);
        } else {
            printf("%-12s ","TERMINATED");
        }

        if (thr->state == _PR_LOCK_WAIT)
            handle = thr->wait.lock;
        else if (thr->state == _PR_COND_WAIT)
            handle = thr->wait.cvar;
        else
            handle = NULL;
        if (handle)
            printf("%-12x ",handle);
        else
            printf("%-12s "," ");
        printf("0x%-10x ",thr->stack->stackBottom);
        printf("0x%-10x\n",thr->stack->stackSize);
    }

    printf("\n%s %-s\n"," ","CPUs");
    printf("%s %-s\n"," ","----");
    printf("%s %-14s %-6s %-12s \n\n"," ","Id","Pid","State");


    for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) {
        cpu = _PR_CPU_PTR(qp);
        printf("%s %-14d %-6d "," ",cpu->id,cpu->md.id);
        /*
         * check if the sproc is still running
         * first call prctl(PR_GETSHMASK,pid) to check if
         * the process is part of the share group (the pid
         * could have been recycled by the OS)
         */
        if (prctl(PR_GETSHMASK,cpu->md.id) < 0) {
            printf("%-12s\n","TERMINATED");
            continue;
        }
        /*
         * Now, check if the sproc terminated and is in zombie
         * state
         */
        sprintf(path,"/proc/pinfo/%s","00000");
        len = strlen(path);
        sprintf(pidstr,"%d",cpu->md.id);
        len -= strlen(pidstr);
        sprintf(path + len,"%s",pidstr);
        fd = open(path,O_RDONLY);
        if (fd >= 0) {
            if (ioctl(fd, PIOCPSINFO, &pinfo) < 0)
                printf("%-12s\n","TERMINATED");
            else if (pinfo.pr_zomb)
                printf("%-12s\n","TERMINATED");
            else
                printf("%-12s\n","RUNNING");
            close(fd);
        } else {
            printf("%-12s\n","TERMINATED");
        }

    }
    fflush(stdout);
}
#endif /* defined(_PR_PTHREADS) */ 

PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
{
#if !defined(_PR_PTHREADS)
    if (isCurrent) {
        (void) setjmp(t->md.jb);
    }
    *np = sizeof(t->md.jb) / sizeof(PRWord);
    return (PRWord *) (t->md.jb);
#else
	*np = 0;
	return NULL;
#endif
}

void _MD_EarlyInit(void)
{
#if !defined(_PR_PTHREADS)
    char *eval;
    int fd;
	extern int __ateachexit(void (*func)(void));

    sigemptyset(&ints_off);
    sigaddset(&ints_off, SIGALRM);
    sigaddset(&ints_off, SIGIO);
    sigaddset(&ints_off, SIGCLD);

    if (eval = getenv("_NSPR_TERMINATE_ON_ERROR"))
        _nspr_terminate_on_error = (0 == atoi(eval) == 0) ? PR_FALSE : PR_TRUE;

    fd = open("/dev/zero",O_RDWR , 0);
    if (fd < 0) {
        perror("open /dev/zero failed");
        exit(1);
    }
    /*
     * Set up the sproc private data area.
     * This region exists at the same address, _nspr_sproc_private, for
     * every sproc, but each sproc gets a private copy of the region.
     */
    _nspr_sproc_private = (char*)mmap(0, _pr_pageSize, PROT_READ | PROT_WRITE,
        MAP_PRIVATE| MAP_LOCAL, fd, 0);
    if (_nspr_sproc_private == (void*)-1) {
        perror("mmap /dev/zero failed");
        exit(1);
    }
	_MD_SET_SPROC_PID(getpid());	
    close(fd);
	__ateachexit(irix_detach_sproc);
#endif
    _MD_IrixIntervalInit();
}  /* _MD_EarlyInit */

void _MD_IrixInit(void)
{
#if !defined(_PR_PTHREADS)
    struct sigaction sigact;
    PRThread *me = _PR_MD_CURRENT_THREAD();
	int rv;

#ifdef _PR_HAVE_SGI_PRDA_PROCMASK
	/*
	 * enable user-level processing of sigprocmask(); this is an undocumented
	 * feature available in Irix 6.2, 6.3, 6.4 and 6.5
	 */
	__sgi_prda_procmask(USER_LEVEL);
#endif

	/*
	 * set up SIGUSR1 handler; this is used to save state
	 * during PR_SuspendAll
	 */
	sigact.sa_handler = save_context_and_block;
	sigact.sa_flags = SA_RESTART;
	sigact.sa_mask = ints_off;
	sigaction(SIGUSR1, &sigact, 0);

    /*
     * Change the name of the core file from core to core.pid,
     * This is inherited by the sprocs created by this process
     */
#ifdef PR_COREPID
    prctl(PR_COREPID, 0, 1);
#endif
    /*
     * Irix-specific terminate on error processing
     */
	/*
	 * PR_SETABORTSIG is a new command implemented in a patch to
	 * Irix 6.2, 6.3 and 6.4. This causes a signal to be sent to all
	 * sprocs in the process when one of them terminates abnormally
	 *
	 */
	if (prctl(PR_SETABORTSIG, SIGKILL) < 0) {
		/*
		 *  if (errno == EINVAL)
		 *
		 *	PR_SETABORTSIG not supported under this OS.
		 *	You may want to get a recent kernel rollup patch that
		 *	supports this feature.
		 *
		 */
	}
	/*
	 * PR_SETEXITSIG -  send the SIGCLD signal to the parent
	 *            sproc when any sproc terminates
	 *
	 *    This is used to cause the entire application to
	 *    terminate when    any sproc terminates abnormally by
	 *     receipt of a SIGSEGV, SIGBUS or SIGABRT signal.
	 *    If this is not done, the application may seem
	 *     "hung" to the user because the other sprocs may be
	 *    waiting for resources held by the
	 *    abnormally-terminating sproc.
	 */
	prctl(PR_SETEXITSIG, 0);

	sigact.sa_handler = sigchld_handler;
	sigact.sa_flags = SA_RESTART;
	sigact.sa_mask = ints_off;
	sigaction(SIGCLD, &sigact, NULL);

    /*
     * setup stack fields for the primordial thread
     */
    me->stack->stackSize = prctl(PR_GETSTACKSIZE);
    me->stack->stackBottom = me->stack->stackTop - me->stack->stackSize;

    rv = pipe(_pr_irix_primoridal_cpu_fd);
    PR_ASSERT(rv == 0);
#ifndef _PR_USE_POLL
    _PR_IOQ_MAX_OSFD(me->cpu) = _pr_irix_primoridal_cpu_fd[0];
    FD_SET(_pr_irix_primoridal_cpu_fd[0], &_PR_FD_READ_SET(me->cpu));
#endif

	libc_handle = dlopen("libc.so",RTLD_NOW);
	PR_ASSERT(libc_handle != NULL);
	libc_exit = (void (*)(int)) dlsym(libc_handle, "exit");
	PR_ASSERT(libc_exit != NULL);
	/* dlclose(libc_handle); */

#endif /* _PR_PTHREADS */

    _PR_UnixInit();
}

/**************************************************************************/
/************** code and such for NSPR 2.0's interval times ***************/
/**************************************************************************/

#define PR_PSEC_PER_SEC 1000000000000ULL  /* 10^12 */

#ifndef SGI_CYCLECNTR_SIZE
#define SGI_CYCLECNTR_SIZE      165     /* Size user needs to use to read CC */
#endif

static PRIntn mmem_fd = -1;
static PRIntn clock_width = 0;
static void *iotimer_addr = NULL;
static PRUint32 pr_clock_mask = 0;
static PRUint32 pr_clock_shift = 0;
static PRIntervalTime pr_ticks = 0;
static PRUint32 pr_clock_granularity = 1;
static PRUint32 pr_previous = 0, pr_residual = 0;
static PRUint32 pr_ticks_per_second = 0;

extern PRIntervalTime _PR_UNIX_GetInterval(void);
extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);

static void _MD_IrixIntervalInit(void)
{
    /*
     * As much as I would like, the service available through this
     * interface on R3000's (aka, IP12) just isn't going to make it.
     * The register is only 24 bits wide, and rolls over at a verocious
     * rate.
     */
    PRUint32 one_tick = 0;
    struct utsname utsinfo;
    uname(&utsinfo);
    if ((strncmp("IP12", utsinfo.machine, 4) != 0)
        && ((mmem_fd = open("/dev/mmem", O_RDONLY)) != -1))
    {
        int poffmask = getpagesize() - 1;
        __psunsigned_t phys_addr, raddr, cycleval;

        phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &cycleval);
        raddr = phys_addr & ~poffmask;
        iotimer_addr = mmap(
            0, poffmask, PROT_READ, MAP_PRIVATE, mmem_fd, (__psint_t)raddr);

        clock_width = syssgi(SGI_CYCLECNTR_SIZE);
        if (clock_width < 0)
        {
            /* 
             * We must be executing on a 6.0 or earlier system, since the
             * SGI_CYCLECNTR_SIZE call is not supported.
             * 
             * The only pre-6.1 platforms with 64-bit counters are
             * IP19 and IP21 (Challenge, PowerChallenge, Onyx).
             */
            if (!strncmp(utsinfo.machine, "IP19", 4) ||
                !strncmp(utsinfo.machine, "IP21", 4))
                clock_width = 64;
            else
                clock_width = 32;
        }

        /*
         * 'cycleval' is picoseconds / increment of the counter.
         * I'm pushing for a tick to be 100 microseconds, 10^(-4).
         * That leaves 10^(-8) left over, or 10^8 / cycleval.
         * Did I do that right?
         */

        one_tick =  100000000UL / cycleval ;  /* 100 microseconds */

        while (0 != one_tick)
        {
            pr_clock_shift += 1;
            one_tick = one_tick >> 1;
            pr_clock_granularity = pr_clock_granularity << 1;
        }
        pr_clock_mask = pr_clock_granularity - 1;  /* to make a mask out of it */
        pr_ticks_per_second = PR_PSEC_PER_SEC
                / ((PRUint64)pr_clock_granularity * (PRUint64)cycleval);
            
        iotimer_addr = (void*)
            ((__psunsigned_t)iotimer_addr + (phys_addr & poffmask));
    }
    else
    {
        pr_ticks_per_second = _PR_UNIX_TicksPerSecond();
    }
}  /* _MD_IrixIntervalInit */

PRIntervalTime _MD_IrixIntervalPerSec(void)
{
    return pr_ticks_per_second;
}

PRIntervalTime _MD_IrixGetInterval(void)
{
    if (mmem_fd != -1)
    {
        if (64 == clock_width)
        {
            PRUint64 temp = *(PRUint64*)iotimer_addr;
            pr_ticks = (PRIntervalTime)(temp >> pr_clock_shift);
        }
        else
        {
            PRIntervalTime ticks = pr_ticks;
            PRUint32 now = *(PRUint32*)iotimer_addr, temp;
            PRUint32 residual = pr_residual, previous = pr_previous;

            temp = now - previous + residual;
            residual = temp & pr_clock_mask;
            ticks += temp >> pr_clock_shift;

            pr_previous = now;
            pr_residual = residual;
            pr_ticks = ticks;
        }
    }
    else
    {
        /*
         * No fast access. Use the time of day clock. This isn't the
         * right answer since this clock can get set back, tick at odd
         * rates, and it's expensive to acqurie.
         */
        pr_ticks = _PR_UNIX_GetInterval();
    }
    return pr_ticks;
}  /* _MD_IrixGetInterval */

