Add missing doxygen for pthread funs and structs
parent
f2e28c8146
commit
3e6bebadd3
@ -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 */
|
||||
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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));
|
@ -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);
|
@ -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;
|
||||
}
|
@ -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);
|
@ -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_ */
|
@ -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;
|
||||
}
|
||||