2023-02-10 15:13:26 +08:00

108 lines
5.0 KiB
C

#pragma once
#include "Baselib_Timer.h"
#include "Baselib_ErrorState.h"
#ifdef __cplusplus
BASELIB_C_INTERFACE
{
#endif
// Unique thread id that can be used to compare different threads or stored for bookkeeping etc..
typedef intptr_t Baselib_Thread_Id;
// Baselib_Thread_Id that is guaranteed not to represent a thread
static const Baselib_Thread_Id Baselib_Thread_InvalidId = 0;
// Max number of characters for threadnames internal to baselib. Used for name in Baselib_Thread_Config
// In practice thread implementation on some platforms support even fewer characters for names
static const size_t Baselib_Thread_MaxThreadNameLength = 64;
// Yields the execution context of the current thread to other threads, potentially causing a context switch.
//
// The operating system may decide to not switch to any other thread.
BASELIB_API void Baselib_Thread_YieldExecution(void);
// Return the thread id of the current thread, i.e. the thread that is calling this function
BASELIB_API Baselib_Thread_Id Baselib_Thread_GetCurrentThreadId(void);
// We currently do not allow creating threads from C# bindings,
// since there is right now no way accessible way to inform the garbage collector about new baselib threads.
// I.e. any managed allocation on a baselib thread created from C# would never be garbage collected!
#ifndef BASELIB_BINDING_GENERATION
// The minimum guaranteed number of max concurrent threads that works on all platforms.
//
// This only applies if all the threads are created with Baselib.
// In practice, it might not be possible to create this many threads either. If memory is exhausted,
// by for example creating threads with very large stacks, that might translate to a lower limit in practice.
// Note that on many platforms the actual limit is way higher.
static const int Baselib_Thread_MinGuaranteedMaxConcurrentThreads = 64;
typedef struct Baselib_Thread Baselib_Thread;
typedef void (*Baselib_Thread_EntryPointFunction)(void* arg);
typedef struct Baselib_Thread_Config
{
// Nullterminated name of the created thread (optional)
// Useful exclusively for debugging - which tooling it is shown by and how it can be queried is platform dependent.
// Truncated to Baselib_Thread_MaxThreadNameLength number of characters and copied to an internal buffer
const char* name;
// The minimum size in bytes to allocate for the thread stack. (optional)
// If not set, a platform/system specific default stack size will be used.
// If the value set does not conform to platform specific minimum values or alignment requirements,
// the actual stack size used will be bigger than what was requested.
uint64_t stackSize;
// Required, this is set by calling Baselib_Thread_ConfigCreate with a valid entry point function.
Baselib_Thread_EntryPointFunction entryPoint;
// Argument to the entry point function, does only need to be set if entryPoint takes an argument.
void* entryPointArgument;
} Baselib_Thread_Config;
// Creates and starts a new thread.
//
// On some platforms the thread name is not set until the thread has begun executing, which is not guaranteed
// to have happened when the creation function returns. There is typically a platform specific limit on the length of
// the thread name. If config.name is longer than this limit, the name will be automatically truncated.
//
// \param config A pointer to a config object. entryPoint needs to be a valid function pointer, all other properties can be zero/null.
//
// Possible error codes:
// - Baselib_ErrorCode_InvalidArgument: config.entryPoint is null
// - Baselib_ErrorCode_OutOfSystemResources: there is not enough memory to create a thread with that stack size or the system limit of number of concurrent threads has been reached
BASELIB_API Baselib_Thread* Baselib_Thread_Create(Baselib_Thread_Config config, Baselib_ErrorState* errorState);
// Waits until a thread has finished its execution.
//
// Also frees its resources.
// If called and completed successfully, no Baselib_Thread function can be called again on the same Baselib_Thread.
//
// \param thread A pointer to a thread object.
// \param timeoutInMilliseconds Time to wait for the thread to finish
//
// Possible error codes:
// - Baselib_ErrorCode_InvalidArgument: thread is null
// - Baselib_ErrorCode_ThreadCannotJoinSelf: the thread parameter points to the current thread, i.e. the thread that is calling this function
// - Baselib_ErrorCode_Timeout: timeout is reached before the thread has finished
BASELIB_API void Baselib_Thread_Join(Baselib_Thread* thread, uint32_t timeoutInMilliseconds, Baselib_ErrorState* errorState);
// Return the thread id of the thread given as argument
//
// \param thread A pointer to a thread object.
BASELIB_API Baselib_Thread_Id Baselib_Thread_GetId(Baselib_Thread* thread);
// Returns true if there is support in baselib for threads on this platform, otherwise false.
BASELIB_API bool Baselib_Thread_SupportsThreads(void);
#endif // !BASELIB_BINDING_GENERATION
#ifdef __cplusplus
} // BASELIB_C_INTERFACE
#endif