299 lines
9.2 KiB
C
299 lines
9.2 KiB
C
/*
|
|
* Copyright(c) 2006 to 2022 ZettaScale Technology and others
|
|
*
|
|
* This program and the accompanying materials are made available under the
|
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
|
* v. 1.0 which is available at
|
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
|
*
|
|
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
|
*/
|
|
/**
|
|
* @file threads.h
|
|
* @brief Thread management and creation.
|
|
*
|
|
* Platform independent interface for managing and creating execution threads.
|
|
*/
|
|
#ifndef DDSRT_THREADS_H
|
|
#define DDSRT_THREADS_H
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
#include "dds/config.h"
|
|
#include "dds/export.h"
|
|
#include "dds/ddsrt/attributes.h"
|
|
#include "dds/ddsrt/retcode.h"
|
|
#include "dds/ddsrt/sched.h"
|
|
|
|
#if DDSRT_WITH_FREERTOS
|
|
#include "dds/ddsrt/threads/freertos.h"
|
|
#elif _WIN32
|
|
#include "dds/ddsrt/threads/windows.h"
|
|
#else
|
|
#include "dds/ddsrt/threads/posix.h"
|
|
#endif
|
|
|
|
#if defined (__cplusplus)
|
|
extern "C" {
|
|
#endif
|
|
|
|
#if defined(_MSC_VER) || __MINGW__
|
|
/* Thread-local storage using __declspec(thread) on Windows versions before
|
|
Vista and Server 2008 works in DLLs if they are bound to the executable,
|
|
it does not work if the library is loaded using LoadLibrary. */
|
|
#define ddsrt_thread_local __declspec(thread)
|
|
#elif defined(__GNUC__) || (defined(__clang__) && __clang_major__ >= 2)
|
|
/* GCC supports Thread-local storage for x86 since version 3.3. Clang
|
|
supports Thread-local storage since version 2.0. */
|
|
/* VxWorks 7 supports __thread for both GCC and DIAB, older versions may
|
|
support it as well, but that is not verified. */
|
|
#define ddsrt_thread_local __thread
|
|
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
|
#define ddsrt_thread_local __thread
|
|
#else
|
|
#error "Thread-local storage is not supported"
|
|
#endif
|
|
|
|
/**
|
|
* @brief Definition for a thread routine invoked on thread create.
|
|
*/
|
|
typedef uint32_t (*ddsrt_thread_routine_t)(void*);
|
|
|
|
/**
|
|
* @brief Definition of the thread attributes
|
|
*/
|
|
typedef struct {
|
|
/** Specifies the scheduling class */
|
|
ddsrt_sched_t schedClass;
|
|
/** Specifies the thread priority */
|
|
int32_t schedPriority;
|
|
/** Specifies the thread stack size */
|
|
uint32_t stackSize;
|
|
} ddsrt_threadattr_t;
|
|
|
|
/**
|
|
* @brief Initialize thread attributes to platform defaults.
|
|
*/
|
|
DDS_EXPORT void
|
|
ddsrt_threadattr_init(
|
|
ddsrt_threadattr_t *attr)
|
|
ddsrt_nonnull_all;
|
|
|
|
/**
|
|
* @brief Create a new thread.
|
|
*
|
|
* Creates a new thread of control that executes concurrently with
|
|
* the calling thread. The new thread applies the function start_routine
|
|
* passing it arg as first argument.
|
|
*
|
|
* The new thread terminates by returning from the start_routine function.
|
|
* The created thread is identified by the returned threadId.
|
|
*
|
|
* @param[out] thread Location where thread id is stored.
|
|
* @param[in] name Name assigned to created thread.
|
|
* @param[in] attr Attributes to create thread with.
|
|
* @param[in] start_routine Function to execute in created thread.
|
|
* @param[in] arg Argument passed to @start_routine.
|
|
*
|
|
* @returns A dds_return_t indicating success or failure.
|
|
*
|
|
* @retval DDS_RETCODE_OK
|
|
* Thread successfully created.
|
|
* @retval DDS_RETCODE_ERROR
|
|
* Thread could not be created.
|
|
*/
|
|
DDS_EXPORT dds_return_t
|
|
ddsrt_thread_create(
|
|
ddsrt_thread_t *thread,
|
|
const char *name,
|
|
const ddsrt_threadattr_t *attr,
|
|
ddsrt_thread_routine_t start_routine,
|
|
void *arg)
|
|
ddsrt_nonnull((1,2,3,4));
|
|
|
|
/**
|
|
* @brief Retrieve integer representation of the given thread id.
|
|
*
|
|
* @returns The integer representation of the current thread.
|
|
*/
|
|
DDS_EXPORT ddsrt_tid_t
|
|
ddsrt_gettid(void);
|
|
|
|
/**
|
|
* @brief Retrieve integer representation of the given thread id.
|
|
*
|
|
* @returns The integer representation of the given thread.
|
|
*/
|
|
DDS_EXPORT ddsrt_tid_t
|
|
ddsrt_gettid_for_thread( ddsrt_thread_t thread);
|
|
|
|
|
|
/**
|
|
* @brief Return thread ID of the calling thread.
|
|
*
|
|
* @returns Thread ID of the calling thread.
|
|
*/
|
|
DDS_EXPORT ddsrt_thread_t
|
|
ddsrt_thread_self(void);
|
|
|
|
/**
|
|
* @brief Compare thread identifiers.
|
|
*
|
|
* @returns true if thread ids match, otherwise false.
|
|
*/
|
|
DDS_EXPORT bool
|
|
ddsrt_thread_equal(ddsrt_thread_t t1, ddsrt_thread_t t2);
|
|
|
|
/**
|
|
* @brief Wait for termination of the specified thread.
|
|
*
|
|
* If the specified thread is still running, wait for its termination
|
|
* else return immediately. In thread_result it returns the exit status
|
|
* of the thread. If NULL is passed for @thread_result, no exit status is
|
|
* returned, but ddsrt_thread_join still waits for the thread to terminate.
|
|
*
|
|
* @param[in] thread Id of thread to wait for.
|
|
* @param[out] thread_result Location where thread result is stored.
|
|
*
|
|
* @returns A dds_return_t indicating success or failure.
|
|
*
|
|
* @retval DDS_RETCODE_OK
|
|
* Target thread terminated.
|
|
* @retval DDS_RETCODE_ERROR
|
|
* An error occurred while waiting for the thread to terminate.
|
|
*/
|
|
DDS_EXPORT dds_return_t
|
|
ddsrt_thread_join(
|
|
ddsrt_thread_t thread,
|
|
uint32_t *thread_result);
|
|
|
|
/**
|
|
* @brief Get name of current thread.
|
|
*
|
|
* @param[in] name Buffer where the name is copied to.
|
|
* @param[in] size Number of bytes available in the buffer.
|
|
*
|
|
* @returns The number of bytes (excluding the null terminating bytes) that
|
|
* are written. If the buffer is not sufficiently large enough, the
|
|
* name is truncated and the number of bytes that would have been
|
|
* written is returned.
|
|
*/
|
|
DDS_EXPORT size_t
|
|
ddsrt_thread_getname(
|
|
char *__restrict name,
|
|
size_t size);
|
|
|
|
/**
|
|
* @brief Set name of current thread.
|
|
*
|
|
* Set name of the current thread to @name. If the name is longer than the
|
|
* platform maximum, it is silently truncated.
|
|
*
|
|
* @param[in] name Name for current thread.
|
|
*/
|
|
#if DDSRT_HAVE_THREAD_SETNAME
|
|
DDS_EXPORT void
|
|
ddsrt_thread_setname(
|
|
const char *__restrict name);
|
|
#endif
|
|
|
|
#if DDSRT_HAVE_THREAD_LIST
|
|
/**
|
|
* @brief Get a list of threads in the calling process
|
|
*
|
|
* @param[out] tids Array of size elements to be filled with thread
|
|
* identifiers, may be NULL if size is 0
|
|
* @param[in] size The size of the tids array; 0 is allowed
|
|
*
|
|
* @returns A dds_return_t indicating the number of threads in the process
|
|
* or an error code on failure.
|
|
*
|
|
* @retval > 0
|
|
* Number of threads in the process, may be larger than size
|
|
* tids[0 .. (return - 1)] are valid
|
|
* @retval DDS_RETCODE_ERROR
|
|
* Something went wrong, contents of tids is undefined
|
|
* @retval DDS_RETCODE_UNSUPPORTED
|
|
* Not supported on the platform
|
|
*/
|
|
DDS_EXPORT dds_return_t ddsrt_thread_list (ddsrt_thread_list_id_t * __restrict tids, size_t size);
|
|
|
|
/**
|
|
* @brief Get the name of the specified thread (in the calling process)
|
|
*
|
|
* @param[in] tid Thread identifier for which the name is sought
|
|
* @param[out] name Filled with the thread name (or a synthesized one)
|
|
* on successful return; name is silently truncated
|
|
* if the actual name is longer than name can hold;
|
|
* always 0-terminated if size > 0
|
|
* @param[in] size Number of bytes of name that may be assigned, size
|
|
* is 0 is allowed, though somewhat useless
|
|
*
|
|
* @returns A dds_return_t indicating success or failure.
|
|
*
|
|
* @retval DDS_RETCODE_OK
|
|
* Possibly truncated name is returned as a null-terminated
|
|
* string in name (provided size > 0).
|
|
* @retval DDS_RETCODE_NOT_FOUND
|
|
* Thread not found; the contents of name is unchanged
|
|
* @retval DDS_RETCODE_ERROR
|
|
* Unspecified failure, the contents of name is undefined
|
|
* @retval DDS_RETCODE_UNSUPPORTED
|
|
* Not supported on the platform
|
|
*/
|
|
DDS_EXPORT dds_return_t ddsrt_thread_getname_anythread (ddsrt_thread_list_id_t tid, char *__restrict name, size_t size);
|
|
#endif
|
|
|
|
/**
|
|
* @brief Push cleanup handler onto the cleanup stack
|
|
*
|
|
* Push a cleanup handler onto the top of the calling thread's cleanup
|
|
* stack. The cleanup handler will be popped of the thread's cleanup stack
|
|
* and invoked with the specified argument when the thread exits.
|
|
*
|
|
* @param[in] routine Cleanup handler to push onto the thread cleanup stack.
|
|
* @param[in] arg Argument that will be passed to the cleanup handler.
|
|
*/
|
|
DDS_EXPORT dds_return_t
|
|
ddsrt_thread_cleanup_push(
|
|
void (*routine)(void*),
|
|
void *arg);
|
|
|
|
/**
|
|
* @brief Pop cleanup handler from the top of the cleanup stack
|
|
*
|
|
* Remove routine at the top of the calling thread's cleanup stack and
|
|
* optionally invoke it (if execute is non-zero).
|
|
*/
|
|
DDS_EXPORT dds_return_t
|
|
ddsrt_thread_cleanup_pop(
|
|
int execute);
|
|
|
|
/**
|
|
* @brief Initialize thread internals.
|
|
*
|
|
* Initialize internals for threads not created with @ddsrt_create_thread. By
|
|
* default initialization is done automatically.
|
|
*/
|
|
DDS_EXPORT void
|
|
ddsrt_thread_init(uint32_t reason);
|
|
|
|
/**
|
|
* @brief Free thread resources and execute cleanup handlers.
|
|
*
|
|
* Platforms that support it, automatically free resources claimed by the
|
|
* current thread and call any registered cleanup routines. This function only
|
|
* needs to be called on platforms that do not support thread destructors and
|
|
* only for threads that were not created with @ddsrt_thread_create.
|
|
*/
|
|
DDS_EXPORT void
|
|
ddsrt_thread_fini(uint32_t reason);
|
|
|
|
#if defined (__cplusplus)
|
|
}
|
|
#endif
|
|
|
|
#endif /* DDSRT_THREADS_H */
|