Files
qt6-migration-pipeline/external/rti_connext_dds-7.7.0/include/ndds/osapi/osapi_thread.h
T
torstenandCopilot 342ffd3e5c Update submodule to latest BUILD_RTI fixes
- HandlerMinelayerData: BUILD_RTI Guards für RTI-Abhängigkeiten
- svcTabCommon: Export-Header-Fix via Fallback-Target
- TrainingAreaBase: Stub-Header für BUILD_RTI=OFF
- ddsfts: Include-Pfad und Dependency-Fixes
- BUILD_RTI=OFF Compilation vollständig unterstützt

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Entire-Checkpoint: 01M0JNZA586SACX1PRZ2DJAE5S
2026-08-21 19:30:20 +02:00

1243 lines
44 KiB
C

/*
* (c) Copyright, Real-Time Innovations, 2003-2024.
* All rights reserved.
*
* No duplications, whole or partial, manual or electronic, may be made
* without express written permission. Any such copies, or
* revisions thereof, must display this notice unaltered.
* This code contains trade secrets of Real-Time Innovations, Inc.
*/
#ifndef osapi_thread_h
#define osapi_thread_h
#include "osapi/osapi_ntptime.h"
#include "osapi/osapi_dll.h"
#include "log/log_common.h"
#include "osapi/osapi_cpu.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @internal \file
* \brief thread related utility
*/
/** @internal \defgroup RTIOsapiThreadClass RTIOsapiThread
* \ingroup RTIOsapiModule
*
* \brief OS independent encapsulation of an application thread.
*/
struct RTIOsapiThread;
/** @internal
* \defgroup RTIOsapiJoinableThreadClass RTIOsapiThread
* \ingroup RTIOsapiModule
*
* \brief A class that inherits from RTIOsapiThread and has special
* capabilities:
* - Ability to stop the execution of the thread and delete it.
* A JoinableThread will create a semaphore to synchronize the deletion of the
* thread. When the user calls RTIOsapiJoinableThread_stopAndDelete, the
* semaphore will wait until the thead finish its spawn method.
* - The thread has a worker associated.
* The method RTIOsapiJoinableThread_new will create a worker and associate it
* to the thread.
*
* More info in confluence: Engineering aka R&D-> R&D Teams -> General Purpose
* Products -> Developer knowledge Base -> Concurrency -> Thread ->
* JoinableThread
*/
struct RTIOsapiJoinableThread;
/** @internal \ingroup RTIOsapiThreadClass
Use only the default options the OS gives you.
*/
#define RTI_OSAPI_THREAD_OPTION_DEFAULT 0x00
/** @internal \ingroup RTIOsapiThreadClass
Support floating point.
*/
#define RTI_OSAPI_THREAD_OPTION_FLOATING_POINT 0x01
/** @internal \ingroup RTIOsapiThreadClass
This thread can do standard io.
*/
#define RTI_OSAPI_THREAD_OPTION_STDIO 0x02
/** @internal \ingroup RTIOsapiThreadClass
This thread will run in real-time priority mode.
*/
#define RTI_OSAPI_THREAD_OPTION_REALTIME_PRIORITY 0x08
/** @internal \ingroup RTIOsapiThreadClass
Insist on the specified priority and fail if OS doesn't like it.
*/
#define RTI_OSAPI_THREAD_OPTION_PRIORITY_ENFORCE 0x10
/** @internal \ingroup RTIOsapiThreadClass
Set the flag to be able to asynchronously cancel thread.
*/
#define RTI_OSAPI_THREAD_OPTION_CANCEL_ASYNCHRONOUS 0x20
/** @internal \ingroup RTIOsapiThreadClass
*
* TESTING ONLY. Skip the creation of the Context Tss in the
* onSpawned method. This option is used to test automatic TSS
* cleanup. This option lets us create threads in tests more
* closely to how a user may create threads in their
* applications (e.g. using calls directly to pthread_create
* instead of through our wrapper APIs). Our wrapper APIs make
* sure that state is cleaned up properly when they are used,
* but we want to test that the state is also cleaned up when
* our wrappers are not used.
*/
#define RTI_OSAPI_THREAD_OPTION_SKIP_CONTEXT_CREATION 0x40
/** @internal \ingroup RTIOsapiThreadClass
Indicates to create the thread with the OS default stack size. If not
supported, will use the platform default.
*/
#define RTI_OSAPI_THREAD_STACK_SIZE_OS_DEFAULT (-1)
#if defined(RTI_VXWORKS)
typedef enum {
RTI_OSAPI_THREAD_PRIORITY_HIGH = 68,
RTI_OSAPI_THREAD_PRIORITY_ABOVE_NORMAL = 71,
RTI_OSAPI_THREAD_PRIORITY_NORMAL = 100,
RTI_OSAPI_THREAD_PRIORITY_BELOW_NORMAL = 110,
RTI_OSAPI_THREAD_PRIORITY_LOW = 120
} RTIOsapiThreadPriority;
#define RTI_OSAPI_THREAD_PRIORITY_DEFAULT RTI_OSAPI_THREAD_PRIORITY_NORMAL
#define RTI_OSAPI_THREAD_STACK_SIZE_DEFAULT (40 * 1024)
#elif defined(RTI_PSOS)
typedef enum {
RTI_OSAPI_THREAD_PRIORITY_HIGH = 150,
RTI_OSAPI_THREAD_PRIORITY_ABOVE_NORMAL = 130,
RTI_OSAPI_THREAD_PRIORITY_NORMAL = 100,
RTI_OSAPI_THREAD_PRIORITY_BELOW_NORMAL = 90,
RTI_OSAPI_THREAD_PRIORITY_LOW = 80
} RTIOsapiThreadPriority;
#define RTI_OSAPI_THREAD_PRIORITY_DEFAULT RTI_OSAPI_THREAD_PRIORITY_NORMAL
#define RTI_OSAPI_THREAD_STACK_SIZE_DEFAULT (16 * 1024)
#elif defined(RTI_LYNX)
typedef enum {
RTI_OSAPI_THREAD_PRIORITY_HIGH = 32,
RTI_OSAPI_THREAD_PRIORITY_ABOVE_NORMAL = 29,
RTI_OSAPI_THREAD_PRIORITY_NORMAL = 17,
RTI_OSAPI_THREAD_PRIORITY_BELOW_NORMAL = 13,
RTI_OSAPI_THREAD_PRIORITY_LOW = 10
} RTIOsapiThreadPriority;
#define RTI_OSAPI_THREAD_PRIORITY_DEFAULT RTI_OSAPI_THREAD_PRIORITY_NORMAL
#define RTI_OSAPI_THREAD_STACK_SIZE_DEFAULT (64 * 1024)
#elif defined(RTI_NETOS)
typedef enum {
RTI_OSAPI_THREAD_PRIORITY_HIGH = 6,
RTI_OSAPI_THREAD_PRIORITY_ABOVE_NORMAL = 9,
RTI_OSAPI_THREAD_PRIORITY_NORMAL = 15,
RTI_OSAPI_THREAD_PRIORITY_BELOW_NORMAL = 20,
RTI_OSAPI_THREAD_PRIORITY_LOW = 22
} RTIOsapiThreadPriority;
#define RTI_OSAPI_THREAD_PRIORITY_DEFAULT RTI_OSAPI_THREAD_PRIORITY_NORMAL
#define RTI_OSAPI_THREAD_STACK_SIZE_DEFAULT (16 * 1024)
#elif defined(RTI_WIN32)
typedef enum {
RTI_OSAPI_THREAD_PRIORITY_HIGH = 3,
RTI_OSAPI_THREAD_PRIORITY_ABOVE_NORMAL = 2,
RTI_OSAPI_THREAD_PRIORITY_NORMAL = 0,
RTI_OSAPI_THREAD_PRIORITY_BELOW_NORMAL = -2,
RTI_OSAPI_THREAD_PRIORITY_LOW = -3
} RTIOsapiThreadPriority;
#define RTI_OSAPI_THREAD_PRIORITY_DEFAULT RTI_OSAPI_THREAD_PRIORITY_NORMAL
#define RTI_OSAPI_THREAD_STACK_SIZE_DEFAULT \
(RTI_OSAPI_THREAD_STACK_SIZE_OS_DEFAULT)
#elif defined(RTI_INTIME)
typedef enum {
RTI_OSAPI_THREAD_PRIORITY_HIGH = 3,
RTI_OSAPI_THREAD_PRIORITY_ABOVE_NORMAL = 2,
RTI_OSAPI_THREAD_PRIORITY_NORMAL = 0,
RTI_OSAPI_THREAD_PRIORITY_BELOW_NORMAL = -2,
RTI_OSAPI_THREAD_PRIORITY_LOW = -3
} RTIOsapiThreadPriority;
#define RTI_OSAPI_THREAD_PRIORITY_DEFAULT RTI_OSAPI_THREAD_PRIORITY_NORMAL
#define RTI_OSAPI_THREAD_STACK_SIZE_DEFAULT (192 * 1024)
#elif defined(RTI_WINCE)
typedef enum {
RTI_OSAPI_THREAD_PRIORITY_HIGH = 249,
RTI_OSAPI_THREAD_PRIORITY_ABOVE_NORMAL = 250,
RTI_OSAPI_THREAD_PRIORITY_NORMAL = 251,
RTI_OSAPI_THREAD_PRIORITY_BELOW_NORMAL = 252,
RTI_OSAPI_THREAD_PRIORITY_LOW = 253
} RTIOsapiThreadPriority;
#define RTI_OSAPI_THREAD_PRIORITY_DEFAULT RTI_OSAPI_THREAD_PRIORITY_NORMAL
#define RTI_OSAPI_THREAD_STACK_SIZE_DEFAULT (0)
#elif defined(RTI_QNX)
typedef enum {
RTI_OSAPI_THREAD_PRIORITY_HIGH = 14,
RTI_OSAPI_THREAD_PRIORITY_ABOVE_NORMAL = 12,
RTI_OSAPI_THREAD_PRIORITY_NORMAL = 10,
RTI_OSAPI_THREAD_PRIORITY_BELOW_NORMAL = 8,
RTI_OSAPI_THREAD_PRIORITY_LOW = 6
} RTIOsapiThreadPriority;
#define RTI_OSAPI_THREAD_PRIORITY_DEFAULT RTI_OSAPI_THREAD_PRIORITY_NORMAL
#define RTI_OSAPI_THREAD_STACK_SIZE_DEFAULT (64 * 1024)
#elif defined(RTI_INTY)
typedef enum {
RTI_OSAPI_THREAD_PRIORITY_HIGH = 120,
RTI_OSAPI_THREAD_PRIORITY_ABOVE_NORMAL = 100,
RTI_OSAPI_THREAD_PRIORITY_NORMAL = 90,
RTI_OSAPI_THREAD_PRIORITY_BELOW_NORMAL = 80,
RTI_OSAPI_THREAD_PRIORITY_LOW = 60
} RTIOsapiThreadPriority;
#define RTI_OSAPI_THREAD_PRIORITY_DEFAULT 16
#define RTI_OSAPI_THREAD_STACK_SIZE_DEFAULT (64 * 1024)
#elif defined(RTI_AIX)
typedef enum {
RTI_OSAPI_THREAD_PRIORITY_HIGH = -9999999,
RTI_OSAPI_THREAD_PRIORITY_ABOVE_NORMAL = -9999999,
RTI_OSAPI_THREAD_PRIORITY_NORMAL = -9999999,
RTI_OSAPI_THREAD_PRIORITY_BELOW_NORMAL = -9999999,
RTI_OSAPI_THREAD_PRIORITY_LOW = -9999999
} RTIOsapiThreadPriority;
#define RTI_OSAPI_THREAD_PRIORITY_DEFAULT RTI_OSAPI_THREAD_PRIORITY_NORMAL
/*
* The default stack size on 32 bit AIX is too small, the default for 64 bit
* is 192KB, which is enough. Set the default high enough.
*/
#define RTI_OSAPI_THREAD_STACK_SIZE_DEFAULT (192 * 1024)
#else
typedef enum {
RTI_OSAPI_THREAD_PRIORITY_HIGH = -9999999,
RTI_OSAPI_THREAD_PRIORITY_ABOVE_NORMAL = -9999999,
RTI_OSAPI_THREAD_PRIORITY_NORMAL = -9999999,
RTI_OSAPI_THREAD_PRIORITY_BELOW_NORMAL = -9999999,
RTI_OSAPI_THREAD_PRIORITY_LOW = -9999999
} RTIOsapiThreadPriority;
#define RTI_OSAPI_THREAD_PRIORITY_DEFAULT RTI_OSAPI_THREAD_PRIORITY_NORMAL
#define RTI_OSAPI_THREAD_STACK_SIZE_DEFAULT \
(RTI_OSAPI_THREAD_STACK_SIZE_OS_DEFAULT)
#endif /* setting of default thread property */
/** @internal \ingroup RTIOsapiThreadClass
* @brief Default thread name prefix for transport threads.
*/
#define NDDS_TRANSPORT_THREAD_NAME_PREFIX_DEFAULT "rTr#####"
typedef void RTIOsapiThreadTssFactory;
/** @internal \ingroup RTIOsapiThreadClass
* @brief Creates the factory that provides keys for
* thread-local storage.
*
* The factory is intended to act as a singleton.
* It's definition is opaque and implementation-dependent.
* This function is not thread safe.
*/
extern RTIOsapiDllExport RTIOsapiThreadTssFactory *
RTIOsapiThread_createTssFactory(void);
/** @internal \ingroup RTIOsapiThreadClass
* @brief Deletes the factory.
* This function is not thread safe.
*/
extern RTIOsapiDllExport void RTIOsapiThread_deleteTssFactory(
RTIOsapiThreadTssFactory *factory);
/** @internal \ingroup RTIOsapiThreadClass
*
* @brief Enables or disables automatic tss cleanup on platforms
* that support it, depending on the value passed in for
* enable.
*
* @see RTIOsapiThread_createKeyWithDtor
*/
extern RTIOsapiDllExport void RTIOsapiThread_enableTssDestructors(
RTIBool enable);
/** @internal \ingroup RTIOsapiThreadClass
* @brief Returns true if automatic tss destructor support has
* been enabled. Windows and POSIX APIs support providing
* a destructor when a TSS key is created that will be
* called when the thread exits so that the TSS
* associated with that thread can be cleaned up.
*
* @see RTIOsapiThread_createKeyWithDtor
* @see RTIOsapiThread_enableTssDestructors
*/
extern RTIOsapiDllExport RTIBool RTIOsapiThread_tssDestructorsAreEnabled(void);
#if defined(RTI_POSIX_THREADS)
#include <limits.h>
#define RTI_OSAPI_THREAD_INVALID_TSS_KEY (PTHREAD_KEYS_MAX + 1)
#elif defined (RTI_WIN32)
#define RTI_OSAPI_THREAD_INVALID_TSS_KEY TLS_OUT_OF_INDEXES
#elif defined(RTI_RTP)
#define RTI_OSAPI_THREAD_INVALID_TSS_KEY ERROR
#else
#define RTI_OSAPI_THREAD_INVALID_TSS_KEY 0xFFFFFFFF
#endif
/** @internal \ingroup RTIOsapiThreadClass
* @brief Returns an invalid TSS key value. This value is
* different depending on the platform, so instead of
* defining a single constant we have this function
*
* @see RTIOsapiThread_isTssKeyValid
*/
extern RTIOsapiDllExport
RTI_UINT32 RTIOsapiThread_getInvalidTssKey(void);
/** @internal \ingroup RTIOsapiThreadClass
* @brief Returns true if the tss key value is in the valid
* range of values. This range varies per platform
*
* @see RTIOsapiThread_getInvalidTssKey
*/
extern RTIOsapiDllExport
RTIBool RTIOsapiThread_isTssKeyValid(RTI_UINT32 key);
/** @internal \ingroup RTIOsapiThreadClass
*
* @brief Function prototype for a destructor that can be
* associated to a TSS key when it is created.
*
* Some platforms support associating a destructor callback to a
* TSS key in the form of this function prototype.
*
* @param tssValue When a thread exits and the destructor is
* called for a TSS key slot, tssValue is the value in the tss
* slot that this destructor is associated with.
*/
#if defined(RTI_WIN32) && !defined(RTI_64BIT)
/*
* On 32-bit Windows the destructor callback function is defined with the
* __stdcall calling convention, which is not the default. The default is
* __cdecl. We must use this same calling convention when defining our
* callback prototype or else there will be compiler errors about mismatched
* function types. Casting from a function that is declared with __cdecl to
* one defined with __stdcall will lead to stack corruption.
*/
#define RTI_OSAPI_THREAD_TSS_DTOR_CALLING_CONVENTION __stdcall
#else
#define RTI_OSAPI_THREAD_TSS_DTOR_CALLING_CONVENTION
#endif
typedef void(RTI_OSAPI_THREAD_TSS_DTOR_CALLING_CONVENTION
*RTIOsapiThreadTssDesctructorFnc)(void *tssValue);
/** @internal \ingroup RTIOsapiThreadClass
* @brief create key with a destructor.
*
* @param key \b Out. The key created will be returned here.
* @param tssFactory \b In. The singleton created by
* RTIOsapiThread_createTssFactory
* @param destructor \b In. The destructor to be called when the
* thread exits to cleanup the data that is pointed at by
* key. Not all platforms support automatically calling a
* destructor. See RTIOsapiThread_supportsTssDestructor.
*
* The destructor must take the following into account:
*
* - On platforms which support pthreads the following is
* true:
* - When a key is deleted, the destructor will NO
* LONGER be called on any outstanding threads that
* may have non-NULL values in the key slot which is
* being deleted. This mean that the memory will be
* leaked if it is not tracked and cleaned up
* elsewhere.
* - When a thread exits, the TSS slot is set to
* NULL, and then the destructor is called, passing
* in the previous (non-NULL) value to the
* destructor. This means that calling getTss will
* return a NULL value and setting the TSS to NULL
* within the destructor is not needed.
*
* - On Windows, when a key is deleted, the destructor
* for all outstanding threads with non-NULL values
* stored at that key ARE called within the context of
* the same thread that is deleting the key. The
* implications of this are:
* - Any lock that is taken within the destructor
* must be reentrant if the code path that is
* deleting the key is also taking that lock.
* - The destructor is not called within the
* context of the thread whose TSS is being
* deleted, so calling APIs to get or set TSS in
* the destructor will be getting and setting TSS
* within the thread that is deleting the key,
* not within the thread that is having its TSS
* cleaned up.
*
* The best practices therefore when deleting a key that
* has an associated destructor is to:
* 1. Cache the key value.
* 2. Set the key to an invalid value
* 3. Delete the key using the cached value
* 4. In the destructor:
* - Check for an invalid key value and if the
* key is invalid, exit without cleaning up
* anything, therefore leaving the code path
* that is deleting the key to clean up all
* resources that may have been stored in TSS
* for all threads.
* - Do not call getTss or setTss -- since you
* can't be sure what thread the destructor is
* called in
* - Make sure all locks that are used are
* reentrant on Windows
*
* @return RTI_TRUE on success, RTI_FALSE on failure
*/
extern RTIOsapiDllExport RTIBool RTIOsapiThread_createKeyWithDtor(
RTI_UINT32 *key,
RTIOsapiThreadTssFactory *factory,
RTIOsapiThreadTssDesctructorFnc destructor);
/** @internal \ingroup RTIOsapiThreadClass
* @brief create key.
*
* @param key \b Out. The key created will be returned here.
* @param tssFactory \b In. The singleton created by
* RTIOsapiThread_createTssFactory
* @return RTI_TRUE on success, RTI_FALSE on failure
*/
extern RTIOsapiDllExport RTIBool
RTIOsapiThread_createKey(RTI_UINT32 *key, RTIOsapiThreadTssFactory *tssFactory);
/** @internal \ingroup RTIOsapiThreadClass
* @brief set thread specific storage.
*
* @param key \b In. The key of the storage.
* @param value \b In. The param put into the storage.
* @return RTI_TRUE on success, RTI_FALSE on failure
*/
extern RTIOsapiDllExport RTIBool
RTIOsapiThread_setTss(RTI_UINT32 key, const void *value);
/** @internal \ingroup RTIOsapiThreadClass
* @brief get thread specific storage.
*
* @param key \b In. The key of the storage.
* @return The value in the storage if success. NULL on failure.
*/
extern RTIOsapiDllExport void *RTIOsapiThread_getTss(RTI_UINT32 key);
/** @internal \ingroup RTIOsapiThreadClass
* @brief Get thread specific storage Integer value.
*
* @param key \b In. The key of the storage.
* @return The value in the storage as Integer, if success. 0 on failure.
*/
extern RTIOsapiDllExport RTI_INT32
RTIOsapiThread_getTssAsInteger(RTI_UINT32 key);
/** @internal \ingroup RTIOsapiThreadClass
* @brief set thread specific storage for an Integer value.
*
* @param key \b In. The key of the storage.
* @param value \b In. The Integer value to put into the storage.
* @return RTI_TRUE on success, RTI_FALSE on failure
*/
extern RTIOsapiDllExport RTIBool
RTIOsapiThread_setTssAsInteger(RTI_UINT32 key, RTI_INT32 value);
/** @internal \ingroup RTIOsapiThreadClass
* @brief delete key.
*
* @param key \b In. The key to be deleted.
* @param tssFactory \b In. The singleton created by
* RTIOsapiThread_createTssFactory
* @return RTI_TRUE on success, RTI_FALSE on failure
*/
extern RTIOsapiDllExport RTIBool
RTIOsapiThread_deleteKey(RTIOsapiThreadTssFactory *tssFactory, RTI_UINT32 key);
/** @internal \ingroup RTIOsapiThreadClass
*
* @brief Static method to suspend current thread, sleep for specified NTP time.
*
* This call suspends the current thread for the specified duration.
* Note that the granularity, and minimum sleep time are OS dependant.
*
* - \b On \b VxWorks, this function calls taskDelay(),
* hence the granularity and the minimum sleep time are a
* single clock tick (as reported by sysClockRateGet()).
* - \b On \b pSOS, this function calls tm_wkafter(); the granularity is
* determined by the clock-tick rate.
* - \b On \b Unix, this function calls either poll() or select().
* In fact it may call them multiple times if poll()/select()
* return prematurely woken by a signal. RTIOsapiThread_sleep() keeps
* track of the total time slept using gettimeofday() to ensure
* the specified usec have elapsed.
* - \b On \b Win32, use Sleep(), which has a different granularity
* on different windows OSes, but is generally poorer than 10 ms.
*
* \b Example:
*
* To sleep for 1.5 seconds,
* \verbatim
* RTINtpTime time;
* RTINtpTime_packFromMillisec(time, 1, 500);
* RTIOsapiThread_sleep(&time);
* \endverbatim
*
* @param time The amount of time to sleep using RTITime. If NULL
* (infinite time), sleep forever (on UNIX a very long time).
* If Zero time, it causes a at least a context switch.
* @return RTI_FALSE if error occurred (e.g., if thread is locked on
* VxWorks) otherwise, return RTI_TRUE.
*
* @mtsafety NOT safe in the first call. Safe subsequently.
*/
extern RTIOsapiDllExport RTIBool
RTIOsapiThread_sleep(const struct RTINtpTime *timeIn);
/** @internal \ingroup RTIOsapiThreadClass
*
* @brief Static method to suspend current thread using an active wait.
*
* This method is usually used in combination with
* RTIClock_getSpinPerMicrosecond.
*/
extern RTIOsapiDllExport void RTIOsapiThread_spin(RTI_UINT64 spinCount);
/** @internal \ingroup RTIOsapiThreadClass
*
* @brief Get a thread's priority
*/
extern RTIOsapiDllExport int RTIOsapiThread_getPriority(
struct RTIOsapiThread *me);
/** @internal \ingroup RTIOsapiThreadClass
* @brief log CPU affinity for a thread
*
* This method acts as a proxy for printing the CPU affinity for a
* thread. Because affinity APIs are OS-specific, we
* centralize their use so othe modules can remain agnostic.
*/
extern RTIOsapiDllExport void RTIOsapiThread_logCpuAffinity(
const char *threadName);
#if defined(RTI_CPU_AFFINITY) && defined(RTI_POSIX_THREADS) && defined(RTI_LINUX)
/** @internal \ingroup RTIOsapiThreadClass
* @brief get the CPU affinity for a thread.
*
* Only supported on platforms that support CPU affinity.
*/
extern RTIOsapiDllExport RTIBool RTIOsapiThread_getCpu(char *cpuBuffer);
/** @internal \ingroup RTIOsapiThreadClass
* @brief get the maximum number of CPUs in set.
*
* Only supported on platforms that support CPU affinity.
*/
extern RTIOsapiDllExport RTI_INT32 RTIOsapiThread_getCpuCount(void);
#endif
/** @internal \ingroup RTIOsapiThreadClass
*
* @brief Function prototype for entry point for the thread.
*
* Function prototype for the routine specified at thread creation
* time. The new thread will start executing this function.
*
* @param threadParam Pointer to data that will be passed to the thread
* routine. You must cast this to appropriate type to access the data.
*/
typedef void *(*RTIOsapiThreadOnSpawnedMethod)(void *threadParam);
/** @internal \ingroup RTIOsapiThreadClass
*
* @brief ctor
*
* Creates a new thread with the specified priority and
* stack. The new thread starts executing the "thread_rtn" which gets
* passed the single parameter "param".
* The thread is removed when the function "thread_rtn" returns.
*
* If a stack pointer different than NULL is provided, the thread will be
* created so it uses the provided memory as stack. Otherwise, a stack with the
* specified size will be created by the underlying OS.
*
* The function returns a newly allocated ThreadId. It is the
* responsibility of the user of this method to free this structure again
* with RTIOsapiThread_delete (see the example below).
*
* As a convenience, the CPU bitmap parameter may be NULL. This has
* the same effect as passing a bitmap corresponding to the default
* QoS. In these cases, the thread affinity is left to the OS to handle.
*
* The priority passed to RTIOsapiThread_new() is the *native* OS priority.
* You can use RTIOsapiThreadClassNativePriorityGet() to get a native priority
* from a system-independent logical priority.
*
* NOTE: By default this function does not check whether the
* specified priority is in the allowed range for the OS/Mode where the
* process is running. If it is not in range, you will get
* whatever the OS decides to give you. To get predictable behavior,
* you must specify the RTI_OSAPI_THREAD_OPTION_PRIORITY_ENFORCE flag in your
* options parameter. When this option is specified, RtiTreadCreate()
* will check the priority, and return NULL *without* starting
* the thread if the priority is outside the allowed range.
*
* Hence you should *always* use RTI_OSAPI_THREAD_OPTION_PRIORITY_ENFORCE.
* The only reason this is not the default is to provide backwards
* compatibility.
*
* Note on IRIX native sprocs:
*
* Priorities from NDPHIMAX (30) to NDPHIMIN (39) are considered real-time
* and higher than normally scheduled processes.
*
* You should NOT set normal priorities if don't want to degrade
* what you would get if didn't try to set any priorities.
* Setting a normal priority will guarantee that you get something
* less than if you didn't set anything at all!
*
* Note on Windows:
*
* Windows supports 7 levels for threads (within each priority class -
* there are 4 priorities classes, and all
* threads within a process belong to one of these 4 classes): The actual enum
* value of these macros is different on Windows, and to gain some
* commonality, the THREAD_OPTION_PRIORITIES are defined as follows. (This
* mapping is done during ThreadCreate, but not with ThreadPrioritySet, there
* you must use native priorities)
*
* - RTI_OSAPI_THREAD_PRIORITY_TIME_CRITICAL - 3
* - RTI_OSAPI_THREAD_PRIORITY_HIGHEST - 2
* - RTI_OSAPI_THREAD_PRIORITY_ABOVE_NORMAL - 1
* - RTI_OSAPI_THREAD_PRIORITY_NORMAL - 0
* - RTI_OSAPI_THREAD_PRIORITY_BELOW_NORMAL - -1
* - RTI_OSAPI_THREAD_PRIORITY_LOWEST - -2
*
* On Windows:
*
* THREAD_PRIORITY_IDLE - -3
*
* \b Example:
* The following provide some basic examples:
*
* \verbatim
* struct RTIOsapiThread* tid;
* tid = RTIOsapiThread_new("WelcomeThread", 100,
* RTI_OSAPI_THREAD_OPTION_PRIORITY_ENFORCE,
* 1024, NULL, PrintMessage, "Hello world", NULL);
* RTIOsapiThread_delete(tid);
* \endverbatim
*
* @param name The name of the thread.
* @param priority The operating system specific priority.
* @param options Thread options.
* @param stack Thread's stack. If NULL the OS will provide a stack of
* stackSize
* @param stackSize Stack size
* @param cpuBitmap CPUs the thread can run on. May be NULL, which imposes
* no restrictions.
* @param thread_rtn The starting location of this new thread.
*
* @return On failure, this function returns NULL. On success, this function
* returns a handle to a new thread, which you should use later in
* dtor.
*
* @see RTIOsapiThread_delete
*/
extern RTIOsapiDllExport struct RTIOsapiThread *RTIOsapiThread_newWithStack(
const char *name,
int priority,
int options,
void *stack,
int stackSize,
struct RTIOsapiCpuBitmap *cpuBitmap,
RTIOsapiThreadOnSpawnedMethod thread_rtn,
void *threadParam);
/** @internal \ingroup RTIOsapiThreadClass
*
* @brief Initializes a thread whose stack is managed by the underlying OS
*
*/
extern RTIOsapiDllExport RTIBool RTIOsapiThread_initialize(
struct RTIOsapiThread *me,
const char *name,
int priority,
int options,
int stackSize,
struct RTIOsapiCpuBitmap *cpuBitmap,
RTIOsapiThreadOnSpawnedMethod thread_rtn,
void *threadParam);
/** @internal \ingroup RTIOsapiThreadClass
*
* @brief Creates a thread whose stack is managed by the underlying OS has the
* specified size.
*
* @see RTIOsapiThread_newWithStack
*/
extern RTIOsapiDllExport struct RTIOsapiThread *RTIOsapiThread_new(
const char *name,
int priority,
int options,
int stackSize,
struct RTIOsapiCpuBitmap *cpuBitmap,
RTIOsapiThreadOnSpawnedMethod thread_rtn,
void *threadParam);
/** @internal \ingroup RTIOsapiThreadClass
* @brief Delete a thread.
* Frees the memory associates with the ThreadId.
* By default, the thread will be joined.
*
* @param tid A handle to the thread to delete.
*/
extern RTIOsapiDllExport void RTIOsapiThread_delete(struct RTIOsapiThread *me);
/** @internal \ingroup RTIOsapiThreadClass
* @brief Delete a thread.
* Frees the memory associates with the ThreadId.
* By default, the thread will be joined.
*
* @param tid A handle to the thread to delete.
* @param me \b In. joinThread. Call pthread_join. It should be true for the
* thread created in osapi.1.0. It can be false for thread created by
* the native Java API (new Thread()).
*/
extern RTIOsapiDllExport void RTIOsapiThread_deleteEx(
struct RTIOsapiThread *me,
RTIBool joinThread);
#if defined(RTI_WIN32) || defined(RTI_WINCE) || defined(RTI_VXWORKS) \
|| defined(RTI_INTIME)
/** @internal \ingroup RTIOsapiThreadClass
*
* @brief Terminate the thread. (Windows and VxWorks OS only)
*
* Wrapper for windows TerminateThread call, required since thread handles are
* OS specific, and cannot be "generalized". Higher layers should confine
* themselves to the use of RTIOsapiThread structures, and utilize the OSAPI
* layer to perform system calls.
*
* Wrapper for vxworks taskDelete call.
*
* @param struct RTIOsapiThread* me.
*/
extern RTIOsapiDllExport void RTIOsapiThread_terminateThread(
struct RTIOsapiThread *me);
#endif
/** @internal \ingroup RTIOsapiThreadClass
*
* @brief Get the thread from which this method is called.
*
* This method returns a new copy of this thread object; the client is
* responsible for deleting it when it's no longer needed. Deleting the
* thread object does not affect the actually running thread of execution.
*
* @return The thread object corresponding to the calling thread.
*
* @author rbw
*/
extern RTIOsapiDllExport struct RTIOsapiThread *RTIOsapiThread_getCurrentThread(
void);
/** @internal \ingroup RTIOsapiThreadClass
*
* @brief Get the threadID from which this method is called.
*
* @return 32-bit value corresponding to the calling thread, or zero on failure.
*
* @author as
*/
extern RTIOsapiDllExport RTI_UINT64 RTIOsapiThread_getCurrentThreadID(void);
/** @internal \ingroup RTIOsapiThreadClass
*
* @brief Gets the native priority for the thread.
*
* RTI priority range is from normalMin to normalMax, which is nominally
* 0 to 255 with 255 being the highest priority.
*
* Because not all OS's have 256 priority levels there may be a many to
* one mapping of RTI priorities to native priorities.
*
* The mapping is linear at this time and will change depending on the
* operation mode that you are running and requesting.
*/
extern RTIOsapiDllExport RTIBool RTIOsapiThread_getNativePriorityFromNormal(
int *nativePriority,
int normalPriority,
int normalMin,
int normalMax,
int options);
/** @internal \ingroup RTIOsapiThreadClass
*
* @brief Gets the normalized priority for the thread.
*
* RTI priority range is from normalMin to normalMax, which is nominally
* 0 to 255 with 255 being the highest priority.
*
* Because not all OS's have 256 priority levels there may be a many to
* one mapping of RTI priorities to native priorities.
*
* The mapping is linear at this time and will change depending on the
* operation mode that you are running and requesting.
*/
extern RTIOsapiDllExport RTIBool RTIOsapiThread_getNormalPriorityFromNative(
int *normalPriority,
int nativePriority,
int normalMin,
int normalMax,
int options);
/** @internal \ingroup RTIOsapiThreadClass
*
* @brief Checks whether managed stack is supported by the current platform.
*
* Managed stack is supported by certain platforms only. For instance, some
* POSIX implementations support this via pthread_attr_setstack.
*
* @return RTI_TRUE if supported.
*/
extern RTIOsapiDllExport RTIBool RTIOsapiThread_isManagedStackSupported(void);
/*--------------------- RTIOsapiJoinableThread -------------------------------*/
/** @internal \ingroup RTIOsapiThreadClass
* Default blocking timeout 20 sec.
*/
#define RTI_OSAPI_THREAD_DEFAULT_BLOCKING_TIMEOUT 20000
/** @internal \ingroup RTIOsapiThreadClass
* Infinite blocking timeout.
*/
#define RTI_OSAPI_THREAD_INFINITE_BLOCKING_TIMEOUT RTI_UINT32_MAX
/** @internal \defgroup RTIOsapiJoinableThreadClass RTIOsapiThread
* \ingroup RTIOsapiModule
*
* \brief A regular delete call that will block timeoutMillisec the thread.
* It removes the resources associate to the thread.
*
*/
extern RTIOsapiDllExport RTIBool RTIOsapiJoinableThread_stopAndDelete(
struct RTIOsapiJoinableThread *self,
RTI_UINT32 timeoutMillisec);
/** @internal \defgroup RTIOsapiJoinableThreadClass RTIOsapiThread
* \ingroup RTIOsapiModule
*
* \brief Creates a controlled thread. Parameters are the same than a regular
* OSAPI thread.
*
*/
extern RTIOsapiDllExport struct RTIOsapiJoinableThread *
RTIOsapiJoinableThread_new(
const char *name,
int priority,
int options,
int stackSize,
struct RTIOsapiCpuBitmap *cpuBitmap,
RTIOsapiThreadOnSpawnedMethod thread_rtn,
void *threadParam);
/** @internal \ingroup RTIOsapiModule
*
* @brief Get a thread's priority
*/
extern RTIOsapiDllExport int RTIOsapiJoinableThread_getPriority(
struct RTIOsapiJoinableThread *me);
/** @internal
* @brief Get the name of the thread.
*
* @return the name of the thread.
* The caller of this function is responsible for freeing the string.
*/
extern RTIOsapiDllExport char *RTIOsapiThread_getName(void);
/** @internal
* @brief Set the name of the thread
*
* @param name \b In. Name of the thread
*
* @return If there is an error returns the returnCode. Otherwise, 0
*/
extern RTIOsapiDllExport int RTIOsapiThread_setName(const char *name);
#if ((defined(RTI_LINUX) && defined(__GLIBC__) \
&& ((__GLIBC__ > 2) || (__GLIBC__ == 2 && (__GLIBC_MINOR__ >= 12)))) \
|| (defined(RTI_DARWIN) && defined(__MAC_OS_X_VERSION_MAX_ALLOWED) \
&& (__MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_6)) \
|| defined(RTI_QNX) || defined(RTI_WIN32) \
|| (defined(RTI_IOS) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200))) \
&& defined(RTI_CPU_AFFINITY)
#define RTI_OSAPI_SET_THREAD_NAME_SUPPORTED 1
#else
#define RTI_OSAPI_SET_THREAD_NAME_SUPPORTED 0
#endif
#if RTI_OSAPI_SET_THREAD_NAME_SUPPORTED && defined(RTI_POSIX_THREADS)
#define RTI_OSAPI_GET_THREAD_NAME_SUPPORTED 1
#else
#define RTI_OSAPI_GET_THREAD_NAME_SUPPORTED 0
#endif
/** @internal
* For all the platforms:
* We limit the thread name length to 16 characters,
* including the null byte ('\0').
* This limit comes from Linux, that is the more restrictive architecture.
* We use the same limit in all the platforms for consistency.
*/
#define RTI_OSAPI_THREAD_NAME_MAX_SIZE 16
/** @internal
* Thread name prefix represents the concatenation of:
* 'r' + Module + participantIdentification + '\0'.
* For example the Transport prefix thread:
* With domainID (111) and participantId (22)
* "rTr11122"
*/
#define RTI_OSAPI_THREAD_NAME_PREFIX_MAX_SIZE 9
/** @internal
* Thread participant identification:
* 5 characters + '\0'.
*/
#define RTI_OSAPI_THREAD_PARTICIPANT_ID_MAX_SIZE 6
/** @internal
* Thread module abbreviation:
* 3 characters + '\0'.
*/
#define RTI_OSAPI_THREAD_MODULE_MAX_SIZE 4
/** @internal
* Thread task type:
* 3 characters + '\0'.
*/
#define RTI_OSAPI_THREAD_TASK_TYPE_MAX_SIZE 4
/** @internal
* Thread custom name, not fitting a pattern:
* 9 characters + '\0'.
*/
#define RTI_OSAPI_THREAD_CUSTOM_NAME_MAX_SIZE 10
/** @internal
* Thread transport name, such as "TCP4":
* 4 characters + '\0'.
*/
#define RTI_OSAPI_THREAD_TRANSPORT_NAME_MAX_SIZE 5
/** @internal The task type for the event thread */
#define RTI_OSAPI_EVENT_THREAD_TASK_TYPE "Evt"
/** @internal The task type for the receive thread */
#define RTI_OSAPI_RECEIVE_THREAD_TASK_TYPE "Rcv"
/** @internal The task type for the local credential thread */
#define RTI_OSAPI_LOCAL_CREDENTIAL_THREAD_TASK_TYPE "LCr"
/** @internal \ingroup RTIOsapiThreadClass
* \brief Disables the support to log the backTrace.
*
* This function is not thread safe
*/
extern RTIOsapiDllExport void RTIOsapiThread_disableBacktraceSupport(void);
/** @internal \ingroup RTIOsapiThreadClass
* \brief Enables the support to log the backTrace.
*
* This function is not thread safe
*
* @param tssFactory \b In. TSS Factory to cache the backtrace per thread.
*
* @return RTI_TRUE on success.
* RTI_FALSE on failure enabling the log backtrace support.
*/
extern RTIOsapiDllExport RTIBool
RTIOsapiThread_enableBacktraceSupport(RTIOsapiThreadTssFactory *tssFactory);
struct RTIOsapiThreadBacktraceNode;
/** @internal \ingroup RTIOsapiThreadClass
*
* @brief Clean cached backtrace in current thread's TSS.
*
* @param finalizeBacktraceNode \b In. The first time a thread caches a
* backtrace, in addition to the backtrace itself, we allocate some additional
* resources. When finalizeBacktraceNode is set to RTI_TRUE, this function will
* release both the cached backtrace and those additional resources. If
* finalizeBacktraceNode is set to RTI_FALSE, this function will delete the
* cached backtrace, but it will not release these additional resources (which
* will be deleted upon DomainParticipantGlobals destruction).
*
* @param node \b In. If passed in as non-NULL, this is the node
* that is finalized. When passed in as NULL, the
* function attempts to get the node from TSS. It is
* passed in as non-NULL when called from the TSS
* destructor on those platforms that support
* automatic tss destruction upon thread exit.
*/
extern RTIOsapiDllExport void RTIOsapiThread_finalizeCachedBacktrace(
RTIBool finalizeBacktraceNode,
struct RTIOsapiThreadBacktraceNode *node);
/** @internal \ingroup RTIOsapiThreadClass
* \brief Install a signal handler
*
* This function is not thread safe
*
* @return RTI_TRUE on success or RTI_FALSE on failure.
*/
extern RTIOsapiDllExport RTIBool RTIOsapiThread_installSigsegvHandler(void);
/** @internal \ingroup RTIOsapiThreadClass
* @brief Log the stack trace of the current thread.
*
* @param index \b In. The first element of the stack to log.
* @param detailLevel \b In. Only for RTI_LINUX. Define the level of detail of
* the backtrace.
* @param handlingSigsegv \b In. Whether we are handling a SIGSEGV. If we are,
* we cannot call malloc because it is not signal safe.
*/
extern RTIOsapiDllExport void RTIOsapiThread_logBacktrace(
int index,
RTILogBacktraceDetailLevel detailLevel,
int handlingSigsegv);
/** @internal \ingroup RTIOsapiThreadClass
* @brief Add function name to the queue of Function History per worker
*
* @param pointerFuncName \b In. Function name.
*/
extern RTIOsapiDllExport void RTIOsapiThread_addFunctionToDebugInfo(
void *pointerFuncName);
/** @internal
* - RTI_OSAPI_BACKTRACE_SUPPORTED means that the backtrace feature is
* supported.
* - RTI_BACKTRACE_DISABLED_BY_DEFAULT means that the backtrace feature is
* disabled by default. When disabled by default, it can only be enabled by
* setting the logPrintFormat bit RTI_LOG_PRINT_BIT_FORCE_BACKTRACE.
* - RTI_OSAPI_BACKTRACE_TEST_SUPPORTED means that the backtrace feature is
* suported and it is enabled by default.
*/
#if (defined(RTI_DARWIN) || defined(RTI_WIN32) \
|| (defined(RTI_LINUX) \
&& ENABLE_FACE_COMPLIANCE == FACE_COMPLIANCE_LEVEL_NONE)) \
&& !defined(RTI_ANDROID)
#define RTI_OSAPI_BACKTRACE_SUPPORTED
#ifndef RTI_BACKTRACE_DISABLED_BY_DEFAULT
/* Backtrace unit tests are supported */
#define RTI_OSAPI_BACKTRACE_TEST_SUPPORTED
#endif
#else
/*
* If backtrace is not supported:
* support FunctionHistory feature in debug mode.
* FunctionHistory can be supported also by setting
* RTI_FUNCTION_HISTORY_SUPPORTED in the systemIncludes
* of the makefile of the platform, like:
* "systemIncludes += -DRTI_FUNCTION_HISTORY_SUPPORTED"
*/
#ifdef RTI_PRECONDITION_TEST
#define RTI_FUNCTION_HISTORY_SUPPORTED
#endif /* RTI_PRECONDITION_TEST */
#endif
#if ((defined(RTI_DARWIN) || defined(RTI_LINUX) || defined(RTI_WIN32)) \
&& !defined(RTI_IOS) && !defined(RTI_ANDROID))
#define RTI_OSAPI_SIGNAL_HANDLER_SUPPORTED 1
#endif
/** @internal \ingroup RTIOsapiThreadClass
* Function pointer to destroy a worker.
*/
typedef void (*RTIOsapiThread_destroyWorkerMethod)(void *worker);
extern RTIOsapiDllVariable RTIOsapiThread_destroyWorkerMethod
RTIOsapiThread_destroyWorker;
/** @internal \ingroup RTIOsapiThreadClass
* Function pointer to associate a worker to the current thread.
*/
typedef RTIBool (*RTIOsapiThread_associateWorkerMethod)(void *worker);
extern RTIOsapiDllVariable RTIOsapiThread_associateWorkerMethod
RTIOsapiThread_associateWorker;
/** @internal \ingroup RTIOsapiThreadClass
* Function pointer to create a worker with a name.
*/
typedef void *(*RTIOsapiThread_createWorkerMethod)(const char *name);
extern RTIOsapiDllVariable RTIOsapiThread_createWorkerMethod
RTIOsapiThread_createWorker;
/** @internal \ingroup RTIOsapiThreadClass
* @brief Create a thread name in the first parameter based on the other
* parameters
*
* @param[in,out] threadName Calling functions must provide a string allocated
* for 16 characters. The output is a thread consisting of 15 characters and a
* null terminator.
* @param[in] threadPrefix A string of at most 8 characters that consists of a
* module and an identifier such as a participant ID, topic name, task, or
* user-supplied name. May not be null. Will be truncated at 8 characters if
* necessary.
* @param[in] threadIndex Disregard if equal to -1.
* @param[in] taskType A string of 3 characters such as "Evt", "AWs", "Ctr",
* "Rcv", "Dtb", "Dsp", "Wri", "Log", "ITr", "ABF", "TQP", "Rea", or "Pub". May
* not be null.
*/
extern RTIOsapiDllExport void RTIOsapiThread_createThreadName(
char *threadName,
const char *threadPrefix,
int threadIndex,
const char *taskType);
/** @internal \ingroup RTIOsapiThreadClass
* @brief Create a name for a participant thread in the first parameter based on
* the other parameters
*
* @param[in,out] threadName Calling functions must provide a string allocated
* for 16 characters. The output is a thread consisting of 15 characters and a
* null terminator.
* @param[in] module A string of at most three characters identifying the
* product such as "rTR", "rCo", "rRS", "rPS", "rSe", or "RDI". May not be
* null.
* @param[in] participantId A string of at most 5 characters--may not be null.
* @param[in] threadIndex Disregard if equal to -1.
* @param[in] taskType A string of 3 characters such as "Evt", "AWs", "Ctr",
* "Rcv", "Dtb", "Dsp", "Wri", "Log", "ITr", "ABF", "TQP", "Rea", or "Pub". May
* not be null.
*/
extern RTIOsapiDllExport void RTIOsapiThread_createParticipantThreadName(
char *threadName,
const char *module,
const char *participantId,
int threadIndex,
const char *taskType);
/** @internal \ingroup RTIOsapiThreadClass
* @brief Create a thread name in the first parameter based on the other
* parameters
*
* @param[in,out] threadName Calling functions must provide a string allocated
* for 16 characters. The output is a thread consisting of 15 characters and a
* null terminator.
* @param[in] threadPrefix A string of at most 8 characters that consists of a
* module and an identifier such as a participant ID, topic name, task, or
* user-supplied name. May not be null. Will be truncated at 8 characters if
* necessary.
* @param[in] transportName A string of at most 4 characters describing the
* transport used ("TCP4"). May not be null.
* @param[in] taskType A string of 3 characters such as "Evt", "AWs", "Ctr",
* "Rcv", "Dtb", "Dsp", "Wri", "Log", "ITr", "ABF", "TQP", "Rea", or "Pub". May
* not be null.
*/
extern RTIOsapiDllExport void RTIOsapiThread_createTransportThreadName(
char *threadName,
const char *threadPrefix,
const char *transportName,
const char *taskType);
/** @internal \ingroup RTIOsapiThreadClass
* @brief Create a thread name in the first parameter based on the other
* parameters
*
* @param[in,out] threadName Calling functions must provide a string allocated
* for 16 characters. The output is a thread consisting of 15 characters and a
* null terminator.
* @param[in] module A string of at most 3 characters that consists of a
* module and an identifier such as a participant ID, topic name, task, or
* user-supplied name. May not be null.
* @param[in] customName Custom string of at most 9 characters for use in the
* thread name. May not be null. Will be truncated at 9 characters if necessary.
* @param[in] taskType A string of 3 characters such as "Evt", "AWs", "Ctr",
* "Rcv", "Dtb", "Dsp", "Wri", "Log", "ITr", "ABF", "TQP", "Rea", or "Pub". May
* not be null.
*/
extern RTIOsapiDllExport void RTIOsapiThread_createCustomThreadName(
char *threadName,
const char *module,
const char *customName,
const char *taskType);
/** @internal
* @brief Returns the thread ID of the 'self' thread object.
*
* This operation can be called from any threading context. Note that this is
* different than RTIOsapiThread_getCurrentId(), which receives no parameter
* and returns the id from the caller thread context.
*/
extern RTIOsapiDllExport RTI_UINT64
RTIOsapiThread_getId(struct RTIOsapiThread *self);
/** @internal \ingroup RTIOsapiProcessClass
* @brief Definition of the Cpu information type for a Thread
*/
struct RTIOsapiThreadCpuInfo {
RTI_UINT64 id;
struct RTINtpTime cpuTime;
};
#define RTIOsapiThreadCpuInfo_INITIALIZER \
{ \
0, RTI_NTP_TIME_ZERO \
}
/** @internal \ingroup RTIOsapiProcessClass
* @brief Obtain information about the cpu used by the specified thread.
*
* @param[out] cpu_info Holder to the structure that will return the cpu info.
*/
extern RTIOsapiDllExport void RTIOsapiThread_getCpuInfo(
struct RTIOsapiThread *self,
struct RTIOsapiThreadCpuInfo *cpuInfo);
#if defined(RTI_LINUX) || defined(RTI_DARWIN) || defined(RTI_WIN32) \
|| defined(RTI_QNX)
#define RTI_OSAPI_THREAD_CPU_INFO_SUPPORTED
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "osapi/osapi_thread_impl.h"
#endif /* osapi_thread_h */