Baselib_Thread.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #pragma once
  2. #include "Baselib_Timer.h"
  3. #include "Baselib_ErrorState.h"
  4. #ifdef __cplusplus
  5. BASELIB_C_INTERFACE
  6. {
  7. #endif
  8. // Unique thread id that can be used to compare different threads or stored for bookkeeping etc..
  9. typedef intptr_t Baselib_Thread_Id;
  10. // Baselib_Thread_Id that is guaranteed not to represent a thread
  11. static const Baselib_Thread_Id Baselib_Thread_InvalidId = 0;
  12. // Max number of characters for threadnames internal to baselib. Used for name in Baselib_Thread_Config
  13. // In practice thread implementation on some platforms support even fewer characters for names
  14. static const size_t Baselib_Thread_MaxThreadNameLength = 64;
  15. // Yields the execution context of the current thread to other threads, potentially causing a context switch.
  16. //
  17. // The operating system may decide to not switch to any other thread.
  18. BASELIB_API void Baselib_Thread_YieldExecution(void);
  19. // Return the thread id of the current thread, i.e. the thread that is calling this function
  20. BASELIB_API Baselib_Thread_Id Baselib_Thread_GetCurrentThreadId(void);
  21. // We currently do not allow creating threads from C# bindings,
  22. // since there is right now no way accessible way to inform the garbage collector about new baselib threads.
  23. // I.e. any managed allocation on a baselib thread created from C# would never be garbage collected!
  24. #ifndef BASELIB_BINDING_GENERATION
  25. // The minimum guaranteed number of max concurrent threads that works on all platforms.
  26. //
  27. // This only applies if all the threads are created with Baselib.
  28. // In practice, it might not be possible to create this many threads either. If memory is exhausted,
  29. // by for example creating threads with very large stacks, that might translate to a lower limit in practice.
  30. // Note that on many platforms the actual limit is way higher.
  31. static const int Baselib_Thread_MinGuaranteedMaxConcurrentThreads = 64;
  32. typedef struct Baselib_Thread Baselib_Thread;
  33. typedef void (*Baselib_Thread_EntryPointFunction)(void* arg);
  34. typedef struct Baselib_Thread_Config
  35. {
  36. // Nullterminated name of the created thread (optional)
  37. // Useful exclusively for debugging - which tooling it is shown by and how it can be queried is platform dependent.
  38. // Truncated to Baselib_Thread_MaxThreadNameLength number of characters and copied to an internal buffer
  39. const char* name;
  40. // The minimum size in bytes to allocate for the thread stack. (optional)
  41. // If not set, a platform/system specific default stack size will be used.
  42. // If the value set does not conform to platform specific minimum values or alignment requirements,
  43. // the actual stack size used will be bigger than what was requested.
  44. uint64_t stackSize;
  45. // Required, this is set by calling Baselib_Thread_ConfigCreate with a valid entry point function.
  46. Baselib_Thread_EntryPointFunction entryPoint;
  47. // Argument to the entry point function, does only need to be set if entryPoint takes an argument.
  48. void* entryPointArgument;
  49. } Baselib_Thread_Config;
  50. // Creates and starts a new thread.
  51. //
  52. // On some platforms the thread name is not set until the thread has begun executing, which is not guaranteed
  53. // to have happened when the creation function returns. There is typically a platform specific limit on the length of
  54. // the thread name. If config.name is longer than this limit, the name will be automatically truncated.
  55. //
  56. // \param config A pointer to a config object. entryPoint needs to be a valid function pointer, all other properties can be zero/null.
  57. //
  58. // Possible error codes:
  59. // - Baselib_ErrorCode_InvalidArgument: config.entryPoint is null
  60. // - 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
  61. BASELIB_API Baselib_Thread* Baselib_Thread_Create(Baselib_Thread_Config config, Baselib_ErrorState* errorState);
  62. // Waits until a thread has finished its execution.
  63. //
  64. // Also frees its resources.
  65. // If called and completed successfully, no Baselib_Thread function can be called again on the same Baselib_Thread.
  66. //
  67. // \param thread A pointer to a thread object.
  68. // \param timeoutInMilliseconds Time to wait for the thread to finish
  69. //
  70. // Possible error codes:
  71. // - Baselib_ErrorCode_InvalidArgument: thread is null
  72. // - Baselib_ErrorCode_ThreadCannotJoinSelf: the thread parameter points to the current thread, i.e. the thread that is calling this function
  73. // - Baselib_ErrorCode_Timeout: timeout is reached before the thread has finished
  74. BASELIB_API void Baselib_Thread_Join(Baselib_Thread* thread, uint32_t timeoutInMilliseconds, Baselib_ErrorState* errorState);
  75. // Return the thread id of the thread given as argument
  76. //
  77. // \param thread A pointer to a thread object.
  78. BASELIB_API Baselib_Thread_Id Baselib_Thread_GetId(Baselib_Thread* thread);
  79. // Returns true if there is support in baselib for threads on this platform, otherwise false.
  80. BASELIB_API bool Baselib_Thread_SupportsThreads(void);
  81. #endif // !BASELIB_BINDING_GENERATION
  82. #ifdef __cplusplus
  83. } // BASELIB_C_INTERFACE
  84. #endif