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". */
11 /*!\file edi_pthreads.h
12 * \brief A basic subset of POSIX Threads functionality, providing threading and thread synchronization.
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.
18 * Data structures and algorithms this header represents:
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. */
28 #include "edi_objects.h"
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;
38 /*!\struct sched_param
39 * \brief POSIX Threading scheduler parameters for a thread. */
41 /*!\brief The priority of the thread. */
42 int32_t sched_priority;
45 /*!\brief POSIX Threading thread identifier. */
46 typedef uint32_t pthread_t;
47 /*!\brief POSIX Threading thread function type.
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*);
54 /*!\brief Insufficient resources. */
56 /*!\brief Invalid parameter. */
58 /*!\brief Permission denied. */
60 /*!\brief Operation not supported. */
62 /*!\brief Priority scheduling for POSIX/multiple schedulers is not implemented. */
64 /*!\brief Out of memory. */
66 /*!\brief Deadlock. Crap. */
68 /*!\brief Busy. Mutex already locked. */
71 /*!\brief Scheduling policy for regular, non-realtime scheduling. The default. */
73 /*!\brief Real-time, first-in first-out scheduling policy. Requires special (superuser, where such a thing exists) permissions. */
75 /*!\brief Real-time, round-robin scheduling policy. Requires special (superuser, where such a thing exists) permissions. */
78 /*!\brief Creates a new thread with the given attributes, thread function and arguments, giving back the thread ID of the new
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.
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.
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
100 void pthread_yield();
102 /*!\brief Gets the scheduling policy of the given attributes.
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.
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);
114 /*!\brief Gets the scheduling paramaters (priority) from the given attributes.
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.
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);
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
131 /*!\brief Returns the inheritsched attribute of the given attributes.
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.
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);
144 /*!\brief Creates a new POSIX Threads mutex, which will initially be unlocked.
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.
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.
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.
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.
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);