2
0

Threading.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. //===-- llvm/Support/Threading.cpp- Control multithreading mode --*- C++ -*-==//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines helper functions for running LLVM in a multi-threaded
  11. // environment.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "llvm/Support/Threading.h"
  15. #include "llvm/Config/config.h"
  16. #include "llvm/Support/Atomic.h"
  17. #include "llvm/Support/Mutex.h"
  18. #include <cassert>
  19. using namespace llvm;
  20. bool llvm::llvm_is_multithreaded() {
  21. #if LLVM_ENABLE_THREADS != 0
  22. return true;
  23. #else
  24. return false;
  25. #endif
  26. }
  27. #if LLVM_ENABLE_THREADS != 0 && defined(HAVE_PTHREAD_H)
  28. #include <pthread.h>
  29. struct ThreadInfo {
  30. void (*UserFn)(void *);
  31. void *UserData;
  32. };
  33. static void *ExecuteOnThread_Dispatch(void *Arg) {
  34. ThreadInfo *TI = reinterpret_cast<ThreadInfo*>(Arg);
  35. TI->UserFn(TI->UserData);
  36. return nullptr;
  37. }
  38. void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData,
  39. unsigned RequestedStackSize) {
  40. ThreadInfo Info = { Fn, UserData };
  41. pthread_attr_t Attr;
  42. pthread_t Thread;
  43. // Construct the attributes object.
  44. if (::pthread_attr_init(&Attr) != 0)
  45. return;
  46. // Set the requested stack size, if given.
  47. if (RequestedStackSize != 0) {
  48. if (::pthread_attr_setstacksize(&Attr, RequestedStackSize) != 0)
  49. goto error;
  50. }
  51. // Construct and execute the thread.
  52. if (::pthread_create(&Thread, &Attr, ExecuteOnThread_Dispatch, &Info) != 0)
  53. goto error;
  54. // Wait for the thread and clean up.
  55. ::pthread_join(Thread, nullptr);
  56. error:
  57. ::pthread_attr_destroy(&Attr);
  58. }
  59. #elif LLVM_ENABLE_THREADS!=0 && defined(LLVM_ON_WIN32)
  60. #include "Windows/WindowsSupport.h"
  61. #include <process.h>
  62. struct ThreadInfo {
  63. void (*func)(void*);
  64. void *param;
  65. };
  66. static unsigned __stdcall ThreadCallback(void *param) {
  67. struct ThreadInfo *info = reinterpret_cast<struct ThreadInfo *>(param);
  68. info->func(info->param);
  69. return 0;
  70. }
  71. void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData,
  72. unsigned RequestedStackSize) {
  73. struct ThreadInfo param = { Fn, UserData };
  74. HANDLE hThread = (HANDLE)::_beginthreadex(NULL,
  75. RequestedStackSize, ThreadCallback,
  76. &param, 0, NULL);
  77. if (hThread) {
  78. // We actually don't care whether the wait succeeds or fails, in
  79. // the same way we don't care whether the pthread_join call succeeds
  80. // or fails. There's not much we could do if this were to fail. But
  81. // on success, this call will wait until the thread finishes executing
  82. // before returning.
  83. (void)::WaitForSingleObject(hThread, INFINITE);
  84. ::CloseHandle(hThread);
  85. }
  86. }
  87. #else
  88. // Support for non-Win32, non-pthread implementation.
  89. void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData,
  90. unsigned RequestedStackSize) {
  91. (void) RequestedStackSize;
  92. Fn(UserData);
  93. }
  94. #endif