Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
pthreads_user.c File Reference
#include "primpl.h"
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>

Go to the source code of this file.

Defines

#define PT_NANOPERMICRO   1000UL
#define PT_BILLION   1000000000UL

Functions

void _MD_EarlyInit (void)
void _MD_InitLocks ()
 PR_IMPLEMENT (void)
 PR_IMPLEMENT (PRStatus)
PRWord_MD_HomeGCRegisters (PRThread *t, int isCurrent, int *np)
 _MD_SetPriority (_MDThread *thread, PRThreadPriority newPri)
 _pt_wait (PRThread *thread, PRIntervalTime timeout)
 _MD_wait (PRThread *thread, PRIntervalTime ticks)
 _MD_WakeupWaiter (PRThread *thread)
 _MD_YIELD (void)
 _MD_CreateThread (PRThread *thread, void(*start)(void *), PRThreadPriority priority, PRThreadScope scope, PRThreadState state, PRUint32 stackSize)
 _MD_InitRunningCPU (struct _PRCPU *cpu)
void _MD_CleanupBeforeExit (void)

Variables

sigset_t ints_off
pthread_mutex_t _pr_heapLock
pthread_key_t current_thread_key
pthread_key_t current_cpu_key
pthread_key_t last_thread_key
pthread_key_t intsoff_key
PRInt32 _pr_md_pthreads_created
PRInt32 _pr_md_pthreads_failed
PRInt32 _pr_md_pthreads = 1

Define Documentation

#define PT_BILLION   1000000000UL

Definition at line 238 of file pthreads_user.c.

#define PT_NANOPERMICRO   1000UL

Definition at line 237 of file pthreads_user.c.


Function Documentation

Definition at line 441 of file pthreads_user.c.

{
#if 0
    extern PRInt32    _pr_cpus_exit;

       _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;
     }
#endif
}

Here is the call graph for this function:

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

Definition at line 364 of file pthreads_user.c.

{
    PRIntn is;
    int rv;
       PRThread *me = _PR_MD_CURRENT_THREAD();   
       pthread_attr_t attr;

       if (!_PR_IS_NATIVE_THREAD(me))
              _PR_INTSOFF(is);

       if (pthread_mutex_init(&thread->md.pthread_mutex, NULL) != 0) {
              if (!_PR_IS_NATIVE_THREAD(me))
                     _PR_FAST_INTSON(is);
        return PR_FAILURE;
       }

       if (pthread_cond_init(&thread->md.pthread_cond, NULL) != 0) {
              pthread_mutex_destroy(&thread->md.pthread_mutex);
              if (!_PR_IS_NATIVE_THREAD(me))
                     _PR_FAST_INTSON(is);
        return PR_FAILURE;
       }
    thread->flags |= _PR_GLOBAL_SCOPE;

       pthread_attr_init(&attr); /* initialize attr with default attributes */
       if (pthread_attr_setstacksize(&attr, (size_t) stackSize) != 0) {
              pthread_mutex_destroy(&thread->md.pthread_mutex);
              pthread_cond_destroy(&thread->md.pthread_cond);
              pthread_attr_destroy(&attr);
              if (!_PR_IS_NATIVE_THREAD(me))
                     _PR_FAST_INTSON(is);
        return PR_FAILURE;
       }

       thread->md.wait = 0;
    rv = pthread_create(&thread->md.pthread, &attr, start, (void *)thread);
    if (0 == rv) {
        _MD_ATOMIC_INCREMENT(&_pr_md_pthreads_created);
        _MD_ATOMIC_INCREMENT(&_pr_md_pthreads);
              if (!_PR_IS_NATIVE_THREAD(me))
                     _PR_FAST_INTSON(is);
        return PR_SUCCESS;
    } else {
              pthread_mutex_destroy(&thread->md.pthread_mutex);
              pthread_cond_destroy(&thread->md.pthread_cond);
              pthread_attr_destroy(&attr);
        _MD_ATOMIC_INCREMENT(&_pr_md_pthreads_failed);
              if (!_PR_IS_NATIVE_THREAD(me))
                     _PR_FAST_INTSON(is);
        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, rv);
        return PR_FAILURE;
    }
}

Here is the call graph for this function:

Definition at line 56 of file pthreads_user.c.

{
extern PRInt32 _nspr_noclock;

       if (pthread_key_create(&current_thread_key, NULL) != 0) {
              perror("pthread_key_create failed");
              exit(1);
       }
       if (pthread_key_create(&current_cpu_key, NULL) != 0) {
              perror("pthread_key_create failed");
              exit(1);
       }
       if (pthread_key_create(&last_thread_key, NULL) != 0) {
              perror("pthread_key_create failed");
              exit(1);
       }
       if (pthread_key_create(&intsoff_key, NULL) != 0) {
              perror("pthread_key_create failed");
              exit(1);
       }

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

       /*
        * disable clock interrupts
        */
       _nspr_noclock = 1;

}

Here is the call graph for this function:

PRWord* _MD_HomeGCRegisters ( PRThread t,
int  isCurrent,
int np 
)

Definition at line 126 of file pthreads_user.c.

{
    if (isCurrent) {
       (void) setjmp(CONTEXT(t));
    }
    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
    return (PRWord *) CONTEXT(t);
}

Definition at line 89 of file pthreads_user.c.

{
       if (pthread_mutex_init(&_pr_heapLock, NULL) != 0) {
              perror("pthread_mutex_init failed");
              exit(1);
       }
}

Here is the call graph for this function:

_MD_InitRunningCPU ( struct _PRCPU cpu)

Definition at line 425 of file pthreads_user.c.

{
    extern int _pr_md_pipefd[2];

    _MD_unix_init_running_cpu(cpu);
    cpu->md.pthread = pthread_self();
       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:

_MD_SetPriority ( _MDThread thread,
PRThreadPriority  newPri 
)

Definition at line 136 of file pthreads_user.c.

{
       /*
        * XXX - to be implemented
        */
    return;
}
_MD_wait ( PRThread thread,
PRIntervalTime  ticks 
)

Definition at line 285 of file pthreads_user.c.

{
    if ( thread->flags & _PR_GLOBAL_SCOPE ) {
              _MD_CHECK_FOR_EXIT();
        if (_pt_wait(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 {
                     _pt_wait(thread, PR_INTERVAL_NO_TIMEOUT);
                _PR_THREAD_UNLOCK(thread);
            }
        }
    } else {
              _PR_MD_SWITCH_CONTEXT(thread);
    }
    return PR_SUCCESS;
}

Here is the call graph for this function:

_MD_WakeupWaiter ( PRThread thread)

Definition at line 315 of file pthreads_user.c.

{
    PRThread *me = _PR_MD_CURRENT_THREAD();
    PRInt32 pid, rv;
    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 the thread is on my cpu's runq there is no need to
               * wakeup any cpus
               */
              if (!_PR_IS_NATIVE_THREAD(me)) {
                     if (me->cpu != thread->cpu) {
                            if (_pr_md_idle_cpus)
                            _MD_Wakeup_CPUs();
                     }
              } else {
                     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);

              pthread_mutex_lock(&thread->md.pthread_mutex);
              thread->md.wait++;
              rv = pthread_cond_signal(&thread->md.pthread_cond);
              PR_ASSERT(rv == 0);
              pthread_mutex_unlock(&thread->md.pthread_mutex);

              if (!_PR_IS_NATIVE_THREAD(me))
                     _PR_FAST_INTSON(is);
    } 
    return PR_SUCCESS;
}

Here is the call graph for this function:

_MD_YIELD ( void  )

Definition at line 358 of file pthreads_user.c.

{
    PR_NOT_REACHED("_MD_YIELD should not be called for AIX.");
}
_pt_wait ( PRThread thread,
PRIntervalTime  timeout 
)

Definition at line 241 of file pthreads_user.c.

{
int rv;
struct timeval now;
struct timespec tmo;
PRUint32 ticks = PR_TicksPerSecond();


       if (timeout != PR_INTERVAL_NO_TIMEOUT) {
              tmo.tv_sec = timeout / ticks;
              tmo.tv_nsec = timeout - (tmo.tv_sec * ticks);
              tmo.tv_nsec = PR_IntervalToMicroseconds(PT_NANOPERMICRO *
                                                                             tmo.tv_nsec);

              /* pthreads wants this in absolute time, off we go ... */
              (void)GETTIMEOFDAY(&now);
              /* that one's usecs, this one's nsecs - grrrr! */
              tmo.tv_sec += now.tv_sec;
              tmo.tv_nsec += (PT_NANOPERMICRO * now.tv_usec);
              tmo.tv_sec += tmo.tv_nsec / PT_BILLION;
              tmo.tv_nsec %= PT_BILLION;
       }

       pthread_mutex_lock(&thread->md.pthread_mutex);
       thread->md.wait--;
       if (thread->md.wait < 0) {
              if (timeout != PR_INTERVAL_NO_TIMEOUT) {
                     rv = pthread_cond_timedwait(&thread->md.pthread_cond,
                                   &thread->md.pthread_mutex, &tmo);
        }
              else
                     rv = pthread_cond_wait(&thread->md.pthread_cond,
                                   &thread->md.pthread_mutex);
              if (rv != 0) {
                     thread->md.wait++;
              }
       } else
              rv = 0;
       pthread_mutex_unlock(&thread->md.pthread_mutex);

       return (rv == 0) ? PR_SUCCESS : PR_FAILURE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 97 of file pthreads_user.c.

{
       PRIntn _is;
       PRThread *me = _PR_MD_CURRENT_THREAD();

       if (me && !_PR_IS_NATIVE_THREAD(me))
              _PR_INTSOFF(_is); 
       pthread_mutex_destroy(&lockp->mutex);
       if (me && !_PR_IS_NATIVE_THREAD(me))
              _PR_FAST_INTSON(_is);
}

Here is the call graph for this function:

Definition at line 111 of file pthreads_user.c.

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

       if (me && !_PR_IS_NATIVE_THREAD(me))
              _PR_INTSOFF(is);
       rv = pthread_mutex_init(&lockp->mutex, NULL);
       if (me && !_PR_IS_NATIVE_THREAD(me))
              _PR_FAST_INTSON(is);
       return (rv == 0) ? PR_SUCCESS : PR_FAILURE;
}

Here is the call graph for this function:


Variable Documentation

Definition at line 46 of file pthreads_user.c.

Definition at line 54 of file pthreads_user.c.

Definition at line 53 of file pthreads_user.c.

Definition at line 53 of file pthreads_user.c.

Definition at line 48 of file pthreads_user.c.

Definition at line 47 of file pthreads_user.c.

Definition at line 45 of file pthreads_user.c.

Definition at line 50 of file pthreads_user.c.

Definition at line 49 of file pthreads_user.c.