linux_common.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. Copyright (c) 2005-2020 Intel Corporation
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. #ifndef __TBB_machine_H
  14. #error Do not #include this internal file directly; use public TBB headers instead.
  15. #endif
  16. #include <sched.h>
  17. #define __TBB_Yield() sched_yield()
  18. #include <unistd.h>
  19. /* Futex definitions */
  20. #include <sys/syscall.h>
  21. #if defined(SYS_futex)
  22. /* This header file is included for Linux and some other systems that may support futexes.*/
  23. #define __TBB_USE_FUTEX 1
  24. #if defined(__has_include)
  25. #define __TBB_has_include __has_include
  26. #else
  27. #define __TBB_has_include(x) 0
  28. #endif
  29. /*
  30. If available, use typical headers where futex API is defined. While Linux and OpenBSD
  31. are known to provide such headers, other systems might have them as well.
  32. */
  33. #if defined(__linux__) || __TBB_has_include(<linux/futex.h>)
  34. #include <linux/futex.h>
  35. #elif defined(__OpenBSD__) || __TBB_has_include(<sys/futex.h>)
  36. #include <sys/futex.h>
  37. #endif
  38. #include <limits.h>
  39. #include <errno.h>
  40. /*
  41. Some systems might not define the macros or use different names. In such case we expect
  42. the actual parameter values to match Linux: 0 for wait, 1 for wake.
  43. */
  44. #if defined(FUTEX_WAIT_PRIVATE)
  45. #define __TBB_FUTEX_WAIT FUTEX_WAIT_PRIVATE
  46. #elif defined(FUTEX_WAIT)
  47. #define __TBB_FUTEX_WAIT FUTEX_WAIT
  48. #else
  49. #define __TBB_FUTEX_WAIT 0
  50. #endif
  51. #if defined(FUTEX_WAKE_PRIVATE)
  52. #define __TBB_FUTEX_WAKE FUTEX_WAKE_PRIVATE
  53. #elif defined(FUTEX_WAKE)
  54. #define __TBB_FUTEX_WAKE FUTEX_WAKE
  55. #else
  56. #define __TBB_FUTEX_WAKE 1
  57. #endif
  58. #ifndef __TBB_ASSERT
  59. #error machine specific headers must be included after tbb_stddef.h
  60. #endif
  61. namespace tbb {
  62. namespace internal {
  63. inline int futex_wait( void *futex, int comparand ) {
  64. int r = syscall( SYS_futex,futex,__TBB_FUTEX_WAIT,comparand,NULL,NULL,0 );
  65. #if TBB_USE_ASSERT
  66. int e = errno;
  67. __TBB_ASSERT( r==0||r==EWOULDBLOCK||(r==-1&&(e==EAGAIN||e==EINTR)), "futex_wait failed." );
  68. #endif /* TBB_USE_ASSERT */
  69. return r;
  70. }
  71. inline int futex_wakeup_one( void *futex ) {
  72. int r = ::syscall( SYS_futex,futex,__TBB_FUTEX_WAKE,1,NULL,NULL,0 );
  73. __TBB_ASSERT( r==0||r==1, "futex_wakeup_one: more than one thread woken up?" );
  74. return r;
  75. }
  76. inline int futex_wakeup_all( void *futex ) {
  77. int r = ::syscall( SYS_futex,futex,__TBB_FUTEX_WAKE,INT_MAX,NULL,NULL,0 );
  78. __TBB_ASSERT( r>=0, "futex_wakeup_all: error in waking up threads" );
  79. return r;
  80. }
  81. } /* namespace internal */
  82. } /* namespace tbb */
  83. #endif /* SYS_futex */