Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions | Variables
irix.c File Reference
#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>
#include "prprf.h"

Go to the source code of this file.

Classes

struct  nspr_arena
struct  sproc_data
struct  sproc_params

Defines

#define ARENA_PTR(qp)   ((nspr_arena *) ((char*) (qp) - offsetof(nspr_arena , links)))
#define SPROC_PARAMS_PTR(qp)   ((sproc_params *) ((char*) (qp) - offsetof(sproc_params , links)))
#define _NSPR_DEF_INITUSERS   100 /* default value of CONF_INITUSERS */
#define _NSPR_DEF_INITSIZE   (4 * 1024 * 1024) /* 4 MB */
#define PR_SETABORTSIG   18
#define SPROC_EXIT_WAIT_TIME   5
#define MAX_PROCESSORS   32
#define PR_PSEC_PER_SEC   1000000000000ULL /* 10^12 */
#define SGI_CYCLECNTR_SIZE   165 /* Size user needs to use to read CC */

Typedefs

typedef struct nspr_arena nspr_arena
typedef struct sproc_data sproc_data
typedef struct sproc_params sproc_params

Functions

static void _MD_IrixIntervalInit (void)
static void irix_detach_sproc (void)
static usptr_t * alloc_new_arena (void)
void _PR_Irix_Set_Arena_Params (PRInt32 initusers, PRInt32 initsize)
static PRStatus new_poll_sem (struct _MDThread *mdthr, int val)
static void free_poll_sem (struct _MDThread *mdthr)
static PRStatus new_lock (struct _MDLock *lockp)
static void free_lock (struct _MDLock *lockp)
void _MD_FREE_LOCK (struct _MDLock *lockp)
PRThread_MD_get_attached_thread (void)
PRThread_MD_get_current_thread (void)
PRStatus _MD_NEW_LOCK (struct _MDLock *lockp)
static void sigchld_handler (int sig)
static void save_context_and_block (int sig)
PRInt32 _MD_irix_connect (PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen, PRIntervalTime timeout)
void_MD_GetSP (PRThread *t)
void _MD_InitLocks ()
void _PR_IRIX_CHILD_PROCESS ()
static PRStatus pr_cvar_wait_sem (PRThread *thread, PRIntervalTime timeout)
PRStatus _MD_wait (PRThread *thread, PRIntervalTime ticks)
PRStatus _MD_WakeupWaiter (PRThread *thread)
void create_sproc (void(*entry)(void *, size_t), unsigned inh, void *arg, caddr_t sp, size_t len, int *pid)
void _PR_MD_WAKEUP_PRIMORDIAL_CPU ()
void _PR_MD_primordial_cpu ()
PRStatus _MD_CreateThread (PRThread *thread, void(*start)(void *), PRThreadPriority priority, PRThreadScope scope, PRThreadState state, PRUint32 stackSize)
void _MD_CleanThread (PRThread *thread)
void _MD_SetPriority (_MDThread *thread, PRThreadPriority newPri)
void _MD_unix_terminate_waitpid_daemon (void)
void _MD_CleanupBeforeExit (void)
PRStatus _MD_InitAttachedThread (PRThread *thread, PRBool wakeup_parent)
PRStatus _MD_InitThread (PRThread *thread, PRBool wakeup_parent)
void _PR_MD_PRE_CLEANUP (PRThread *me)
 PR_EXTERN (void)
 Sets SecurityCotext for proxy env.
void exit (int status)
void _MD_InitRunningCPU (_PRCPU *cpu)
void _MD_ExitThread (PRThread *thread)
void _MD_SuspendCPU (_PRCPU *cpu)
void _MD_ResumeCPU (_PRCPU *cpu)
void _MD_SuspendThread (PRThread *thread)
void _MD_ResumeThread (PRThread *thread)
PRInt32 _MD_GetThreadAffinityMask (PRThread *unused, PRUint32 *mask)
void _PR_List_Threads ()
PRWord_MD_HomeGCRegisters (PRThread *t, int isCurrent, int *np)
void _MD_EarlyInit (void)
void _MD_IrixInit (void)
PRIntervalTime _PR_UNIX_GetInterval (void)
PRIntervalTime _PR_UNIX_TicksPerSecond (void)
PRIntervalTime _MD_IrixIntervalPerSec (void)
PRIntervalTime _MD_IrixGetInterval (void)

Variables

char * _nspr_sproc_private
PRUintn _pr_numCPU
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
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
PRInt32 _pr_irix_process_exit = 0
int _pr_irix_primoridal_cpu_fd [2] = { -1, -1 }
static void(* libc_exit )(int) = NULL
static voidlibc_handle = NULL
int _irix_initusers = _NSPR_DEF_INITUSERS
int _irix_initsize = _NSPR_DEF_INITSIZE
PRIntn _pr_io_in_progress
PRIntn _pr_clock_in_progress
PRInt32 _pr_md_irix_sprocs_created
PRInt32 _pr_md_irix_sprocs_failed
PRInt32 _pr_md_irix_sprocs = 1
PRCList _pr_md_irix_sproc_list
sigset_t ints_off
sigset_t timer_set
PRBool _nspr_terminate_on_error = PR_TRUE
static char * _thr_state []
static PRIntn mmem_fd = -1
static PRIntn clock_width = 0
static voidiotimer_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
static PRUint32 pr_residual = 0
static PRUint32 pr_ticks_per_second = 0

Class Documentation

struct nspr_arena

Definition at line 76 of file irix.c.

Class Members
PRCList links
usptr_t * usarena
struct sproc_params

Definition at line 104 of file irix.c.

Collaboration diagram for sproc_params:
Class Members
PRCList links
sproc_data sd

Define Documentation

#define _NSPR_DEF_INITSIZE   (4 * 1024 * 1024) /* 4 MB */

Definition at line 130 of file irix.c.

#define _NSPR_DEF_INITUSERS   100 /* default value of CONF_INITUSERS */

Definition at line 129 of file irix.c.

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

Definition at line 81 of file irix.c.

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

Definition at line 1554 of file irix.c.

Definition at line 146 of file irix.c.

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

Definition at line 1557 of file irix.c.

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

Definition at line 109 of file irix.c.


Typedef Documentation

typedef struct nspr_arena nspr_arena
typedef struct sproc_data sproc_data
typedef struct sproc_params sproc_params

Function Documentation

void _MD_CleanThread ( PRThread thread)

Definition at line 794 of file irix.c.

{
    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;
    }
}

Here is the call graph for this function:

Definition at line 812 of file irix.c.

{
    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;
     }
}

Here is the call graph for this function:

PRStatus _MD_CreateThread ( PRThread thread,
void(*)(void *)  start,
PRThreadPriority  priority,
PRThreadScope  scope,
PRThreadState  state,
PRUint32  stackSize 
)

Definition at line 736 of file irix.c.

{
    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;
    }
}

Here is the call graph for this function:

Definition at line 1419 of file irix.c.

{
#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 */

Here is the call graph for this function:

void _MD_ExitThread ( PRThread thread)

Definition at line 1132 of file irix.c.

void _MD_FREE_LOCK ( struct _MDLock lockp)

Definition at line 309 of file irix.c.

{
       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);
}

Here is the call graph for this function:

Definition at line 329 of file irix.c.

{

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

Definition at line 343 of file irix.c.

{
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);
}

Here is the call graph for this function:

void* _MD_GetSP ( PRThread t)

Definition at line 460 of file irix.c.

{
    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);
}
PRInt32 _MD_GetThreadAffinityMask ( PRThread unused,
PRUint32 mask 
)

Definition at line 1220 of file irix.c.

{
    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;
}
PRWord* _MD_HomeGCRegisters ( PRThread t,
int  isCurrent,
int np 
)

Definition at line 1405 of file irix.c.

{
#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
}
PRStatus _MD_InitAttachedThread ( PRThread thread,
PRBool  wakeup_parent 
)

Definition at line 858 of file irix.c.

{
       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;
}

Here is the call graph for this function:

Definition at line 474 of file irix.c.

{
    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);
}

Here is the call graph for this function:

Definition at line 1116 of file irix.c.

{
    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
       }
}

Here is the call graph for this function:

PRStatus _MD_InitThread ( PRThread thread,
PRBool  wakeup_parent 
)

Definition at line 884 of file irix.c.

{
    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;
}

Here is the call graph for this function:

PRInt32 _MD_irix_connect ( PRInt32  osfd,
const PRNetAddr addr,
PRInt32  addrlen,
PRIntervalTime  timeout 
)

Definition at line 439 of file irix.c.

{
    PRInt32 rv;
    sigset_t oldset;

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

    return(rv);
}

Here is the caller graph for this function:

Definition at line 1645 of file irix.c.

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

Here is the call graph for this function:

Definition at line 1457 of file irix.c.

{
#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();
}

Here is the call graph for this function:

static void _MD_IrixIntervalInit ( void  ) [static]

Definition at line 1573 of file irix.c.

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

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1640 of file irix.c.

{
    return pr_ticks_per_second;
}
PRStatus _MD_NEW_LOCK ( struct _MDLock lockp)

Definition at line 371 of file irix.c.

{
    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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1158 of file irix.c.

{
    unblockproc(cpu->md.id);
}

Definition at line 1209 of file irix.c.

{
    PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) &&
        _PR_IS_GCABLE_THREAD(thread));
    (void)unblockproc(thread->md.id);
}
void _MD_SetPriority ( _MDThread thread,
PRThreadPriority  newPri 
)

Definition at line 804 of file irix.c.

{
    return;
}

Definition at line 1142 of file irix.c.

{
    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());

}

Definition at line 1191 of file irix.c.

{
    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());
}

Here is the caller graph for this function:

PRStatus _MD_wait ( PRThread thread,
PRIntervalTime  ticks 
)

Definition at line 603 of file irix.c.

{
    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;
}

Here is the call graph for this function:

Definition at line 639 of file irix.c.

Here is the call graph for this function:

Definition at line 520 of file irix.c.

{
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());       
}
void _PR_Irix_Set_Arena_Params ( PRInt32  initusers,
PRInt32  initsize 
)

Definition at line 156 of file irix.c.

{
    _irix_initusers = initusers;
    _irix_initsize = initsize;
}

Definition at line 1265 of file irix.c.

{
    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);
}

Here is the call graph for this function:

Definition at line 944 of file irix.c.

{
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);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 715 of file irix.c.

{
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);
}

Here is the caller graph for this function:

Definition at line 699 of file irix.c.

{
char data = '0';
int rv;

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

Definition at line 124 of file beos.c.

{
       struct timeval time;
       PRIntervalTime ticks;

       (void)GETTIMEOFDAY(&time);  /* fallicy of course */
       ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC;  /* that's in milliseconds */
       ticks += (PRUint32)time.tv_usec / PR_USEC_PER_MSEC;  /* so's that */
       return ticks;
}  /* _PR_SUNOS_GetInterval */

Definition at line 135 of file beos.c.

{
       return 1000;  /* this needs some work :) */
}
static usptr_t * alloc_new_arena ( void  ) [static]

Definition at line 162 of file irix.c.

{
    return(usinit("/dev/zero"));
}

Here is the caller graph for this function:

void create_sproc ( void(*)(void *, size_t)  entry,
unsigned  inh,
void arg,
caddr_t  sp,
size_t  len,
int pid 
)

Definition at line 662 of file irix.c.

{
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());
       }
}

Here is the caller graph for this function:

void exit ( int  status)

Definition at line 1021 of file irix.c.

{
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);
       }
}

Here is the call graph for this function:

static void free_lock ( struct _MDLock lockp) [static]

Definition at line 296 of file irix.c.

{
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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void free_poll_sem ( struct _MDThread mdthr) [static]

Definition at line 225 of file irix.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void irix_detach_sproc ( void  ) [static]

Definition at line 360 of file irix.c.

{
PRThread *me;

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

Here is the call graph for this function:

Here is the caller graph for this function:

static PRStatus new_lock ( struct _MDLock lockp) [static]

Definition at line 238 of file irix.c.

{
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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRStatus new_poll_sem ( struct _MDThread mdthr,
int  val 
) [static]

Definition at line 167 of file irix.c.

{
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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRStatus pr_cvar_wait_sem ( PRThread thread,
PRIntervalTime  timeout 
) [static]

Definition at line 534 of file irix.c.

{
    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;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

PR_EXTERN ( void  )

Sets SecurityCotext for proxy env.

XPI_Exit.

Definition at line 972 of file irix.c.

{
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);
       }
}
static void save_context_and_block ( int  sig) [static]

Definition at line 407 of file irix.c.

{
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());
}

Here is the caller graph for this function:

static void sigchld_handler ( int  sig) [static]

Definition at line 386 of file irix.c.

{
    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);
                     }
    }
}

Here is the caller graph for this function:


Variable Documentation

Definition at line 133 of file irix.c.

Definition at line 132 of file irix.c.

Definition at line 89 of file irix.c.

Definition at line 112 of file irix.c.

Definition at line 114 of file irix.c.

Definition at line 113 of file irix.c.

Definition at line 72 of file irix.c.

Definition at line 151 of file irix.c.

Definition at line 135 of file irix.c.

ulock_t _pr_heapLock

Definition at line 117 of file irix.c.

Definition at line 135 of file irix.c.

Definition at line 120 of file irix.c.

Definition at line 119 of file irix.c.

Definition at line 125 of file irix.c.

Definition at line 122 of file irix.c.

Definition at line 121 of file irix.c.

Initial value:

Definition at line 139 of file irix.c.

Definition at line 138 of file irix.c.

Definition at line 137 of file irix.c.

Definition at line 137 of file irix.c.

PRUintn _pr_numCPU

Definition at line 55 of file prucpu.c.

usptr_t* _pr_usArena

Definition at line 116 of file irix.c.

char* _thr_state[] [static]
Initial value:
 {
    "UNBORN",
    "RUNNABLE",
    "RUNNING",
    "LOCK_WAIT",
    "COND_WAIT",
    "JOIN_WAIT",
    "IO_WAIT",
    "SUSPENDED",
    "DEAD"
}

Definition at line 1253 of file irix.c.

Definition at line 86 of file irix.c.

ulock_t arena_list_lock

Definition at line 87 of file irix.c.

PRIntn clock_width = 0 [static]

Definition at line 1561 of file irix.c.

Definition at line 88 of file irix.c.

Definition at line 142 of file irix.c.

void* iotimer_addr = NULL [static]

Definition at line 1562 of file irix.c.

void(* libc_exit)(int) = NULL [static]

Definition at line 126 of file irix.c.

void* libc_handle = NULL [static]

Definition at line 127 of file irix.c.

PRIntn mmem_fd = -1 [static]

Definition at line 1560 of file irix.c.

Definition at line 1566 of file irix.c.

PRUint32 pr_clock_mask = 0 [static]

Definition at line 1563 of file irix.c.

PRUint32 pr_clock_shift = 0 [static]

Definition at line 1564 of file irix.c.

PRUint32 pr_previous = 0 [static]

Definition at line 1567 of file irix.c.

PRUint32 pr_residual = 0 [static]

Definition at line 1567 of file irix.c.

PRIntervalTime pr_ticks = 0 [static]

Definition at line 1565 of file irix.c.

Definition at line 1568 of file irix.c.

Definition at line 91 of file irix.c.

ulock_t sproc_list_lock

Definition at line 92 of file irix.c.

Definition at line 73 of file beos.c.