c21fa75195a7820167c79f0fd761416f92173d28
[tpg/acess2.git] / Modules / Interfaces / EDI / edi / edi_pthreads.h
1 #ifndef EDI_PTHREADS
2
3 /* Copyright (c)  2006  Eli Gottlieb.
4  * Permission is granted to copy, distribute and/or modify this document
5  * under the terms of the GNU Free Documentation License, Version 1.2
6  * or any later version published by the Free Software Foundation;
7  * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
8  * Texts.  A copy of the license is included in the file entitled "COPYING". */
9
10 #define EDI_PTHREADS
11 /*!\file edi_pthreads.h
12  * \brief A basic subset of POSIX Threads functionality, providing threading and thread synchronization.
13  *
14  * A very basic POSIX Threads interface.  Note that pthreads are not a class, because none of these calls really gels with
15  * object-oriented programming.  Also, if drivers aren't processes or threads under the implementing operating system a small
16  * threading system must be implemented in-runtime just to multiplex the pthreads of EDI drivers.  Sorry about that.
17  *
18  * Data structures and algorithms this header represents:
19  *
20  *      ALGORITHM AND DATA STRUCTURE: POSIX Threading - The runtime must provide enough of a POSIX threading interface to implement
21  * the calls described here.  The actual multithreading must be performed by the runtime, and the runtime can implement that
22  * multithreading however it likes as long as the given POSIX Threads subset works.  There is, however, a caveat: since the runtime
23  * calls the driver like it would a library, the driver must perceive all calls made to it by the runtime as running under one thread.
24  * From this thread the driver can create others.  Such behavior is a quirk of EDI, and does not come from the POSIX standard.
25  * However, it is necessary to provide the driver with a thread for its own main codepaths.  For further details on a given POSIX
26  * Threading routine, consult its Unix manual page. */
27
28 #include "edi_objects.h"
29
30 /* Placeholder type definitions.  Users of the PThreads interface only ever need to define pointers to these types. */
31 /*!\brief Opaque POSIX Threading thread attribute type. */
32 typedef void pthread_attr_t;
33 /*!\brief Opaque POSIX Threading mutex (mutual exclusion semaphore) type. */
34 typedef void pthread_mutex_t;
35 /*!\brief Opaque POSIX Threading mutex attribute type. */
36 typedef void pthread_mutex_attr_t;
37
38 /*!\struct sched_param
39  * \brief POSIX Threading scheduler parameters for a thread. */
40 typedef struct {
41         /*!\brief The priority of the thread. */
42         int32_t sched_priority;
43 } sched_param;
44
45 /*!\brief POSIX Threading thread identifier. */
46 typedef uint32_t pthread_t;
47 /*!\brief POSIX Threading thread function type.
48  *
49  * A function pointer to a thread function, with the required signature of a thread function.  A thread function takes one untyped
50  * pointer as an argument and returns an untyped pointer.  Such a function is a thread's main routine: it's started with the thread,
51  * and the thread exits if it returns. */
52 typedef void *(*pthread_function_t)(void*);
53
54 /*!\brief Insufficient resources. */
55 #define EAGAIN -1
56 /*!\brief Invalid parameter. */
57 #define EINVAL -2
58 /*!\brief Permission denied. */
59 #define EPERM -3
60 /*!\brief Operation not supported. */
61 #define ENOTSUP -4
62 /*!\brief Priority scheduling for POSIX/multiple schedulers is not implemented. */
63 #define ENOSYS -5
64 /*!\brief Out of memory. */
65 #define ENOMEM -6
66 /*!\brief Deadlock.  Crap. */
67 #define EDEADLK -7
68 /*!\brief Busy.  Mutex already locked. */
69 #define EBUSY -8
70
71 /*!\brief Scheduling policy for regular, non-realtime scheduling.  The default. */
72 #define SCHED_OTHER 0
73 /*!\brief Real-time, first-in first-out scheduling policy.  Requires special (superuser, where such a thing exists) permissions. */
74 #define SCHED_FIFO 1
75 /*!\brief Real-time, round-robin scheduling policy.  Requires special (superuser, where such a thing exists) permissions. */
76 #define SCHED_RR 0
77
78 /*!\brief Creates a new thread with the given attributes, thread function and arguments, giving back the thread ID of the new
79  * thread.
80  *
81  * pthread_create() creates a new thread of control that executes concurrently with the calling thread.  The new thread applies the
82  * function start_routine, passing it arg as its argument.  The attr argument specifies thread attributes to apply to the new thread;
83  * it can also be NULL for the default thread attributes (joinable with default scheduling policy).  On success this function returns
84  * 0 and places the identifier of the new thread into thread_id.  On an error, pthread_create() can return EAGAIN if insufficient
85  * runtime resources are available to create the requested thread, EINVAL a value specified by attributes is invalid, or EPERM if the
86  * caller doesn't have permissions to set the given attributes.
87  *
88  * For further information: man 3 pthread_create */
89 int32_t pthread_create(pthread_t *thread_id, const pthread_attr_t *attributes, pthread_function_t thread_function, void *arguments);
90 /*!\brief Terminates the execution of the calling thread.  The thread's exit code with by status, and this routine never returns. */
91 void pthread_exit(void *status);
92 /*!\brief Returns the thread identifier of the calling thread. */
93 pthread_t pthread_self();
94 /*!\brief Compares two thread identifiers.
95  *
96  * Determines of the given two thread identifiers refer to the same thread.  If so, returns non-zero.  Otherwise, 0 is returned. */
97 int32_t pthread_equal(pthread_t thread1, pthread_t thread2);
98 /*!\brief Used by the calling thread to relinquish use of the processor.  The thread then waits in the run queue to be scheduled
99  * again. */
100 void pthread_yield();
101
102 /*!\brief Gets the scheduling policy of the given attributes.
103  *
104  * Places the scheduling policy for attributes into policy.  Returns 0 on success, EINVAL if attributes was invalid, and ENOSYS if
105  * priority scheduling/multiple scheduler support is not implemented. */
106 int32_t pthread_attr_getschedpolicy(const pthread_attr_t *attributes, int32_t *policy);
107 /*!\brief Sets the scheduling policy of the given attributes.
108  *
109  * Requests a switch of scheduling policy to policy for the given attributes.  Can return 0 for success, EINVAL if the given policy
110  * is not one of SCHED_OTHER, SCHED_FIFO or SCHED_RR or ENOTSUP if policy is either SCHED_FIFO or SCHED_RR and the driver is not
111  * running with correct privileges. */
112 int32_t pthread_attr_setschedpolicy(pthread_attr_t *attributes, int32_t policy);
113
114 /*!\brief Gets the scheduling paramaters (priority) from the given attributes.
115  *
116  * On success, stores scheduling parameters in param from attributes, and returns 0.  Otherwise, returns non-zero error code, such
117  * as EINVAL if the attributes object is invalid. */
118 int32_t pthread_attr_getschedparam(const pthread_attr_t *attributes, sched_param *param);
119 /*!\brief Sets the scheduling parameters (priority) of the given attributes.
120  *
121  * Requests that the runtime set the scheduling parameters (priority) of attributes from param. Returns 0 for success, EINVAL for an
122  * invalid attributes object, ENOSYS when multiple schedulers/priority scheduling is not implemented, and ENOTSUP when the value of
123  * param isn't supported/allowed. */
124 int32_t pthread_attr_setschedparam(pthread_attr_t *attributes, const sched_param *param);
125
126 /*!\brief The thread obtains its scheduling properties explicitly from its attributes structure. */
127 #define PTHREAD_EXPLICIT_SCHED 1
128 /*!\brief The thread inherits its scheduling properties from its parent thread. */
129 #define PTHREAD_INHERIT_SCHED 0
130
131 /*!\brief Returns the inheritsched attribute of the given attributes.
132  *
133  * On success, returns 0 and places the inheritsched attribute from attributes into inherit.  This attribute specifies where the
134  * thread's scheduling properites shall come from, and can be set to PTHREAD_EXPLICIT_SCHED or PTHREAD_INHERIT_SCHED.  On failure it
135  * returns EINVAL if attributes was invalid or ENOSYS if multiple schedulers/priority scheduling isn't implemented. */
136 int32_t pthread_attr_getinheritsched(const pthread_attr_t *attributes, int32_t *inherit);
137 /*!\brief Sets the inheritsched attribute of the given attributes.
138  *
139  * On success, places inherit into the inheritsched attribute of attributes and returns 0.  inherit must either contain
140  * PTHREAD_EXPLICIT_SCHED or PTHREAD_INHERIT_SCHED.  On failure, this routine returns EINVAL if attributes is invalid, ENOSYS when
141  * multiple schedulers/priority scheduling isn't implemented, and ENOSUP if the inheritsched attribute isn't supported. */
142 int32_t pthread_attr_setinheritsched(pthread_attr_t *attributes, int32_t inherit);
143
144 /*!\brief Creates a new POSIX Threads mutex, which will initially be unlocked.
145  *
146  * Creates a new mutex with the given attributes.  If attributes is NULL, the default attributes will be used.  The mutex starts out
147  * unlocked.  On success, the new mutex resides in the mutex structure pointed to by mutex, and this routine routines 0.  On failure,
148  * it returns EAGAIN if the system lacked sufficient non-memory resources to initialize the mutex, EBUSY if the given mutex is
149  * already initialized and in use, EINVAL if either parameter is invalid, and ENOMEM if the system lacks the memory for a new
150  * mutex.  Note: All EDI mutexes are created with the default attributes, and are of type PTHREAD_MUTEX_ERRORCHECK.  This means
151  * undefined behavior can never result from an badly placed function call. */
152 int32_t pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutex_attr_t *attributes);
153 /*!\brief Locks the given mutex.
154  *
155  * Locks the given mutex.  If the mutex is already locked, blocks the calling thread until it can acquire the lock.  When this
156  * routine returns successfully, it will return 0 and the calling thread will own the lock of the mutex.  If the call fails, it can
157  * return EINVAL when mutex is invalid or EDEADLK if the calling thread already owns the mutex. */
158 int32_t pthread_mutex_lock(pthread_mutex_t *mutex);
159 /*!\brief Unlocks the given mutex.
160  *
161  * Unlocks the given mutex, returning 0 on success.  On failure, it can return EINVAL when mutex is invalid or EPERM when the
162  * calling thread doesn't own the mutex. */
163 int32_t pthread_mutex_unlock(pthread_mutex_t *mutex);
164 /*!\brief Tries to lock the given mutex, returning immediately even if the mutex is already locked.
165  *
166  * Attempts to lock the given mutex, but returns immediately if it can't acquire a lock.  Returns 0 when it has acquired a lock,
167  * EBUSY if the mutex is already locked, or EINVAL if mutex is invalid. */
168 int32_t pthread_mutex_trylock(pthread_mutex_t *mutex);
169 /*!\brief Destroys the given mutex, or at least the internal structure of it. 
170  *
171  * Deletes the given mutex, making mutex invalid until it should be initialized by pthread_mutex_init().  Returns 0 on success,
172  * EINVAL when mutex is invalid, or EBUSY when mutex is locked or referenced by another thread. */
173 int32_t pthread_mutex_destroy (pthread_mutex_t *mutex);
174
175 #endif

UCC git Repository :: git.ucc.asn.au