1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/nsprpub/pr/include/prthread.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,272 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef prthread_h___ 1.10 +#define prthread_h___ 1.11 + 1.12 +/* 1.13 +** API for NSPR threads. On some architectures (Mac OS Classic 1.14 +** notably) pre-emptibility is not guaranteed. Hard priority scheduling 1.15 +** is not guaranteed, so programming using priority based synchronization 1.16 +** is a no-no. 1.17 +** 1.18 +** NSPR threads are scheduled based loosely on their client set priority. 1.19 +** In general, a thread of a higher priority has a statistically better 1.20 +** chance of running relative to threads of lower priority. However, 1.21 +** NSPR uses multiple strategies to provide execution vehicles for thread 1.22 +** abstraction of various host platforms. As it turns out, there is little 1.23 +** NSPR can do to affect the scheduling attributes of "GLOBAL" threads. 1.24 +** However, a semblance of GLOBAL threads is used to implement "LOCAL" 1.25 +** threads. An arbitrary number of such LOCAL threads can be assigned to 1.26 +** a single GLOBAL thread. 1.27 +** 1.28 +** For scheduling, NSPR will attempt to run the highest priority LOCAL 1.29 +** thread associated with a given GLOBAL thread. It is further assumed 1.30 +** that the host OS will apply some form of "fair" scheduling on the 1.31 +** GLOBAL threads. 1.32 +** 1.33 +** Threads have a "system flag" which when set indicates the thread 1.34 +** doesn't count for determining when the process should exit (the 1.35 +** process exits when the last user thread exits). 1.36 +** 1.37 +** Threads also have a "scope flag" which controls whether the threads 1.38 +** are scheduled in the local scope or scheduled by the OS globally. This 1.39 +** indicates whether a thread is permanently bound to a native OS thread. 1.40 +** An unbound thread competes for scheduling resources in the same process. 1.41 +** 1.42 +** Another flag is "state flag" which control whether the thread is joinable. 1.43 +** It allows other threads to wait for the created thread to reach completion. 1.44 +** 1.45 +** Threads can have "per-thread-data" attached to them. Each thread has a 1.46 +** per-thread error number and error string which are updated when NSPR 1.47 +** operations fail. 1.48 +*/ 1.49 +#include "prtypes.h" 1.50 +#include "prinrval.h" 1.51 + 1.52 +PR_BEGIN_EXTERN_C 1.53 + 1.54 +typedef struct PRThread PRThread; 1.55 +typedef struct PRThreadStack PRThreadStack; 1.56 + 1.57 +typedef enum PRThreadType { 1.58 + PR_USER_THREAD, 1.59 + PR_SYSTEM_THREAD 1.60 +} PRThreadType; 1.61 + 1.62 +typedef enum PRThreadScope { 1.63 + PR_LOCAL_THREAD, 1.64 + PR_GLOBAL_THREAD, 1.65 + PR_GLOBAL_BOUND_THREAD 1.66 +} PRThreadScope; 1.67 + 1.68 +typedef enum PRThreadState { 1.69 + PR_JOINABLE_THREAD, 1.70 + PR_UNJOINABLE_THREAD 1.71 +} PRThreadState; 1.72 + 1.73 +typedef enum PRThreadPriority 1.74 +{ 1.75 + PR_PRIORITY_FIRST = 0, /* just a placeholder */ 1.76 + PR_PRIORITY_LOW = 0, /* the lowest possible priority */ 1.77 + PR_PRIORITY_NORMAL = 1, /* most common expected priority */ 1.78 + PR_PRIORITY_HIGH = 2, /* slightly more aggressive scheduling */ 1.79 + PR_PRIORITY_URGENT = 3, /* it does little good to have more than one */ 1.80 + PR_PRIORITY_LAST = 3 /* this is just a placeholder */ 1.81 +} PRThreadPriority; 1.82 + 1.83 +/* 1.84 +** Create a new thread: 1.85 +** "type" is the type of thread to create 1.86 +** "start(arg)" will be invoked as the threads "main" 1.87 +** "priority" will be created thread's priority 1.88 +** "scope" will specify whether the thread is local or global 1.89 +** "state" will specify whether the thread is joinable or not 1.90 +** "stackSize" the size of the stack, in bytes. The value can be zero 1.91 +** and then a machine specific stack size will be chosen. 1.92 +** 1.93 +** This can return NULL if some kind of error occurs, such as if memory is 1.94 +** tight. 1.95 +** 1.96 +** If you want the thread to start up waiting for the creator to do 1.97 +** something, enter a lock before creating the thread and then have the 1.98 +** threads start routine enter and exit the same lock. When you are ready 1.99 +** for the thread to run, exit the lock. 1.100 +** 1.101 +** If you want to detect the completion of the created thread, the thread 1.102 +** should be created joinable. Then, use PR_JoinThread to synchrnoize the 1.103 +** termination of another thread. 1.104 +** 1.105 +** When the start function returns the thread exits. If it is the last 1.106 +** PR_USER_THREAD to exit then the process exits. 1.107 +*/ 1.108 +NSPR_API(PRThread*) PR_CreateThread(PRThreadType type, 1.109 + void (PR_CALLBACK *start)(void *arg), 1.110 + void *arg, 1.111 + PRThreadPriority priority, 1.112 + PRThreadScope scope, 1.113 + PRThreadState state, 1.114 + PRUint32 stackSize); 1.115 + 1.116 +/* 1.117 +** Wait for thread termination: 1.118 +** "thread" is the target thread 1.119 +** 1.120 +** This can return PR_FAILURE if no joinable thread could be found 1.121 +** corresponding to the specified target thread. 1.122 +** 1.123 +** The calling thread is blocked until the target thread completes. 1.124 +** Several threads cannot wait for the same thread to complete; one thread 1.125 +** will operate successfully and others will terminate with an error PR_FAILURE. 1.126 +** The calling thread will not be blocked if the target thread has already 1.127 +** terminated. 1.128 +*/ 1.129 +NSPR_API(PRStatus) PR_JoinThread(PRThread *thread); 1.130 + 1.131 +/* 1.132 +** Return the current thread object for the currently running code. 1.133 +** Never returns NULL. 1.134 +*/ 1.135 +NSPR_API(PRThread*) PR_GetCurrentThread(void); 1.136 +#ifndef NO_NSPR_10_SUPPORT 1.137 +#define PR_CurrentThread() PR_GetCurrentThread() /* for nspr1.0 compat. */ 1.138 +#endif /* NO_NSPR_10_SUPPORT */ 1.139 + 1.140 +/* 1.141 +** Get the priority of "thread". 1.142 +*/ 1.143 +NSPR_API(PRThreadPriority) PR_GetThreadPriority(const PRThread *thread); 1.144 + 1.145 +/* 1.146 +** Change the priority of the "thread" to "priority". 1.147 +** 1.148 +** PR_SetThreadPriority works in a best-effort manner. On some platforms a 1.149 +** special privilege, such as root access, is required to change thread 1.150 +** priorities, especially to raise thread priorities. If the caller doesn't 1.151 +** have enough privileges to change thread priorites, the function has no 1.152 +** effect except causing a future PR_GetThreadPriority call to return 1.153 +** |priority|. 1.154 +*/ 1.155 +NSPR_API(void) PR_SetThreadPriority(PRThread *thread, PRThreadPriority priority); 1.156 + 1.157 +/* 1.158 +** Set the name of the current thread, which will be visible in a debugger 1.159 +** and accessible via a call to PR_GetThreadName(). 1.160 +*/ 1.161 +NSPR_API(PRStatus) PR_SetCurrentThreadName(const char *name); 1.162 + 1.163 +/* 1.164 +** Return the name of "thread", if set. Otherwise return NULL. 1.165 +*/ 1.166 +NSPR_API(const char *) PR_GetThreadName(const PRThread *thread); 1.167 + 1.168 +/* 1.169 +** This routine returns a new index for per-thread-private data table. 1.170 +** The index is visible to all threads within a process. This index can 1.171 +** be used with the PR_SetThreadPrivate() and PR_GetThreadPrivate() routines 1.172 +** to save and retrieve data associated with the index for a thread. 1.173 +** 1.174 +** Each index is associationed with a destructor function ('dtor'). The function 1.175 +** may be specified as NULL when the index is created. If it is not NULL, the 1.176 +** function will be called when: 1.177 +** - the thread exits and the private data for the associated index 1.178 +** is not NULL, 1.179 +** - new thread private data is set and the current private data is 1.180 +** not NULL. 1.181 +** 1.182 +** The index independently maintains specific values for each binding thread. 1.183 +** A thread can only get access to its own thread-specific-data. 1.184 +** 1.185 +** Upon a new index return the value associated with the index for all threads 1.186 +** is NULL, and upon thread creation the value associated with all indices for 1.187 +** that thread is NULL. 1.188 +** 1.189 +** Returns PR_FAILURE if the total number of indices will exceed the maximun 1.190 +** allowed. 1.191 +*/ 1.192 +typedef void (PR_CALLBACK *PRThreadPrivateDTOR)(void *priv); 1.193 + 1.194 +NSPR_API(PRStatus) PR_NewThreadPrivateIndex( 1.195 + PRUintn *newIndex, PRThreadPrivateDTOR destructor); 1.196 + 1.197 +/* 1.198 +** Define some per-thread-private data. 1.199 +** "tpdIndex" is an index into the per-thread private data table 1.200 +** "priv" is the per-thread-private data 1.201 +** 1.202 +** If the per-thread private data table has a previously registered 1.203 +** destructor function and a non-NULL per-thread-private data value, 1.204 +** the destructor function is invoked. 1.205 +** 1.206 +** This can return PR_FAILURE if the index is invalid. 1.207 +*/ 1.208 +NSPR_API(PRStatus) PR_SetThreadPrivate(PRUintn tpdIndex, void *priv); 1.209 + 1.210 +/* 1.211 +** Recover the per-thread-private data for the current thread. "tpdIndex" is 1.212 +** the index into the per-thread private data table. 1.213 +** 1.214 +** The returned value may be NULL which is indistinguishable from an error 1.215 +** condition. 1.216 +** 1.217 +** A thread can only get access to its own thread-specific-data. 1.218 +*/ 1.219 +NSPR_API(void*) PR_GetThreadPrivate(PRUintn tpdIndex); 1.220 + 1.221 +/* 1.222 +** This routine sets the interrupt request for a target thread. The interrupt 1.223 +** request remains in the thread's state until it is delivered exactly once 1.224 +** or explicitly canceled. 1.225 +** 1.226 +** A thread that has been interrupted will fail all NSPR blocking operations 1.227 +** that return a PRStatus (I/O, waiting on a condition, etc). 1.228 +** 1.229 +** PR_Interrupt may itself fail if the target thread is invalid. 1.230 +*/ 1.231 +NSPR_API(PRStatus) PR_Interrupt(PRThread *thread); 1.232 + 1.233 +/* 1.234 +** Clear the interrupt request for the calling thread. If no such request 1.235 +** is pending, this operation is a noop. 1.236 +*/ 1.237 +NSPR_API(void) PR_ClearInterrupt(void); 1.238 + 1.239 +/* 1.240 +** Block the interrupt for the calling thread. 1.241 +*/ 1.242 +NSPR_API(void) PR_BlockInterrupt(void); 1.243 + 1.244 +/* 1.245 +** Unblock the interrupt for the calling thread. 1.246 +*/ 1.247 +NSPR_API(void) PR_UnblockInterrupt(void); 1.248 + 1.249 +/* 1.250 +** Make the current thread sleep until "ticks" time amount of time 1.251 +** has expired. If "ticks" is PR_INTERVAL_NO_WAIT then the call is 1.252 +** equivalent to calling PR_Yield. Calling PR_Sleep with an argument 1.253 +** equivalent to PR_INTERVAL_NO_TIMEOUT is an error and will result 1.254 +** in a PR_FAILURE error return. 1.255 +*/ 1.256 +NSPR_API(PRStatus) PR_Sleep(PRIntervalTime ticks); 1.257 + 1.258 +/* 1.259 +** Get the scoping of this thread. 1.260 +*/ 1.261 +NSPR_API(PRThreadScope) PR_GetThreadScope(const PRThread *thread); 1.262 + 1.263 +/* 1.264 +** Get the type of this thread. 1.265 +*/ 1.266 +NSPR_API(PRThreadType) PR_GetThreadType(const PRThread *thread); 1.267 + 1.268 +/* 1.269 +** Get the join state of this thread. 1.270 +*/ 1.271 +NSPR_API(PRThreadState) PR_GetThreadState(const PRThread *thread); 1.272 + 1.273 +PR_END_EXTERN_C 1.274 + 1.275 +#endif /* prthread_h___ */