nsprpub/pr/include/prthread.h

changeset 0
6474c204b198
     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___ */

mercurial