Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
tbb_thread.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2005-2019 Intel Corporation
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 
16 
17 
18 
19 */
20 
21 #if _WIN32||_WIN64
22 #include <process.h> // _beginthreadex()
23 #endif
24 #include <errno.h>
25 #include "tbb_misc.h" // handle_win_error()
26 #include "tbb/tbb_stddef.h"
27 #include "tbb/tbb_thread.h"
28 #include "tbb/tbb_allocator.h"
29 #include "tbb/global_control.h" // thread_stack_size
30 #include "governor.h" // default_num_threads()
31 #if __TBB_WIN8UI_SUPPORT
32 #include <thread>
33 #endif
34 
35 namespace tbb {
36 namespace internal {
37 
39 void* allocate_closure_v3( size_t size )
40 {
41  return allocate_via_handler_v3( size );
42 }
43 
45 void free_closure_v3( void *ptr )
46 {
48 }
49 
51 {
52  if (!joinable())
53  handle_perror( EINVAL, "tbb_thread::join" ); // Invalid argument
55  handle_perror( EDEADLK, "tbb_thread::join" ); // Resource deadlock avoided
56 #if _WIN32||_WIN64
57 #if __TBB_WIN8UI_SUPPORT
58  std::thread* thread_tmp=(std::thread*)my_thread_id;
59  thread_tmp->join();
60  delete thread_tmp;
61 #else // __TBB_WIN8UI_SUPPORT
62  DWORD status = WaitForSingleObjectEx( my_handle, INFINITE, FALSE );
63  if ( status == WAIT_FAILED )
64  handle_win_error( GetLastError() );
65  BOOL close_stat = CloseHandle( my_handle );
66  if ( close_stat == 0 )
67  handle_win_error( GetLastError() );
68  my_thread_id = 0;
69 #endif // __TBB_WIN8UI_SUPPORT
70 #else
71  int status = pthread_join( my_handle, NULL );
72  if( status )
73  handle_perror( status, "pthread_join" );
74 #endif // _WIN32||_WIN64
75  my_handle = 0;
76 }
77 
79  if (!joinable())
80  handle_perror( EINVAL, "tbb_thread::detach" ); // Invalid argument
81 #if _WIN32||_WIN64
82  BOOL status = CloseHandle( my_handle );
83  if ( status == 0 )
84  handle_win_error( GetLastError() );
85  my_thread_id = 0;
86 #else
87  int status = pthread_detach( my_handle );
88  if( status )
89  handle_perror( status, "pthread_detach" );
90 #endif // _WIN32||_WIN64
91  my_handle = 0;
92 }
93 
95  void* closure ) {
96 #if _WIN32||_WIN64
97 #if __TBB_WIN8UI_SUPPORT
98  std::thread* thread_tmp=new std::thread(start_routine, closure);
99  my_handle = thread_tmp->native_handle();
100 // TODO: to find out the way to find thread_id without GetThreadId and other
101 // desktop functions.
102 // Now tbb_thread does have its own thread_id that stores std::thread object
103  my_thread_id = (size_t)thread_tmp;
104 #else
105  unsigned thread_id;
106  // The return type of _beginthreadex is "uintptr_t" on new MS compilers,
107  // and 'unsigned long' on old MS compilers. uintptr_t works for both.
108  uintptr_t status = _beginthreadex( NULL, (unsigned)global_control::active_value(global_control::thread_stack_size),
109  start_routine, closure, 0, &thread_id );
110  if( status==0 )
111  handle_perror(errno,"__beginthreadex");
112  else {
113  my_handle = (HANDLE)status;
114  my_thread_id = thread_id;
115  }
116 #endif
117 #else
118  pthread_t thread_handle;
119  int status;
120  pthread_attr_t stack_size;
121  status = pthread_attr_init( &stack_size );
122  if( status )
123  handle_perror( status, "pthread_attr_init" );
124  status = pthread_attr_setstacksize( &stack_size, global_control::active_value(global_control::thread_stack_size) );
125  if( status )
126  handle_perror( status, "pthread_attr_setstacksize" );
127 
128  status = pthread_create( &thread_handle, &stack_size, start_routine, closure );
129  if( status )
130  handle_perror( status, "pthread_create" );
131  status = pthread_attr_destroy( &stack_size );
132  if( status )
133  handle_perror( status, "pthread_attr_destroy" );
134 
136 #endif // _WIN32||_WIN64
137 }
138 
141 }
142 
144 #if _WIN32||_WIN64
145  return tbb_thread_v3::id( GetCurrentThreadId() );
146 #else
147  return tbb_thread_v3::id( pthread_self() );
148 #endif // _WIN32||_WIN64
149 }
150 
152 {
153  if (t1.joinable())
154  t1.detach();
155  t1.my_handle = t2.my_handle;
156  t2.my_handle = 0;
157 #if _WIN32||_WIN64
158  t1.my_thread_id = t2.my_thread_id;
159  t2.my_thread_id = 0;
160 #endif // _WIN32||_WIN64
161 }
162 
164 {
165  __TBB_Yield();
166 }
167 
169 {
170 #if _WIN32||_WIN64
172  tick_count t1 = t0;
173  for(;;) {
174  double remainder = (i-(t1-t0)).seconds()*1e3; // milliseconds remaining to sleep
175  if( remainder<=0 ) break;
176  DWORD t = remainder>=INFINITE ? INFINITE-1 : DWORD(remainder);
177 #if !__TBB_WIN8UI_SUPPORT
178  Sleep( t );
179 #else
180  std::chrono::milliseconds sleep_time( t );
181  std::this_thread::sleep_for( sleep_time );
182 #endif
183  t1 = tick_count::now();
184  }
185 #else
186  struct timespec req;
187  double sec = i.seconds();
188 
189  req.tv_sec = static_cast<long>(sec);
190  req.tv_nsec = static_cast<long>( (sec - req.tv_sec)*1e9 );
191  nanosleep(&req, NULL);
192 #endif // _WIN32||_WIN64
193 }
194 
195 } // internal
196 } // tbb
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id id
static unsigned __TBB_EXPORTED_FUNC hardware_concurrency() __TBB_NOEXCEPT(true)
The number of hardware thread contexts.
Definition: tbb_thread.cpp:139
#define __TBB_NOEXCEPT(expression)
Definition: tbb_stddef.h:114
native_handle_type my_handle
Definition: tbb_thread.h:196
Absolute timestamp.
Definition: tick_count.h:38
static unsigned default_num_threads()
Definition: governor.h:85
void __TBB_EXPORTED_FUNC free_closure_v3(void *)
Free a closure allocated by allocate_closure_v3.
Definition: tbb_thread.cpp:45
Versioned thread class.
Definition: tbb_thread.h:112
#define __TBB_Yield()
Definition: ibm_aix51.h:48
void __TBB_EXPORTED_METHOD join()
The completion of the thread represented by *this happens before join() returns.
Definition: tbb_thread.cpp:50
void handle_win_error(int error_code)
Throws std::runtime_error with what() returning error_code description prefixed with aux_info.
static size_t active_value(parameter p)
thread_monitor::handle_type thread_handle
void __TBB_EXPORTED_FUNC move_v3(tbb_thread_v3 &t1, tbb_thread_v3 &t2)
Definition: tbb_thread.cpp:151
#define __TBB_NATIVE_THREAD_ROUTINE_PTR(r)
Definition: tbb_thread.h:39
void *__TBB_EXPORTED_FUNC allocate_via_handler_v3(size_t n)
Allocates memory using MallocHandler.
The graph class.
void __TBB_EXPORTED_FUNC thread_yield_v3()
Definition: tbb_thread.cpp:163
tbb_thread::id get_id()
Definition: tbb_thread.h:321
void __TBB_EXPORTED_METHOD detach()
When detach() returns, *this no longer represents the possibly continuing thread of execution.
Definition: tbb_thread.cpp:78
void __TBB_EXPORTED_FUNC deallocate_via_handler_v3(void *p)
Deallocates memory using FreeHandler.
id get_id() const __TBB_NOEXCEPT(true)
Definition: tbb_thread.h:259
void __TBB_EXPORTED_METHOD internal_start(__TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine), void *closure)
Definition: tbb_thread.cpp:94
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t size
double seconds() const
Return the length of a time interval in seconds.
Definition: tick_count.h:134
void *__TBB_EXPORTED_FUNC allocate_closure_v3(size_t size)
Allocate a closure.
Definition: tbb_thread.cpp:39
void __TBB_EXPORTED_FUNC handle_perror(int error_code, const char *aux_info)
Throws std::runtime_error with what() returning error_code description prefixed with aux_info.
Definition: tbb_misc.cpp:78
bool joinable() const __TBB_NOEXCEPT(true)
Definition: tbb_thread.h:175
Relative time interval.
Definition: tick_count.h:41
static tick_count now()
Return current time.
Definition: tick_count.h:105
tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3()
Definition: tbb_thread.cpp:143
void __TBB_EXPORTED_FUNC thread_sleep_v3(const tick_count::interval_t &i)
Definition: tbb_thread.cpp:168

Copyright © 2005-2019 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.