1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Add missing doxygen for pthread funs and structs

This commit is contained in:
René Kijewski 2014-04-16 22:45:42 +02:00
parent f2e28c8146
commit 3e6bebadd3
23 changed files with 919 additions and 330 deletions

View File

@ -1,101 +1,26 @@
#ifndef RIOT_PTHREAD_H
#define RIOT_PTHREAD_H 1
/**
* @ingroup pthread
*/
#include <time.h>
#include "kernel.h"
#include "mutex.h"
#include "sched.h"
#include "pthreadtypes.h"
/* Create a new thread, starting with execution of START-ROUTINE
getting passed ARG. Creation attributed come from ATTR. The new
handle is stored in *NEWTHREAD. */
int pthread_create(pthread_t *newthread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg);
/* Terminate calling thread.
The registered cleanup handlers are called via exception handling .*/
void pthread_exit(void *retval);
/* Make calling thread wait for termination of the thread TH. The
exit status of the thread is stored in *THREAD_RETURN, if THREAD_RETURN
is not NULL.
This function is a cancellation point and therefore not marked with
. */
int pthread_join(pthread_t th, void **thread_return);
/* Indicate that the thread TH is never to be joined with PTHREAD_JOIN.
The resources of TH will therefore be freed immediately when it
terminates, instead of waiting for another thread to perform PTHREAD_JOIN
on it. */
int pthread_detach(pthread_t th);
/* Obtain the identifier of the current thread. */
pthread_t pthread_self(void);
/* Compare two thread identifiers. */
int pthread_equal(pthread_t thread1, pthread_t thread2);
#include "pthread_attr.h"
/* Functions for scheduling control. */
/* Set the scheduling parameters for TARGET_THREAD according to POLICY
and *PARAM. */
int pthread_setschedparam(pthread_t target_thread, int policy,
const struct sched_param *param);
/* Return in *POLICY and *PARAM the scheduling parameters for TARGET_THREAD. */
int pthread_getschedparam(pthread_t target_thread, int *policy,
struct sched_param *param);
/* Set the scheduling priority for TARGET_THREAD. */
int pthread_setschedprio(pthread_t target_thread, int prio);
/* Functions for handling initialization. */
/* Guarantee that the initialization function INIT_ROUTINE will be called
only once, even if pthread_once is executed several times with the
same ONCE_CONTROL argument. ONCE_CONTROL must point to a static or
variable initialized to PTHREAD_ONCE_INIT.
The initialization functions might throw exception */
int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
/* Functions for handling cancellation.
Note that these functions are explicitly not marked to not throw an
exception in C++ code. If cancellation is implemented by unwinding
this is necessary to have the compiler generate the unwind information. */
/* Set cancelability state of current thread to STATE, returning old
state in *OLDSTATE if OLDSTATE is not NULL. */
int pthread_setcancelstate(int state, int *oldstate);
/* Set cancellation state of current thread to TYPE, returning the old
type in *OLDTYPE if OLDTYPE is not NULL. */
int pthread_setcanceltype(int type, int *oldtype);
/* Cancel THREAD immediately or at the next possibility. */
int pthread_cancel(pthread_t th);
/* Test for pending cancellation for the current thread and terminate
the thread as per pthread_exit(PTHREAD_CANCELED) if it has been
cancelled. */
void pthread_testcancel(void);
#include "pthread_threading_attr.h"
#include "pthread_threading.h"
#include "pthread_mutex_attr.h"
#include "pthread_mutex.h"
#include "pthread_rwlock.h"
#include "pthread_spin.h"
#include "pthread_barrier.h"
#include "pthread_cleanup.h"
#include "pthread_once.h"
#include "pthread_scheduling.h"
#include "pthread_cancellation.h"
#endif /* pthread.h */

View File

@ -1,67 +0,0 @@
/* Thread attribute handling. */
#define PTHREAD_CREATE_DETACHED (1)
#define PTHREAD_CREATE_JOINABLE (0)
/* Initialize thread attribute *ATTR with default attributes
(detachstate is PTHREAD_JOINABLE, scheduling policy is SCHED_OTHER,
no user-provided stack). */
int pthread_attr_init(pthread_attr_t *attr);
/* Destroy thread attribute *ATTR. */
int pthread_attr_destroy(pthread_attr_t *attr);
/* Get detach state attribute. */
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
/* Set detach state attribute. */
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
/* Get the size of the guard area created for stack overflow protection. */
int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize);
/* Set the size of the guard area created for stack overflow protection. */
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
/* Return in *PARAM the scheduling parameters of *ATTR. */
int pthread_attr_getschedparam(const pthread_attr_t *attr,
struct sched_param *param);
/* Set scheduling parameters (priority, etc) in *ATTR according to PARAM. */
int pthread_attr_setschedparam(pthread_attr_t *attr,
const struct sched_param *param);
/* Return in *POLICY the scheduling policy of *ATTR. */
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);
/* Set scheduling policy in *ATTR according to POLICY. */
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
/* Return in *INHERIT the scheduling inheritance mode of *ATTR. */
int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit);
/* Set scheduling inheritance mode in *ATTR according to INHERIT. */
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit);
/* Return in *SCOPE the scheduling contention scope of *ATTR. */
int pthread_attr_getscope(const pthread_attr_t *attr, int *scope);
/* Set scheduling contention scope in *ATTR according to SCOPE. */
int pthread_attr_setscope(pthread_attr_t *attr, int scope);
/* Return the previously set address for the stack. */
int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr);
/* Set the starting address of the stack of the thread to be created.
Depending on whether the stack grows up or down the value must either
be higher or lower than all the address in the memory block. The
minimal size of the block must be PTHREAD_STACK_MIN. */
int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr);
/* Return the currently used minimal stack size. */
int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize);
/* Add information about the minimum stack size needed for the thread
to be started. This size must never be less than PTHREAD_STACK_MIN
and must also not exceed the system limits. */
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);

View File

@ -1,9 +1,23 @@
/* Functions to handle barriers. */
/**
* @ingroup pthread
*/
#include "mutex.h"
#define PTHREAD_PROCESS_SHARED (0) /**< Share the barrier with child processes (default). */
#define PTHREAD_PROCESS_PRIVATE (1) /**< Do not share the barrier with child processes. */
/**
* @def PTHREAD_PROCESS_SHARED
* @brief Share the structure with child processes (default).
* @note RIOT is a single-process OS.
* Setting the value of `pshared` does not change anything.
*/
#define PTHREAD_PROCESS_SHARED (0)
/**
* @def PTHREAD_PROCESS_SHARED
* @brief Don't share the structure with child processes.
* @note RIOT is a single-process OS.
* Setting the value of `pshared` does not change anything.
*/
#define PTHREAD_PROCESS_PRIVATE (1)
/**
* @brief Internal structure to store the list of waiting threads.
@ -18,13 +32,14 @@ typedef struct pthread_barrier_waiting_node
/**
* @brief A synchronization barrier.
* @details Initialize with pthread_barrier_init().
* For a zeroed out datum you do not need to call the initializer, it is enough to set `count`.
* For a zeroed out datum you do not need to call the initializer,
* it is enough to set pthread_barrier_t::count.
*/
typedef struct pthread_barrier
{
struct pthread_barrier_waiting_node *next; /**< The first waiting thread. */
mutex_t mutex; /**< Mutex to unlock to wake the thread up. */
volatile int count; /**< Wait to N more threads before waking everyone up. */
volatile int count; /**< Wait for N more threads before waking everyone up. */
} pthread_barrier_t;
/**
@ -34,7 +49,7 @@ typedef struct pthread_barrier
*/
typedef struct pthread_barrierattr
{
int pshared; /**< Set pthread_barrierattr_setpshared() and pthread_barrierattr_getpshared(). */
int pshared; /**< See pthread_barrierattr_setpshared() and pthread_barrierattr_getpshared(). */
} pthread_barrierattr_t;
/**
@ -93,7 +108,7 @@ int pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, int *pshar
* @brief Set if the barrier should be shared with child processes
* @details Since RIOT is a single process OS, pthread_barrier_init() wil ignore the value.
* @param attr Attribute set for pthread_barrier_init()
* @param pshared Either PTHREAD_PROCESS_PRIVATE or PTHREAD_PROCESS_SHARED
* @param pshared Either #PTHREAD_PROCESS_PRIVATE or #PTHREAD_PROCESS_SHARED
* @returns 0, the invocation cannot fail
*/
int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared);

View File

@ -0,0 +1,43 @@
/**
* @ingroup pthread
*/
#define PTHREAD_CANCEL_DISABLE 0
#define PTHREAD_CANCEL_ENABLE 1
#define PTHREAD_CANCEL_DEFERRED 0
#define PTHREAD_CANCEL_ASYNCHRONOUS 1
#define PTHREAD_CANCELED ((void *) -2)
/**
* @brief Cancellation point are not supported, yet.
* @param[in] state Unused
* @param[out] oldstate Unused
* @returns `-1`, this invocation fails
*/
int pthread_setcancelstate(int state, int *oldstate);
/**
* @brief Cancellation point are not supported, yet.
* @param[in] type Unused
* @param[out] oldtype Unused
* @returns `-1`, this invocation fails
*/
int pthread_setcanceltype(int type, int *oldtype);
/**
* @brief Tells a pthread that it should exit.
* @note Cancellation points are not supported, yet.
* @details A pthread `th` can call pthread_testcancel().
* If pthread_cancel(th) was called before, it will exit then.
* @param[in] th Pthread to tell that it should cancel.
* @returns `-1`, this invocation fails
*/
int pthread_cancel(pthread_t th);
/**
* @brief Exit the current pthread if pthread_cancel() was called for this thread before.
* @details If pthread_cancel() called before, the current thread exits with with the code #PTHREAD_CANCELED.
*/
void pthread_testcancel(void);

View File

@ -1,9 +1,18 @@
/**
* @ingroup pthread
* @{
* @file
* @brief Cleanup primitives for pthread threads.
* @author René Kijewski <kijewski@inf.fu-berlin.de>
* @}
*/
/**
* @brief Internal structure for pthread_cleanup_push()
*/
typedef struct __pthread_cleanup_datum
{
/** Cleanup handler to call next. */
/** Cleanup handler to call next. */
struct __pthread_cleanup_datum *__next;
/** Cleanup routine to call. */

View File

@ -1,5 +1,8 @@
/* Functions for handling conditional variables. */
typedef unsigned long int pthread_cond_t;
typedef unsigned long int pthread_condattr_t;
/* Initialize condition variable COND using attributes ATTR, or use
the default values if later is NULL. */
int pthread_cond_init(pthread_cond_t *cond,

View File

@ -1,81 +1,91 @@
/* Mutex handling. */
/**
* @ingroup pthread
*/
#include <time.h>
#include "kernel.h"
#include "mutex.h"
/* Initialize a mutex. */
int pthread_mutex_init(pthread_mutex_t *mutex,
const pthread_mutexattr_t *mutexattr);
/**
* @brief Pthread mutexes are quite the same as RIOT mutexes.
* @details Recursive locking is not supported.
* A thread can unlock a mutex even if it does not hold it.
*/
typedef mutex_t pthread_mutex_t;
/* Destroy a mutex. */
/**
* @brief Initialize a mutex.
* @details A zeroed out datum is initialized.
* @param[in,out] mutex Mutex to initialize.
* @param[in] mutexattr Unused.
* @returns `0` on success. `-1` iff `mutex == NULL`.
*/
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
/**
* @brief Destroy a mutex.
* @details This is currently a no-op.
*   Destroying a mutex locked is undefined behavior.
* @param[in,out] mutex Datum to destroy.
* @returns 0, this invocation is a no-op that cannot fail.
*/
int pthread_mutex_destroy(pthread_mutex_t *mutex);
/* Try locking a mutex. */
/**
* @brief Try to lock a mutex.
* @details This function won't block.
* @param[in] mutex Mutex to lock, must be initialized.
* @returns `0` if you hold the mutex now.
* `+1` if the mutex already was locked.
* `-1` if you managed to supply `NULL`.
*/
int pthread_mutex_trylock(pthread_mutex_t *mutex);
/* Lock a mutex. */
/**
* @brief Lock and hold a mutex.
* @details This invocation may block if the mutex was locked.
* @param[in] mutex Mutex to lock, must be initialized.
* @returns `-1` iff you managed to supply `NULL`.
* `0` otherwise, you hold the mutex now.
*/
int pthread_mutex_lock(pthread_mutex_t *mutex);
/* Wait until lock becomes available, or specified time passes. */
int pthread_mutex_timedlock(pthread_mutex_t *mutex,
const struct timespec *abstime);
/**
* @brief Not implemented, yet.
* @details Will cause a linktime error ...
* @param[in] mutex The unused mutex.
* @param[in] abstime The used absolute time.
* @return Well ... you'll get a link time error, so nothing will be returned.
*/
int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime);
/* Unlock a mutex. */
/**
* @brief Unlock a mutex.
* @details It is possible to unlock a mutex that you don't hold.
* It is possible to unlock a mutex that is not held at all.
* The mutex can still be locked afterwards if there were threads queuing for this mutex.
* @param[in] mutex Mutex to unlock, must be initialized.
* @returns `-1` iff you managed to supply `NULL`.
* `0` otherwise.
*/
int pthread_mutex_unlock(pthread_mutex_t *mutex);
/* Get the priority ceiling of MUTEX. */
int pthread_mutex_getprioceiling(const pthread_mutex_t *mutex,
int *prioceiling);
/**
* @brief Not implemented, yet.
* @details Will cause a linktime error ...
* @param[in] mutex The unused mutex.
* @param[out] prioceiling Unused.
* @return Well ... you'll get a link time error, so nothing will be returned.
*/
int pthread_mutex_getprioceiling(const pthread_mutex_t *mutex, int *prioceiling);
/* Set the priority ceiling of MUTEX to PRIOCEILING, return old
priority ceiling value in *OLD_CEILING. */
int pthread_mutex_setprioceiling(pthread_mutex_t *mutex, int prioceiling,
int *old_ceiling);
/* Functions for handling mutex attributes. */
/* Initialize mutex attribute object ATTR with default attributes
(kind is PTHREAD_MUTEX_TIMED_NP). */
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
/* Destroy mutex attribute object ATTR. */
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
/* Get the process-shared flag of the mutex attribute ATTR. */
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr,
int *pshared);
/* Set the process-shared flag of the mutex attribute ATTR. */
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);
/* Return in *KIND the mutex kind attribute in *ATTR. */
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *kind);
/* Set the mutex kind attribute in *ATTR to KIND (either PTHREAD_MUTEX_NORMAL,
PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_ERRORCHECK, or
PTHREAD_MUTEX_DEFAULT). */
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int kind);
/* Return in *PROTOCOL the mutex protocol attribute in *ATTR. */
int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr,
int *protocol);
/* Set the mutex protocol attribute in *ATTR to PROTOCOL (either
PTHREAD_PRIO_NONE, PTHREAD_PRIO_INHERIT, or PTHREAD_PRIO_PROTECT). */
int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol);
/* Return in *PRIOCEILING the mutex prioceiling attribute in *ATTR. */
int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr,
int *prioceiling);
/* Set the mutex prioceiling attribute in *ATTR to PRIOCEILING. */
int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling);
/* Get the robustness flag of the mutex attribute ATTR. */
int pthread_mutexattr_getrobust(const pthread_mutexattr_t *attr,
int *robustness);
/* Set the robustness flag of the mutex attribute ATTR. */
int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr, int robustness);
/**
* @brief Not implemented, yet.
* @details Will cause a linktime error ...
* @param[in,out] mutex The unused mutex.
* @param[in] prioceiling Unused.
* @param[out] old_ceiling Unused.
* @return Well ... you'll get a link time error, so nothing will be returned.
*/
int pthread_mutex_setprioceiling(pthread_mutex_t *mutex, int prioceiling, int *old_ceiling);

View File

@ -0,0 +1,189 @@
#include <errno.h>
/**
* @def PTHREAD_MUTEX_NORMAL
* @brief A non-error correcting mutex (default).
*/
/**
* @def PTHREAD_MUTEX_RECURSIVE
* @brief A mutex that allows recursive locking.
* @note Not implemented, yet.
*/
/**
* @def PTHREAD_MUTEX_ERRORCHECK
* @brief A mutex that fails with `EDEADLK` if recursive locking was detected.
* @note Not implemented, yet.
*/
#define PTHREAD_MUTEX_NORMAL 0
#define PTHREAD_MUTEX_RECURSIVE 1
#define PTHREAD_MUTEX_ERRORCHECK 2
#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
/**
* @def PTHREAD_MUTEX_DEFAULT
* @brief The default mutex kind for RIOT.
* @note Not implemented, yet.
*/
/**
* @def PTHREAD_MUTEX_DEFAULT
* @brief No priority inheritance.
* @details Prone to inversed priorities.
* The default mutex protocol.
*/
/**
* @def PTHREAD_PRIO_INHERIT
* @brief If a thread attempts to acquire a held lock,
* the holding thread gets its dynamic priority increased up to
* the priority of the blocked thread
* @note Not implemented, yet.
*/
#define PTHREAD_PRIO_NONE 0
#define PTHREAD_PRIO_INHERIT 1
/**
* @def PTHREAD_PRIO_PROTECT
* @brief Not implemented, yet.
*/
/**
* @def PTHREAD_MUTEX_STALLED
* @brief Mutexes aren't automatically released on the end of a thread.
* @see #pthread_cleanup_push() for an option to unlock mutexes on the end of a thread.
* @note This is the default.
*/
/**
* @def PTHREAD_MUTEX_ROBUST
* @brief Mutexes that are held at the exit of a thread get released automatically.
* @note Not implemented, yet.
*/
#define PTHREAD_PRIO_PROTECT 2
#define PTHREAD_MUTEX_STALLED 0
#define PTHREAD_MUTEX_ROBUST 1
/**
* @brief This type is unused right now, and only exists for POSIX compatibility.
*/
typedef struct pthread_mutexattr
{
int pshared; /**< Whether to share the mutex with child processes. */
int kind; /**< Type of the mutex. */
int protocol; /**< Priority inheritance of the mutex. */
int robustness; /**< What to do if a thread terminates while it holds a mutex. */
} pthread_mutexattr_t;
/**
* @brief Initialize a pthread_mutexattr_t
* @details A zeroed out datum is initialized
* @note This function is not implemented, yet.
* @param[out] attr Datum to initialize.
* @returns `0` on success.
* `EINVAL` if `attr == NULL`.
*/
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
/**
* @brief Destroys a pthread_mutexattr_t
* @details There is no need to ever call this function.
* This function is a no-op.
* @note This function is not implemented, yet.
* @param[in,out] attr Datum to destroy.
* @returns `0` on success.
* `EINVAL` if `attr == NULL`.
*/
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
/**
* @brief Queries the attribute set whether to share the mutex with child processes.
* @note Since RIOT does not implement processes, this value is unused.
* @param[in] attr Attribute set to query.
* @param[out] pshared Either #PTHREAD_PROCESS_SHARED or #PTHREAD_PROCESS_PRIVATE.
* @returns `0` on success.
* `EINVAL` if `attr` or `pshared` are `NULL`.
*/
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *pshared);
/**
* @brief Set whether to share the mutex with child processes.
* @note Since RIOT does not implement processes, this value is unused.
* @param[in,out] attr Attribute set to change.
* @param[in] pshared Either #PTHREAD_PROCESS_SHARED or #PTHREAD_PROCESS_PRIVATE.
* @returns `0` on success.
* `EINVAL` if `pshared` is neither #PTHREAD_PROCESS_SHARED nor #PTHREAD_PROCESS_PRIVATE.
* `EINVAL` if `attr == NULL`.
*/
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);
/**
* @brief Query the type of the mutex to create.
* @note This implementation only supports PTHREAD_MUTEX_NORMAL mutexes.
* @param[in] attr Attribute set to query.
* @param[out] kind Either #PTHREAD_MUTEX_NORMAL or #PTHREAD_MUTEX_RECURSIVE or #PTHREAD_MUTEX_ERRORCHECK.
* @returns `0` on success.
* `EINVAL` if `attr` or `kind` are `NULL`.
*/
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *kind);
/**
* @brief Sets the type of the mutex to create.
* @note This implementation only supports `PTHREAD_MUTEX_NORMAL` mutexes.
* @param[in,out] attr Attribute set to change.
* @param[in] kind Either #PTHREAD_MUTEX_NORMAL or #PTHREAD_MUTEX_RECURSIVE or #PTHREAD_MUTEX_ERRORCHECK.
* @returns `0` on success.
* `EINVAL` if the value of `kind` is unsupported.
* `EINVAL` if `attr == NULL`.
*/
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int kind);
/**
* @brief Query the priority inheritance of the mutex to create.
* @note This implementation only supports `PTHREAD_PRIO_NONE` mutexes.
* @param[in] attr Attribute set to query
* @param[out] protocol Either #PTHREAD_PRIO_NONE or #PTHREAD_PRIO_INHERIT or #PTHREAD_PRIO_PROTECT.
* @returns `0` on success.
* `EINVAL` if `attr` or `protocol` are `NULL`.
*/
int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr, int *protocol);
/**
* @brief Sets the priority inheritance of the mutex to create.
* @note This implementation only supports `PTHREAD_PRIO_NONE` mutexes.
* @param[in,out] attr Attribute set to change.
* @param[in] protocol Either #PTHREAD_PRIO_NONE or #PTHREAD_PRIO_INHERIT or #PTHREAD_PRIO_PROTECT.
* @returns `0` on success.
* `EINVAL` if the value of `protocol` is unsupported.
* `EINVAL` if `attr == NULL`.
*/
int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol);
/* Return in *PRIOCEILING the mutex prioceiling attribute in *ATTR. */
int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr, int *prioceiling);
/* Set the mutex prioceiling attribute in *ATTR to PRIOCEILING. */
int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling);
/**
* @brief Query the attribute set whether to create a robut mutex.
* @details A "robust" mutex releases gets released automagically if the threads exits while it hold the mutex.
* If the thread is cancellable, only rubust mutex should be held.
* @note This implementation does not support robust mutexes, yet.
* As it doesn't implement cancellation points, yet, this should not pose a problem.
* @param[in] attr Attribute set to query.
* @param[out] robustness Either #PTHREAD_MUTEX_STALLED or #PTHREAD_MUTEX_ROBUST.
* @returns `0` on success.
* `EINVAL` if the value of `protocol` is unsupported.
* `EINVAL` if `attr` or `robustness` is `NULL`.
*/
int pthread_mutexattr_getrobust(const pthread_mutexattr_t *attr, int *robustness);
/**
* @brief Set whether the mutex to create should be robust.
* @details A "robust" mutex releases gets released automagically if the threads exits while it hold the mutex.
* If the thread is cancellable, only rubust mutex should be held.
* @note This implementation does not support robust mutexes, yet.
* As it doesn't implement cancellation points, yet, this should not pose a problem.
* @param[in,out] attr Attribute set to change.
* @param[in] robustness Either #PTHREAD_MUTEX_STALLED or #PTHREAD_MUTEX_ROBUST.
* @returns `0` on success.
* `EINVAL` if the value of `robustness` is unsupported.
* `EINVAL` if `attr == NULL`.
*/
int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr, int robustness);

View File

@ -0,0 +1,26 @@
/**
* @ingroup pthread
*/
/**
* @brief Datatype to supply to pthread_once().
*/
typedef volatile int pthread_once_t;
/**
* @def PTHREAD_ONCE_INIT
* @brief Initialization for pthread_once_t.
* @details A zeroed out pthread_once_t is initialized.
*/
#define PTHREAD_ONCE_INIT 0
/**
* @brief Helper function that ensures that `init_routine` is called at once.
* @details Calling pthread_once() changes `once_control`.
* For the same `once_control` the supplied `init_routine` won't get called again,
* unless `once_control` is reset to `PTHREAD_ONCE_INIT` or zeroed out.
* @param[in,out] once_control Flag to ensure that the `init_routine` is called only once.
* @param[in] init_routine Function to call if `once_control` was not used, yet.
* @returns 0, this invocation cannot fail.
*/
int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));

View File

@ -1,4 +1,9 @@
/* Functions for handling read-write locks. */
/**
* @ingroup pthread
*/
typedef unsigned long int pthread_rwlock_t;
typedef unsigned long int pthread_rwlockattr_t;
/* Initialize read-write lock RWLOCK using attributes ATTR, or use
the default values if later is NULL. */

View File

@ -0,0 +1,32 @@
/**
* @ingroup pthread
*/
/**
* @brief Unimplemented.
* @note Due to the native of RIOT it is unlikely that this function will ever be implemented.
* @param[in] target_thread Unused
* @param[in] policy Unused
* @param[in] param Unused
* @returns The function is unimplemented. Using it will cause a link time error.
*/
int pthread_setschedparam(pthread_t target_thread, int policy, const struct sched_param *param);
/**
* @brief Unimplemented.
* @note Due to the native of RIOT it is unlikely that this function will ever be implemented.
* @param[in] target_thread Unused
* @param[in,out] policy Unused
* @param[out] param Unused
* @returns The function is unimplemented. Using it will cause a link time error.
*/
int pthread_getschedparam(pthread_t target_thread, int *policy, struct sched_param *param);
/**
* @brief Unimplemented.
* @note Due to the native of RIOT it is unlikely that this function will ever be implemented.
* @param[in] target_thread Unused
* @param[in] prio Unused
* @returns The function is unimplemented. Using it will cause a link time error.
*/
int pthread_setschedprio(pthread_t target_thread, int prio);

View File

@ -1,4 +1,8 @@
/* Functions to handle spinlocks. */
/**
* @ingroup pthread
*/
typedef volatile int pthread_spinlock_t;
/* Initialize the spinlock LOCK. If PSHARED is nonzero the spinlock can
be shared between different processes. */

View File

@ -0,0 +1,85 @@
/**
* @ingroup pthread
*/
#include "attributes.h"
/**
* @brief Datatype to identify a POSIX thread.
* @note The pthread ids are one off to the index in the internal array.
*/
typedef unsigned pthread_t;
/**
* @brief Spawn a new POSIX thread.
* @details This functions starts a new thread.
* The thread will be joinable (from another pthread),
* unless `attr` tells to create the thread detached.
* A non-detached thread must be joined will stay a zombie into it is joined.
* You can call pthread_exit() inside the thread, or return from `start_routine()`.
* @note Cancellation is currently not implemented.
* @note In an embedded system you probably want to supply a statically allocated stack in `attr`.
* @param[out] newthread The identifier of the new thread.
* @param[in] attr An attribute set that describes how the new thread should be started.
* @param[in] start_routine The entry point of the new thread.
* @param[in] arg Argument supplied to `start_routine`.
* @return `== 0` on success.
* `!= 0` on error.
*/
int pthread_create(pthread_t *newthread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
/**
* @brief Exit calling pthread.
* @note Only pthreads must call this function.
* Native threads must call sched_thread_exit().
* A pthread must not call sched_thread_exit().
* @param[out] retval Return value, supplied to a joining thread.
* @return This function does not return.
*/
void pthread_exit(void *retval) NORETURN;
/**
* @brief Join a pthread.
* @details The current thread sleeps until `th` exits.
* The exit value of `th` gets written into `thread_return`.
* You can only join pthreads, and only pthreads can join.
* A thread must not join itself.
* @param[in] th pthread to join, the id was supplied by pthread_create()
* @param[out] thread_return Exit code of `th`.
* @return `== 0` on success.
* `!= 0` on error.
*/
int pthread_join(pthread_t th, void **thread_return);
/**
* @brief Make a pthread unjoinable.
* @details The resources of a detached thread get released as soon as it exits,
* without the need to call pthread_join() out of another pthread.
* In fact you cannot join a detached thread, it will return an error.
* Detaching a thread while another thread tries to join it causes undefined behavior.
* A pthread may detach himself.
* A non-pthread may call this function, too.
* A pthread cannot be "attached" again.
* @param[in] th pthread to detach.
* @return `== 0` on success.
* `!= 0` on error.
*/
int pthread_detach(pthread_t th);
/**
* @brief Returns the pthread id of the calling/current thread.
* @note This function should not be used to determine if the calling thread is a pthread.
* If your logic is sane then there should be no need to do that.
* @return `> 0` identifies the calling pthread.
* `== 0` if the calling thread is not a pthread.
*/
pthread_t pthread_self(void);
/**
* @brief Compared two pthread identifiers.
* @return `0` if the ids identify two different threads.
*/
static inline int pthread_equal(pthread_t thread1, pthread_t thread2)
{
return thread1 == thread2;
}

View File

@ -0,0 +1,183 @@
/**
* @ingroup pthread
*/
/**
* @brief An attribute set to supply to pthread_create()
* @details A zeroed out datum is default initiliazed.
* @see pthread_create() for further information
*/
typedef struct pthread_attr
{
uint8_t detached; /**< Start in detached state. */
char *ss_sp; /**< Stack to use for new thread. */
size_t ss_size; /**< Size of dynamically allocated stack, or supplied stack, resp. */
} pthread_attr_t;
/**
* @brief This structure is unused right now, and only exists for POSIX compatibility.
*/
struct sched_param {
int todo; /* TODO */
};
#define PTHREAD_CREATE_JOINABLE (0) /**< Create new pthread as joinable (default). */
#define PTHREAD_CREATE_DETACHED (1) /**< Create new pthread in detached state. */
/**
* @brief Initialize attributes for a new pthread.
* @see pthread_create()
* @details A zeroed out `attr` is initialized.
* @param[in,out] attr Structure to initialize
* @returns 0, invocation cannot fail
*/
int pthread_attr_init(pthread_attr_t *attr);
/**
* @brief Destroys an attribute set.
* @details Since pthread_attr_t does not hold dynamic data, this is a no-op.
* @returns 0, since this a no-op that cannot fail
*/
int pthread_attr_destroy(pthread_attr_t *attr);
/**
* @brief Tells whether to create a new pthread in a detached state.
* @param[in] attr Attribute set to query.
* @param[out] detachstate Either PTHREAD_CREATE_JOINABLE or PTHREAD_CREATE_DETACHED.
* @returns 0, the invocation cannot fail
*/
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
/**
* @brief Sets whether to create a new pthread in a detached state.
* @note Supplying a value different form PTHREAD_CREATE_JOINABLE or PTHREAD_CREATE_DETACHED
* causes undefined behavior.
* @param[in,out] attr Attribute set to operate on.
* @param[in] detachstate Either PTHREAD_CREATE_JOINABLE or PTHREAD_CREATE_DETACHED.
* @returns `0` on success.
* `-1` if you managed to supply an illegal value in `detachstate`.
*/
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
/**
* @brief This function is unused right now, and only exists for POSIX compatibility.
* @param[in] attr Unused
* @param[out] guardsize Unused
* @returns -1, this function fails
*/
int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize);
/**
* @brief This function is unused right now, and only exists for POSIX compatibility.
* @param[in,out] attr Unused
* @param[in] guardsize Unused
* @returns -1, this function fails
*/
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
/**
* @brief This function is unused right now, and only exists for POSIX compatibility.
* @param[in] attr Unused
* @param[out] param Unused
* @returns -1, this function fails
*/
int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);
/**
* @brief This function is unused right now, and only exists for POSIX compatibility.
* @param[in,out] attr Unused
* @param[in] param Unused
* @returns -1, this function fails
*/
int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);
/**
* @brief This function is unused right now, and only exists for POSIX compatibility.
* @param[in] attr Unused
* @param[out] policy Unused
* @returns -1, this function fails
*/
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);
/**
* @brief This function is unused right now, and only exists for POSIX compatibility.
* @param[in,out] attr Unused
* @param[in] policy Unused
* @returns -1, this function fails
*/
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
/**
* @brief This function is unused right now, and only exists for POSIX compatibility.
* @param[in] attr Unused
* @param[out] inherit Unused
* @returns -1, this function fails
*/
int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit);
/**
* @brief This function is unused right now, and only exists for POSIX compatibility.
* @param[in,out] attr Unused
* @param[in] inherit Unused
* @returns -1, this function fails
*/
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit);
/**
* @brief This function is unused right now, and only exists for POSIX compatibility.
* @param[in] attr Unused
* @param[out] scope Unused
* @returns -1, this function fails
*/
int pthread_attr_getscope(const pthread_attr_t *attr, int *scope);
/**
* @brief This function is unused right now, and only exists for POSIX compatibility.
* @param[in,out] attr Unused
* @param[in] scope Unused
* @returns -1, this function fails
*/
int pthread_attr_setscope(pthread_attr_t *attr, int scope);
/**
* @brief Query assigned stack for new pthread.
* @see pthread_attr_setstackaddr() for more information
* @param[in] attr Attribute set to query
* @param[out] stackaddr Pointer to previously assigned stack, or `NULL` for dynamic allocation.
* @returns 0, this invocation cannot fail
*/
int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr);
/**
* @brief Set address of the stack to use for the new pthread.
* @details If `*stackaddr == NULL`, then the stack is dynamically allocated with malloc().
* No two running threads may operate on the same stack.
* The stack of a zombie thread (i.e. a non-detached thread that exited but was not yet joined)
* may in theory be reused even before joining, though there might be problems
* if the stack was preempted before pthread_exit() completed.
* @param[in,out] attr Attribute set to operate on.
* @param[in] stackaddr Static stack to use, or `NULL` for dynamic allocation.
* @returns 0, this invocation cannot fail
*/
int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr);
/**
* @brief Query set stacksize for new pthread.
* @details Returns default stack size of the value is yet unset.
* @param[in] attr Attribute set to query.
* @param[out] stacksize Assigned or default stack size, resp.
* @returns 0, this invocation cannot fail
*/
int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize);
/**
* @brief Set the stack size for the new pthread.
* @details If you use pthread_attr_getstackaddr() to assign a static stack,
* then you must use this function to set the size of the stack.
* In case of dynamic memory allocation this overrules the default value.
* @param[in,out] attr Attribute set to operate on
* @param[in] stacksize Size of the stack of the new thread.
* Supply `0` to use the default value.
* @return 0, this invocation cannot fail.
*/
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);

View File

@ -1,33 +0,0 @@
#ifndef PTHREADTYPES_H_
#define PTHREADTYPES_H_
typedef unsigned long int pthread_t;
typedef struct pthread_attr
{
uint8_t detached;
char *ss_sp;
size_t ss_size;
} pthread_attr_t;
struct sched_param {
int todo; /* TODO */
};
/* Once-only execution */
typedef int pthread_once_t;
/* Single execution handling. */
#define PTHREAD_ONCE_INIT 0
typedef unsigned long int pthread_cond_t;
typedef unsigned long int pthread_condattr_t;
typedef mutex_t pthread_mutex_t;
typedef unsigned long int pthread_mutexattr_t;
typedef unsigned long int pthread_rwlock_t;
typedef unsigned long int pthread_rwlockattr_t;
typedef volatile int pthread_spinlock_t;
#endif /* PTHREADTYPES_H_ */

View File

@ -1,16 +1,19 @@
/**
* POSIX implementation of threading.
*
/*
* Copyright (C) 2013 Freie Universität Berlin
*
* This file subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*
*/
/**
* @defgroup pthread POSIX threads
* POSIX conforming multi-threading features.
* @ingroup posix
* @{
* @file pthread.c
* @brief Implementation of pthread.
* @file
* @brief Thread creation features.
* @see [The Open Group Base Specifications Issue 7: pthread.h - threads](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html)
* @author Christian Mehlis <mehlis@inf.fu-berlin.de>
* @author René Kijewski <kijewski@inf.fu-berlin.de>
* @}
@ -254,11 +257,6 @@ pthread_t pthread_self(void)
return result;
}
int pthread_equal(pthread_t thread1, pthread_t thread2)
{
return (thread1 == thread2);
}
int pthread_cancel(pthread_t th)
{
pthread_thread_t *other = pthread_sched_threads[th-1];
@ -275,21 +273,21 @@ int pthread_setcancelstate(int state, int *oldstate)
{
(void) state;
(void) oldstate;
return 0;
return -1;
}
int pthread_setcanceltype(int type, int *oldtype)
{
(void) type;
(void) oldtype;
return 0;
return -1;
}
void pthread_testcancel(void)
{
pthread_t self = pthread_self();
if (pthread_sched_threads[self-1]->should_cancel) {
pthread_exit(NULL);
pthread_exit(PTHREAD_CANCELED);
}
}

View File

@ -1,16 +1,16 @@
/**
* POSIX implementation of threading.
*
/*
* Copyright (C) 2013 Freie Universität Berlin
*
* This file subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*
* @ingroup posix
*/
/**
* @ingroup pthread
* @{
* @file pthread.c
* @brief Implementation of pthread.
* @file
* @brief Thread creation attributes.
* @author Christian Mehlis <mehlis@inf.fu-berlin.de>
* @author René Kijewski <kijewski@inf.fu-berlin.de>
* @}
@ -147,6 +147,9 @@ int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
{
*stacksize = attr->ss_size;
if (*stacksize == 0) {
/* FIXME: the standard says that this function should return the default value if no explicit value was set. */
}
return 0;
}

View File

@ -1,19 +1,21 @@
/*
* POSIX compatible implementation of barriers.
*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*/
/**
* POSIX compatible implementation of barriers.
*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*
* @ingroup posix
* @{
* @file
* @brief Implementation of the pthread barrier.
* @author René Kijewski <kijewski@inf.fu-berlin.de>
* @}
*/
* @ingroup pthread
* @{
* @file
* @brief Synchronization barriers.
* @author René Kijewski <kijewski@inf.fu-berlin.de>
* @}
*/
#include "sched.h"
#include "pthread.h"

View File

@ -1,19 +1,21 @@
/*
* POSIX compatible implementation of barriers.
*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*/
/**
* POSIX compatible implementation of barriers.
*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*
* @ingroup posix
* @{
* @file
* @brief Implementation of the pthread barrier attributes.
* @author René Kijewski <kijewski@inf.fu-berlin.de>
* @}
*/
* @ingroup pthread
* @{
* @file
* @brief Attributes for synchronization barriers.
* @author René Kijewski <kijewski@inf.fu-berlin.de>
* @}
*/
#include "pthread.h"

View File

@ -1,16 +1,16 @@
/**
* POSIX implementation of threading.
*
/*
* Copyright (C) 2013 Freie Universität Berlin
*
* This file subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*
* @ingroup posix
*/
/**
* @ingroup pthread
* @{
* @file pthread.c
* @brief Implementation of pthread.
* @file
* @brief Mutual exclusion.
* @author Christian Mehlis <mehlis@inf.fu-berlin.de>
* @author René Kijewski <kijewski@inf.fu-berlin.de>
* @}
@ -45,7 +45,9 @@ int pthread_mutex_trylock(pthread_mutex_t *mutex)
return -1;
}
return (mutex_trylock(mutex) != 0);
/* mutex_trylock() returns 1 on success, and 0 otherwise. */
/* We want the reverse. */
return 1 - mutex_trylock(mutex);
}
int pthread_mutex_lock(pthread_mutex_t *mutex)

View File

@ -0,0 +1,151 @@
/*
* Copyright (C) 2014 René Kijewski <rene.kijewski@fu-berlin.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @ingroup pthread
* @{
* @file
* @brief Attributes for pthread mutexes.
* @author René Kijewski <rene.kijewski@fu-berlin.de>
* @}
*/
#include "pthread.h"
#include <string.h>
int pthread_mutexattr_init(pthread_mutexattr_t *attr)
{
if (attr == NULL) {
return EINVAL;
}
memset(attr, 0, sizeof (*attr));
return 0;
}
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
{
if (attr == NULL) {
return EINVAL;
}
(void) attr;
return 0;
}
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *pshared)
{
if (attr == NULL || pshared == NULL) {
return EINVAL;
}
*pshared = attr->pshared;
return 0;
}
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared)
{
if (attr == NULL || (pshared != PTHREAD_PROCESS_SHARED &&
pshared != PTHREAD_PROCESS_PRIVATE)) {
return EINVAL;
}
attr->pshared = pshared;
return 0;
}
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *kind)
{
if (attr == NULL || kind == NULL) {
return EINVAL;
}
*kind = attr->kind;
return 0;
}
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int kind)
{
if (attr == NULL || (kind != PTHREAD_MUTEX_NORMAL &&
kind != PTHREAD_MUTEX_RECURSIVE &&
kind != PTHREAD_MUTEX_ERRORCHECK)) {
return EINVAL;
}
if (kind != PTHREAD_MUTEX_NORMAL) {
/* only "normal" mutexes are implemented, yet */
return EINVAL;
}
attr->kind = kind;
return 0;
}
int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr, int *protocol)
{
if (attr == NULL || protocol == NULL) {
return EINVAL;
}
*protocol = attr->protocol;
return 0;
}
int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol)
{
if (attr == NULL || (protocol != PTHREAD_PRIO_NONE &&
protocol != PTHREAD_PRIO_INHERIT &&
protocol != PTHREAD_PRIO_PROTECT)) {
return EINVAL;
}
if (protocol != PTHREAD_PRIO_NONE) {
/* priority inheritance is not supported, yet */
return EINVAL;
}
attr->protocol = protocol;
return 0;
}
int pthread_mutexattr_getrobust(const pthread_mutexattr_t *attr, int *robustness)
{
if (attr == NULL || robustness == NULL) {
return EINVAL;
}
*robustness = attr->robustness;
return 0;
}
int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr, int robustness)
{
if (attr == NULL || (robustness != PTHREAD_MUTEX_STALLED &&
robustness != PTHREAD_MUTEX_ROBUST)) {
return EINVAL;
}
if (robustness != PTHREAD_MUTEX_STALLED) {
/* robust mutexes are not supported, yet */
return EINVAL;
}
attr->robustness = robustness;
return 0;
}

View File

@ -1,4 +1,4 @@
/**
/*
* POSIX implementation of threading.
*
* Copyright (C) 2013 Freie Universität Berlin
@ -6,11 +6,13 @@
* This file subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*
* @ingroup posix
*/
/**
* @ingroup pthread
* @{
* @file pthread.c
* @brief Implementation of pthread.
* @file
* @brief Singletons features / single-shot execution.
* @author Christian Mehlis <mehlis@inf.fu-berlin.de>
* @author René Kijewski <kijewski@inf.fu-berlin.de>
* @}

View File

@ -1,16 +1,16 @@
/**
* POSIX implementation of threading.
*
/*
* Copyright (C) 2013 Freie Universität Berlin
*
* This file subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*
* @ingroup posix
*/
/**
* @ingroup pthread
* @{
* @file pthread.c
* @brief Implementation of pthread.
* @file
* @brief Spin locks.
* @author Christian Mehlis <mehlis@inf.fu-berlin.de>
* @author René Kijewski <kijewski@inf.fu-berlin.de>
* @}