Без опису
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #pragma once
  2. #if !IL2CPP_THREADS_STD && IL2CPP_THREADS_PTHREAD
  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. static void AllocateStaticData();
  36. static void FreeStaticData();
  37. uint64_t Id();
  38. ErrorCode Run(Thread::StartFunc func, void* arg, int64_t affinityMask);
  39. void QueueUserAPC(Thread::APCFunc func, void* context);
  40. void SetName(const char* name);
  41. void SetPriority(ThreadPriority priority);
  42. ThreadPriority GetPriority();
  43. void SetStackSize(size_t newsize);
  44. void ReleaseSemaphore() {m_ConditionSemaphore.Release(1);}
  45. void AcquireSemaphore() {m_ConditionSemaphore.Acquire();}
  46. bool TryTimedAcquireSemaphore(uint32_t timeout) { return m_ConditionSemaphore.TryTimedAcquire(baselib::timeout_ms(timeout));}
  47. static int GetMaxStackSize();
  48. /// Handle any pending APCs.
  49. /// NOTE: Can only be called on current thread.
  50. void CheckForUserAPCAndHandle();
  51. static void Sleep(uint32_t milliseconds, bool interruptible);
  52. static uint64_t CurrentThreadId();
  53. static ThreadImpl* GetCurrentThread();
  54. static ThreadImpl* CreateForCurrentThread();
  55. static bool YieldInternal();
  56. #if IL2CPP_HAS_NATIVE_THREAD_CLEANUP
  57. static void SetNativeThreadCleanup(Thread::ThreadCleanupFunc cleanupFunction);
  58. static void RegisterCurrentThreadForCleanup(void* arg);
  59. static void UnregisterCurrentThreadForCleanup();
  60. #endif
  61. private:
  62. friend class WaitObject; // SetWaitObject(), CheckForAPCAndHandle()
  63. std::atomic<pthread_t> m_Handle;
  64. /// The synchronization primitive that this thread is currently blocked on.
  65. /// Atomic to signal intent
  66. baselib::atomic<WaitObject*> m_CurrentWaitObject;
  67. /// Start data.
  68. Thread::StartFunc m_StartFunc;
  69. void* m_StartArg;
  70. /// List of APC requests for this thread.
  71. struct APCRequest
  72. {
  73. Thread::APCFunc callback;
  74. void* context;
  75. APCRequest(Thread::APCFunc callback, void* context) :
  76. callback(callback), context(context)
  77. {
  78. }
  79. };
  80. baselib::Lock m_PendingAPCsMutex;
  81. std::vector<APCRequest> m_PendingAPCs;
  82. baselib::CappedSemaphore m_ConditionSemaphore;
  83. size_t m_StackSize; // size of stack (can not be adjusted after thread creation)
  84. /// Set the synchronization object the thread is about to wait on.
  85. /// NOTE: This can only be called on the current thread.
  86. void SetWaitObject(WaitObject* waitObject);
  87. static void* ThreadStartWrapper(void* arg);
  88. };
  89. }
  90. }
  91. #endif