nsprpub/pr/include/prthread.h

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef prthread_h___
     7 #define prthread_h___
     9 /*
    10 ** API for NSPR threads. On some architectures (Mac OS Classic
    11 ** notably) pre-emptibility is not guaranteed. Hard priority scheduling
    12 ** is not guaranteed, so programming using priority based synchronization
    13 ** is a no-no.
    14 **
    15 ** NSPR threads are scheduled based loosely on their client set priority.
    16 ** In general, a thread of a higher priority has a statistically better
    17 ** chance of running relative to threads of lower priority. However,
    18 ** NSPR uses multiple strategies to provide execution vehicles for thread
    19 ** abstraction of various host platforms. As it turns out, there is little
    20 ** NSPR can do to affect the scheduling attributes of "GLOBAL" threads.
    21 ** However, a semblance of GLOBAL threads is used to implement "LOCAL"
    22 ** threads. An arbitrary number of such LOCAL threads can be assigned to
    23 ** a single GLOBAL thread.
    24 **
    25 ** For scheduling, NSPR will attempt to run the highest priority LOCAL
    26 ** thread associated with a given GLOBAL thread. It is further assumed
    27 ** that the host OS will apply some form of "fair" scheduling on the
    28 ** GLOBAL threads.
    29 **
    30 ** Threads have a "system flag" which when set indicates the thread
    31 ** doesn't count for determining when the process should exit (the
    32 ** process exits when the last user thread exits).
    33 **
    34 ** Threads also have a "scope flag" which controls whether the threads
    35 ** are scheduled in the local scope or scheduled by the OS globally. This 
    36 ** indicates whether a thread is permanently bound to a native OS thread. 
    37 ** An unbound thread competes for scheduling resources in the same process.
    38 **
    39 ** Another flag is "state flag" which control whether the thread is joinable.
    40 ** It allows other threads to wait for the created thread to reach completion.
    41 **
    42 ** Threads can have "per-thread-data" attached to them. Each thread has a
    43 ** per-thread error number and error string which are updated when NSPR
    44 ** operations fail.
    45 */
    46 #include "prtypes.h"
    47 #include "prinrval.h"
    49 PR_BEGIN_EXTERN_C
    51 typedef struct PRThread PRThread;
    52 typedef struct PRThreadStack PRThreadStack;
    54 typedef enum PRThreadType {
    55     PR_USER_THREAD,
    56     PR_SYSTEM_THREAD
    57 } PRThreadType;
    59 typedef enum PRThreadScope {
    60     PR_LOCAL_THREAD,
    61     PR_GLOBAL_THREAD,
    62     PR_GLOBAL_BOUND_THREAD
    63 } PRThreadScope;
    65 typedef enum PRThreadState {
    66     PR_JOINABLE_THREAD,
    67     PR_UNJOINABLE_THREAD
    68 } PRThreadState;
    70 typedef enum PRThreadPriority
    71 {
    72     PR_PRIORITY_FIRST = 0,      /* just a placeholder */
    73     PR_PRIORITY_LOW = 0,        /* the lowest possible priority */
    74     PR_PRIORITY_NORMAL = 1,     /* most common expected priority */
    75     PR_PRIORITY_HIGH = 2,       /* slightly more aggressive scheduling */
    76     PR_PRIORITY_URGENT = 3,     /* it does little good to have more than one */
    77     PR_PRIORITY_LAST = 3        /* this is just a placeholder */
    78 } PRThreadPriority;
    80 /*
    81 ** Create a new thread:
    82 **     "type" is the type of thread to create
    83 **     "start(arg)" will be invoked as the threads "main"
    84 **     "priority" will be created thread's priority
    85 **     "scope" will specify whether the thread is local or global
    86 **     "state" will specify whether the thread is joinable or not
    87 **     "stackSize" the size of the stack, in bytes. The value can be zero
    88 **        and then a machine specific stack size will be chosen.
    89 **
    90 ** This can return NULL if some kind of error occurs, such as if memory is
    91 ** tight.
    92 **
    93 ** If you want the thread to start up waiting for the creator to do
    94 ** something, enter a lock before creating the thread and then have the
    95 ** threads start routine enter and exit the same lock. When you are ready
    96 ** for the thread to run, exit the lock.
    97 **
    98 ** If you want to detect the completion of the created thread, the thread
    99 ** should be created joinable.  Then, use PR_JoinThread to synchrnoize the
   100 ** termination of another thread.
   101 **
   102 ** When the start function returns the thread exits. If it is the last
   103 ** PR_USER_THREAD to exit then the process exits.
   104 */
   105 NSPR_API(PRThread*) PR_CreateThread(PRThreadType type,
   106                      void (PR_CALLBACK *start)(void *arg),
   107                      void *arg,
   108                      PRThreadPriority priority,
   109                      PRThreadScope scope,
   110                      PRThreadState state,
   111                      PRUint32 stackSize);
   113 /*
   114 ** Wait for thread termination:
   115 **     "thread" is the target thread 
   116 **
   117 ** This can return PR_FAILURE if no joinable thread could be found 
   118 ** corresponding to the specified target thread.
   119 **
   120 ** The calling thread is blocked until the target thread completes.
   121 ** Several threads cannot wait for the same thread to complete; one thread
   122 ** will operate successfully and others will terminate with an error PR_FAILURE.
   123 ** The calling thread will not be blocked if the target thread has already
   124 ** terminated.
   125 */
   126 NSPR_API(PRStatus) PR_JoinThread(PRThread *thread);
   128 /*
   129 ** Return the current thread object for the currently running code.
   130 ** Never returns NULL.
   131 */
   132 NSPR_API(PRThread*) PR_GetCurrentThread(void);
   133 #ifndef NO_NSPR_10_SUPPORT
   134 #define PR_CurrentThread() PR_GetCurrentThread() /* for nspr1.0 compat. */
   135 #endif /* NO_NSPR_10_SUPPORT */
   137 /*
   138 ** Get the priority of "thread".
   139 */
   140 NSPR_API(PRThreadPriority) PR_GetThreadPriority(const PRThread *thread);
   142 /*
   143 ** Change the priority of the "thread" to "priority".
   144 **
   145 ** PR_SetThreadPriority works in a best-effort manner. On some platforms a
   146 ** special privilege, such as root access, is required to change thread
   147 ** priorities, especially to raise thread priorities. If the caller doesn't
   148 ** have enough privileges to change thread priorites, the function has no
   149 ** effect except causing a future PR_GetThreadPriority call to return
   150 ** |priority|.
   151 */
   152 NSPR_API(void) PR_SetThreadPriority(PRThread *thread, PRThreadPriority priority);
   154 /*
   155 ** Set the name of the current thread, which will be visible in a debugger
   156 ** and accessible via a call to PR_GetThreadName().
   157 */
   158 NSPR_API(PRStatus) PR_SetCurrentThreadName(const char *name);
   160 /*
   161 ** Return the name of "thread", if set.  Otherwise return NULL.
   162 */
   163 NSPR_API(const char *) PR_GetThreadName(const PRThread *thread);
   165 /*
   166 ** This routine returns a new index for per-thread-private data table. 
   167 ** The index is visible to all threads within a process. This index can 
   168 ** be used with the PR_SetThreadPrivate() and PR_GetThreadPrivate() routines 
   169 ** to save and retrieve data associated with the index for a thread.
   170 **
   171 ** Each index is associationed with a destructor function ('dtor'). The function
   172 ** may be specified as NULL when the index is created. If it is not NULL, the
   173 ** function will be called when:
   174 **      - the thread exits and the private data for the associated index
   175 **        is not NULL,
   176 **      - new thread private data is set and the current private data is
   177 **        not NULL.
   178 **
   179 ** The index independently maintains specific values for each binding thread. 
   180 ** A thread can only get access to its own thread-specific-data.
   181 **
   182 ** Upon a new index return the value associated with the index for all threads
   183 ** is NULL, and upon thread creation the value associated with all indices for 
   184 ** that thread is NULL. 
   185 **
   186 ** Returns PR_FAILURE if the total number of indices will exceed the maximun 
   187 ** allowed.
   188 */
   189 typedef void (PR_CALLBACK *PRThreadPrivateDTOR)(void *priv);
   191 NSPR_API(PRStatus) PR_NewThreadPrivateIndex(
   192     PRUintn *newIndex, PRThreadPrivateDTOR destructor);
   194 /*
   195 ** Define some per-thread-private data.
   196 **     "tpdIndex" is an index into the per-thread private data table
   197 **     "priv" is the per-thread-private data 
   198 **
   199 ** If the per-thread private data table has a previously registered
   200 ** destructor function and a non-NULL per-thread-private data value,
   201 ** the destructor function is invoked.
   202 **
   203 ** This can return PR_FAILURE if the index is invalid.
   204 */
   205 NSPR_API(PRStatus) PR_SetThreadPrivate(PRUintn tpdIndex, void *priv);
   207 /*
   208 ** Recover the per-thread-private data for the current thread. "tpdIndex" is
   209 ** the index into the per-thread private data table. 
   210 **
   211 ** The returned value may be NULL which is indistinguishable from an error 
   212 ** condition.
   213 **
   214 ** A thread can only get access to its own thread-specific-data.
   215 */
   216 NSPR_API(void*) PR_GetThreadPrivate(PRUintn tpdIndex);
   218 /*
   219 ** This routine sets the interrupt request for a target thread. The interrupt
   220 ** request remains in the thread's state until it is delivered exactly once
   221 ** or explicitly canceled.
   222 **
   223 ** A thread that has been interrupted will fail all NSPR blocking operations
   224 ** that return a PRStatus (I/O, waiting on a condition, etc).
   225 **
   226 ** PR_Interrupt may itself fail if the target thread is invalid.
   227 */
   228 NSPR_API(PRStatus) PR_Interrupt(PRThread *thread);
   230 /*
   231 ** Clear the interrupt request for the calling thread. If no such request
   232 ** is pending, this operation is a noop.
   233 */
   234 NSPR_API(void) PR_ClearInterrupt(void);
   236 /*
   237 ** Block the interrupt for the calling thread.
   238 */
   239 NSPR_API(void) PR_BlockInterrupt(void);
   241 /*
   242 ** Unblock the interrupt for the calling thread.
   243 */
   244 NSPR_API(void) PR_UnblockInterrupt(void);
   246 /*
   247 ** Make the current thread sleep until "ticks" time amount of time
   248 ** has expired. If "ticks" is PR_INTERVAL_NO_WAIT then the call is
   249 ** equivalent to calling PR_Yield. Calling PR_Sleep with an argument
   250 ** equivalent to PR_INTERVAL_NO_TIMEOUT is an error and will result
   251 ** in a PR_FAILURE error return.
   252 */
   253 NSPR_API(PRStatus) PR_Sleep(PRIntervalTime ticks);
   255 /*
   256 ** Get the scoping of this thread.
   257 */
   258 NSPR_API(PRThreadScope) PR_GetThreadScope(const PRThread *thread);
   260 /*
   261 ** Get the type of this thread.
   262 */
   263 NSPR_API(PRThreadType) PR_GetThreadType(const PRThread *thread);
   265 /*
   266 ** Get the join state of this thread.
   267 */
   268 NSPR_API(PRThreadState) PR_GetThreadState(const PRThread *thread);
   270 PR_END_EXTERN_C
   272 #endif /* prthread_h___ */

mercurial