ThreadImpl.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #pragma once
  2. #if !IL2CPP_THREADS_STD && IL2CPP_THREADS_PTHREAD && !RUNTIME_TINY
  3. #include <pthread.h>
  4. #include <vector>
  5. #include <atomic>
  6. #include "os/Generic/WaitObject.h"
  7. #include "os/ErrorCodes.h"
  8. #include "os/Mutex.h"
  9. #include "os/Event.h"
  10. #include "os/Thread.h"
  11. #include "os/WaitStatus.h"
  12. #include "utils/NonCopyable.h"
  13. #include "Cpp/CappedSemaphore.h"
  14. #include "Cpp/Atomic.h"
  15. #if defined(IL2CPP_ENABLE_PLATFORM_THREAD_AFFINTY)
  16. struct cpu_set_t;
  17. int pthread_attr_setaffinity_np(pthread_attr_t *attr, size_t cpusetsize, const cpu_set_t *cpuset);
  18. #endif
  19. #if defined(IL2CPP_ENABLE_PLATFORM_THREAD_RENAME)
  20. int pthread_setname_np(pthread_t handle, const char *name);
  21. #endif
  22. #if !defined(IL2CPP_DEFAULT_STACK_SIZE)
  23. #define IL2CPP_DEFAULT_STACK_SIZE ( 1 * 1024 * 1024) // default .NET stacksize is 1mb
  24. #endif
  25. namespace il2cpp
  26. {
  27. namespace os
  28. {
  29. /// POSIX threads implementation. Supports APCs and interruptible waits.
  30. class ThreadImpl : public il2cpp::utils::NonCopyable
  31. {
  32. public:
  33. ThreadImpl();
  34. ~ThreadImpl();
  35. uint64_t Id();
  36. ErrorCode Run(Thread::StartFunc func, void* arg, int64_t affinityMask);
  37. void QueueUserAPC(Thread::APCFunc func, void* context);
  38. void SetName(const char* name);
  39. void SetPriority(ThreadPriority priority);
  40. ThreadPriority GetPriority();
  41. void SetStackSize(size_t newsize);
  42. void ReleaseSemaphore() {m_ConditionSemaphore.Release(1);}
  43. void AcquireSemaphore() {m_ConditionSemaphore.Acquire();}
  44. bool TryTimedAcquireSemaphore(uint32_t timeout) { return m_ConditionSemaphore.TryTimedAcquire(baselib::timeout_ms(timeout));}
  45. static int GetMaxStackSize();
  46. /// Handle any pending APCs.
  47. /// NOTE: Can only be called on current thread.
  48. void CheckForUserAPCAndHandle();
  49. static void Sleep(uint32_t milliseconds, bool interruptible);
  50. static uint64_t CurrentThreadId();
  51. static ThreadImpl* GetCurrentThread();
  52. static ThreadImpl* CreateForCurrentThread();
  53. static bool YieldInternal();
  54. #if IL2CPP_HAS_NATIVE_THREAD_CLEANUP
  55. static void SetNativeThreadCleanup(Thread::ThreadCleanupFunc cleanupFunction);
  56. static void RegisterCurrentThreadForCleanup(void* arg);
  57. static void UnregisterCurrentThreadForCleanup();
  58. #endif
  59. private:
  60. friend class WaitObject; // SetWaitObject(), CheckForAPCAndHandle()
  61. std::atomic<pthread_t> m_Handle;
  62. /// The synchronization primitive that this thread is currently blocked on.
  63. /// Atomic to signal intent
  64. baselib::atomic<WaitObject*> m_CurrentWaitObject;
  65. /// Start data.
  66. Thread::StartFunc m_StartFunc;
  67. void* m_StartArg;
  68. /// List of APC requests for this thread.
  69. struct APCRequest
  70. {
  71. Thread::APCFunc callback;
  72. void* context;
  73. APCRequest(Thread::APCFunc callback, void* context) :
  74. callback(callback), context(context)
  75. {
  76. }
  77. };
  78. baselib::Lock m_PendingAPCsMutex;
  79. std::vector<APCRequest> m_PendingAPCs;
  80. baselib::CappedSemaphore m_ConditionSemaphore;
  81. size_t m_StackSize; // size of stack (can not be adjusted after thread creation)
  82. /// Set the synchronization object the thread is about to wait on.
  83. /// NOTE: This can only be called on the current thread.
  84. void SetWaitObject(WaitObject* waitObject);
  85. static void* ThreadStartWrapper(void* arg);
  86. };
  87. }
  88. }
  89. #endif