BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslmt_threadutil.h
Go to the documentation of this file.
1/// @file bslmt_threadutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmt_threadutil.h -*-C++-*-
8#ifndef INCLUDED_BSLMT_THREADUTIL
9#define INCLUDED_BSLMT_THREADUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmt_threadutil bslmt_threadutil
15/// @brief Provide platform-independent utilities related to threading.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmt
19/// @{
20/// @addtogroup bslmt_threadutil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmt_threadutil-purpose"> Purpose</a>
25/// * <a href="#bslmt_threadutil-classes"> Classes </a>
26/// * <a href="#bslmt_threadutil-description"> Description </a>
27/// * <a href="#bslmt_threadutil-creating-a-simple-thread-with-default-attributes"> Creating a Simple Thread with Default Attributes </a>
28/// * <a href="#bslmt_threadutil-thread-identity"> Thread Identity </a>
29/// * <a href="#bslmt_threadutil-setting-thread-priorities"> Setting Thread Priorities </a>
30/// * <a href="#bslmt_threadutil-supported-clock-types"> Supported Clock-Types </a>
31/// * <a href="#bslmt_threadutil-usage"> Usage </a>
32/// * <a href="#bslmt_threadutil-example-1-creating-a-simple-thread-with-default-attributes"> Example 1: Creating a Simple Thread with Default Attributes </a>
33/// * <a href="#bslmt_threadutil-example-2-creating-a-simple-thread-with-user-specified-attributes"> Example 2: Creating a Simple Thread with User-Specified Attributes </a>
34/// * <a href="#bslmt_threadutil-example-3-setting-thread-priorities"> Example 3: Setting Thread Priorities </a>
35///
36/// # Purpose {#bslmt_threadutil-purpose}
37/// Provide platform-independent utilities related to threading.
38///
39/// # Classes {#bslmt_threadutil-classes}
40///
41/// - bslmt::ThreadUtil: namespace for portable thread management utilities
42///
43/// @see bslmt_threadattributes, bslmt_configuration
44///
45/// # Description {#bslmt_threadutil-description}
46/// This component defines a utility `struct`, `bslmt::ThreadUtil`,
47/// that serves as a name space for a suite of pure functions to create threads,
48/// join them (make one thread block and wait for another thread to exit),
49/// manipulate thread handles, manipulate the current thread, and (on some
50/// platforms) access thread-local storage.
51///
52/// ## Creating a Simple Thread with Default Attributes {#bslmt_threadutil-creating-a-simple-thread-with-default-attributes}
53///
54///
55/// Clients call `bslmt::ThreadUtil::create()` to create threads. Threads may
56/// be started using a "C" linkage function pointer (of a type defined by
57/// `bslmt::ThreadUtil::ThreadFunction`) and a `void` pointer to `userData` to
58/// be passed to the function; or an "invokable" object of parameterized type
59/// (any copy-constructible type on which `operator()` may be invoked). The
60/// invoked function becomes the main driver for the new thread; when it
61/// returns, the thread terminates.
62///
63/// ## Thread Identity {#bslmt_threadutil-thread-identity}
64///
65///
66/// A thread is identified by an object of the opaque type
67/// `bslmt::ThreadUtil::Handle`. A handle of this type is returned when a
68/// thread is created (using `bslmt::ThreadUtil::create`). A client can also
69/// retrieve a `Handle` for the "current" thread via the `self` method:
70/// @code
71/// bslmt::ThreadUtil::Handle myHandle = bslmt::ThreadUtil::self();
72/// @endcode
73/// Several thread manipulation functions in `bslmt::ThreadUtil` take a thread
74/// handle, or pointer to a thread handle, as an argument. To facilitate
75/// compatibility with existing systems and allow for non-portable operations,
76/// clients also have access to the `bslmt::ThreadUtil::NativeHandle` type,
77/// which exposes the underlying, platform-specific thread identifier type:
78/// @code
79/// bslmt::ThreadUtil::NativeHandle myNativeHandle;
80/// myNativeHandle = bslmt::ThreadUtil::nativeHandle();
81/// @endcode
82/// Note that the returned native handle may not be a globally unique identifier
83/// for the thread, and, e.g., should not be converted to an integer identifier,
84/// or used as a key in a map.
85///
86/// ## Setting Thread Priorities {#bslmt_threadutil-setting-thread-priorities}
87///
88///
89/// `bslmt::ThreadUtil` allows clients to configure the priority of newly
90/// created threads by setting the `inheritSchedule`, `schedulingPolicy`, and
91/// `schedulingPriority` of a thread attributes object supplied to the `create`
92/// method. The range of legal values for `schedulingPriority` depends on both
93/// the platform and the value of `schedulingPolicy`, and can be obtained from
94/// the `getMinSchedulingPriority` and `getMaxSchedulingPriority` methods. Both
95/// `schedulingPolicy` and `schedulingPriority` are ignored unless
96/// `inheritSchedule` is `false` (the default value is `true`). Note that not
97/// only is effective setting of thread priorities workable on only some
98/// combinations of platforms and user privileges, but setting the thread policy
99/// and priority appropriately for one platform may cause thread creation to
100/// fail on another platform. Also note that an unset thread priority may be
101/// interpreted as being outside the valid range defined by
102/// `[ getMinSchedulingPriority(policy), getMaxSchedulingPriority(policy) ]`.
103/// @code
104/// Platform Restrictions
105/// ------------ --------------------------------------------------------------
106/// Solaris 5.10 None.
107///
108/// Solaris 5.11 Spawning of threads fails if `schedulingPolicy` is
109/// `BSLMT_SCHED_FIFO` or `BSLMT_SCHED_RR`. Thread priorities
110/// should not be used on Solaris 5.11 as it is not clear that
111/// they have any detectable effect. Note that
112/// `getMinSchedulingPriority` and `getMaxSchedulingPriority`
113/// return different values than on Solaris 5.10.
114///
115/// AIX For non-privileged clients, spawning of threads fails if
116/// `schedulingPolicy` is `BSLMT_SCHED_FIFO` or `BSLMT_SCHED_RR`.
117///
118/// Linux Non-privileged clients *can* *not* make effective use of
119/// thread priorities -- spawning of threads fails if
120/// `schedulingPolicy` is `BSLMT_SCHED_FIFO` or `BSLMT_SCHED_RR`,
121/// and `getMinSchedulingPriority == getMaxSchedulingPriority` if
122/// the policy has any other value.
123///
124/// Darwin Non-privileged clients *can* *not* make effective use of
125/// thread priorities -- there is no observable difference in
126/// urgency between high priority and low priority threads.
127/// Spawning of threads does succeed, however, for all scheduling
128/// policies.
129///
130/// Windows Clients *can* *not* make effective use of thread priorities --
131/// `schedulingPolicy`, `schedulingPriority`, and
132/// `inheritSchedule` are ignored for all clients.
133/// @endcode
134///
135/// ## Supported Clock-Types {#bslmt_threadutil-supported-clock-types}
136///
137///
138/// `bsls::SystemClockType` supplies the enumeration indicating the system clock
139/// on which timeouts supplied to other methods should be based. If the clock
140/// type indicated at construction is `bsls::SystemClockType::e_REALTIME`, the
141/// `absTime` argument passed to the `timedWait` method of the various
142/// synchronization primitives offered in `bslmt` should be expressed as an
143/// *absolute* offset since 00:00:00 UTC, January 1, 1970 (which matches the
144/// epoch used in `bsls::SystemTime::now(bsls::SystemClockType::e_REALTIME)`.
145/// If the clock type indicated at construction is
146/// `bsls::SystemClockType::e_MONOTONIC`, the `absTime` argument passed to the
147/// `timedWait` method of the various synchronization primitives offered in
148/// `bslmt` should be expressed as an *absolute* offset since the epoch of this
149/// clock (which matches the epoch used in
150/// `bsls::SystemTime::now(bsls::SystemClockType::e_MONOTONIC)`.
151///
152/// ## Usage {#bslmt_threadutil-usage}
153///
154///
155/// This section illustrates the intended use of this component.
156///
157/// ### Example 1: Creating a Simple Thread with Default Attributes {#bslmt_threadutil-example-1-creating-a-simple-thread-with-default-attributes}
158///
159///
160/// In this example, we create a thread using the default attribute settings.
161/// Upon creation, the thread executes the user-supplied C-linkage function
162/// `myThreadFunction` that counts 5 seconds before terminating:
163///
164/// First, we create a function that will run in the spawned thread:
165/// @code
166/// /// Print to standard output "Another second has passed" every second
167/// /// for five seconds, and return 0.
168/// extern "C" void *myThreadFunction(void *)
169/// {
170/// for (int i = 0; i < 3; ++i) {
171/// bslmt::ThreadUtil::microSleep(0, 1);
172/// bsl::cout << "Another second has passed." << bsl::endl;
173/// }
174/// return 0;
175/// }
176/// @endcode
177/// Now, we show how to create and join the thread.
178///
179/// After creating the thread, the `main` routine *joins* the thread, which, in
180/// effect, causes `main` to wait for execution of `myThreadFunction` to
181/// complete, and guarantees that the output from `main` will follow the last
182/// output from the user-supplied function:
183/// @code
184/// int main()
185/// {
186/// bslmt::Configuration::setDefaultThreadStackSize(
187/// bslmt::Configuration::recommendedDefaultThreadStackSize());
188///
189/// bslmt::ThreadUtil::Handle handle;
190///
191/// bslmt::ThreadAttributes attr;
192/// attr.setStackSize(1024 * 1024);
193///
194/// int rc = bslmt::ThreadUtil::create(&handle, attr, myThreadFunction, 0);
195/// assert(0 == rc);
196///
197/// bslmt::ThreadUtil::yield();
198///
199/// rc = bslmt::ThreadUtil::join(handle);
200/// assert(0 == rc);
201///
202/// bsl::cout << "A three second interval has elapsed\n";
203///
204/// return 0;
205/// }
206/// @endcode
207/// Finally, the output of this program is:
208/// @code
209/// Another second has passed.
210/// Another second has passed.
211/// Another second has passed.
212/// A three second interval has elapsed.
213/// @endcode
214///
215/// ### Example 2: Creating a Simple Thread with User-Specified Attributes {#bslmt_threadutil-example-2-creating-a-simple-thread-with-user-specified-attributes}
216///
217///
218/// In this example, we will choose to override the default thread attribute
219/// values.
220///
221/// The attributes of a thread can be specified explicitly by supplying a
222/// `bslmt::ThreadAttributes` object to the `create` method. For instance, we
223/// could specify a smaller stack size for a thread to conserve system resources
224/// if we know that we will require not require the platform's default stack
225/// size.
226///
227/// First, we define our thread function, noting that it doesn't need much stack
228/// space:
229/// @code
230/// /// Initialize a small object on the stack and do some work.
231/// extern "C" void *mySmallStackThreadFunction(void *threadArg)
232/// {
233/// char *initValue = (char *)threadArg;
234/// char Small[8];
235/// bsl::memset(&Small[0], *initValue, 8);
236/// // do some work ...
237/// return 0;
238/// }
239/// @endcode
240/// Finally, we show how to create a detached thread running the function just
241/// created with a small stack size:
242/// @code
243/// /// Create a detached thread with a small stack size and perform some work.
244/// void createSmallStackSizeThread()
245/// {
246/// enum { k_STACK_SIZE = 16384 };
247/// bslmt::ThreadAttributes attributes;
248/// attributes.setDetachedState(
249/// bslmt::ThreadAttributes::e_CREATE_DETACHED);
250/// attributes.setStackSize(k_STACK_SIZE);
251///
252/// char initValue = 1;
253/// bslmt::ThreadUtil::Handle handle;
254/// int status = bslmt::ThreadUtil::create(&handle,
255/// attributes,
256/// mySmallStackThreadFunction,
257/// &initValue);
258/// }
259/// @endcode
260///
261/// ### Example 3: Setting Thread Priorities {#bslmt_threadutil-example-3-setting-thread-priorities}
262///
263///
264/// In this example we demonstrate creating 3 threads with different priorities.
265/// We use the `convertToSchedulingPriority` function to translate a normalized,
266/// floating-point priority in the range `[ 0.0, 1.0 ]` to an integer priority
267/// in the range `[ getMinSchedulingPriority, getMaxSchedulingPriority ]` to set
268/// the `schedulingPriority` attribute.
269/// @code
270/// /// Create 3 threads with different priorities and then wait for them
271/// /// all to finish.
272/// void runSeveralThreads()
273/// {
274/// enum { k_NUM_THREADS = 3 };
275///
276/// bslmt::ThreadUtil::Handle handles[k_NUM_THREADS];
277/// bslmt_ThreadFunction functions[k_NUM_THREADS] = {
278/// MostUrgentThreadFunctor,
279/// FairlyUrgentThreadFunctor,
280/// LeastUrgentThreadFunctor };
281/// double priorities[k_NUM_THREADS] = { 1.0, 0.5, 0.0 };
282///
283/// bslmt::ThreadAttributes attributes;
284/// attributes.setInheritSchedule(false);
285/// const bslmt::ThreadAttributes::SchedulingPolicy policy =
286/// bslmt::ThreadAttributes::e_SCHED_OTHER;
287/// attributes.setSchedulingPolicy(policy);
288///
289/// for (int i = 0; i < k_NUM_THREADS; ++i) {
290/// attributes.setSchedulingPriority(
291/// bslmt::ThreadUtil::convertToSchedulingPriority(policy,
292/// priorities[i]));
293/// int rc = bslmt::ThreadUtil::create(&handles[i],
294/// attributes,
295/// functions[i], 0);
296/// assert(0 == rc);
297/// }
298///
299/// for (int i = 0; i < k_NUM_THREADS; ++i) {
300/// int rc = bslmt::ThreadUtil::join(handles[i]);
301/// assert(0 == rc);
302/// }
303/// }
304/// @endcode
305/// @}
306/** @} */
307/** @} */
308
309/** @addtogroup bsl
310 * @{
311 */
312/** @addtogroup bslmt
313 * @{
314 */
315/** @addtogroup bslmt_threadutil
316 * @{
317 */
318
319#include <bslscm_version.h>
320
322#include <bslmt_platform.h>
326
327#include <bsla_maybeunused.h>
328
329#include <bslma_allocator.h>
330#include <bslma_default.h>
331
332#include <bsls_assert.h>
333#include <bsls_keyword.h>
334#include <bsls_libraryfeatures.h>
335#include <bsls_systemclocktype.h>
336#include <bsls_systemtime.h>
337#include <bsls_timeinterval.h>
338#include <bsls_types.h>
339
340#include <bsl_string.h>
341
342#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
343#include <bslmt_chronoutil.h>
344
345#include <bsl_chrono.h>
346#endif
347
348
349
350extern "C" {
351 /// `bslmt_ThreadFunction` is an alias for a function type taking a
352 /// single `void` pointer argument and returning `void *`. Such
353 /// functions are suitable to be specified as thread entry-point functions to `bslmt::ThreadUtil::create`.
354 ///
355 /// \note Note that `create` also
356 /// accepts any invokable C++ "functor" object.
357 typedef void *(*bslmt_ThreadFunction)(void *);
358
359 /// `bslmt_KeyDestructorFunction` is an alias for a function type taking
360 /// a single `void` pointer argument and returning `void`. Such
361 /// functions are suitable to be specified as thread-specific key
362 /// destructor functions to `bslmt::ThreadUtil::createKey`.
363 typedef void (*bslmt_KeyDestructorFunction)(void *);
364} // extern "C"
365
366namespace bslmt {
367
368template <class THREAD_POLICY>
369struct ThreadUtilImpl;
370
371 // =================
372 // struct ThreadUtil
373 // =================
374
375/// This `struct` provides a suite of portable utility functions for
376/// managing threads.
377///
378/// See @ref bslmt_threadutil
380
381 public:
382 // PUBLIC TYPES
383
384 /// Platform-specific implementation type.
386
387 /// Thread handle type. Use this type to refer to a thread in a
388 /// platform-independent way.
389 typedef Imp::Handle Handle;
390
391 /// Platform-specific thread handle type.
392 typedef Imp::NativeHandle NativeHandle;
393
394 /// Thread identifier type - distinguished from a `Handle` in that it
395 /// does not have any resources associated with it, whereas `Handle`
396 /// may, depending on platform.
397 typedef Imp::Id Id;
398
399 /// Prototype for thread entry-point functions.
401
402 /// Thread-specific key type, used to refer to thread-specific storage.
403 typedef Imp::Key Key;
404
405 /// Prototype for thread-specific key destructors.
407
408 /// Counts down the limit counter set by `ThreadUtil::setThreadLimit`.
409 /// Returns `true` if current thread creation attempt should be failed.
410 ///
411 /// \note Note that if the thread limit is reached, all future thread creation
412 /// attempts will fail, unless the limit is reset by a call to
413 /// `setThreadLimit`.
414 static bool isThreadLimitReached();
415
416 public:
417 // PUBLIC CLASS METHODS
418 // *** Thread Management ***
419
420 /// Return an integer scheduling priority appropriate for the specified
421 /// `normalizedSchedulingPriority` and the specified `policy`. If
422 /// either the minimum or maximum priority for this platform cannot be
423 /// determined, return `ThreadAttributes::e_UNSET_PRIORITY`. Higher
424 /// values of `normalizedSchedulingPriority` are considered to represent more urgent priorities.
425 ///
426 /// \pre The behavior is undefined unless `policy`
427 /// is a valid `ThreadAttributes::SchedulingPolicy` and
428 /// `normalizedSchedulingPriority` is in the range `[ 0.0, 1.0 ]`.
431 double normalizedSchedulingPriority);
432
433 /// Create a new thread of program control whose entry point will be the
434 /// specified `function`, and which will be passed the specified
435 /// `userData` as its sole argument, and load into the specified
436 /// `handle` an identifier that may be used to refer to this thread in
437 /// calls to other `ThreadUtil` methods. Optionally specify
438 /// `attributes` describing the properties for the new thread. If
439 /// `attributes` is not supplied, a default `ThreadAttributes` object is
440 /// used. Use the global allocator to supply memory. Return 0 on
441 /// success, and a non-zero value otherwise. `bslmt::Configuration` is
442 /// used to determine the created thread's default stack-size if either
443 /// `attributes` is not supplied or if `attributes.stackSize()` has the unset value.
444 ///
445 /// \pre The behavior is undefined unless `attributes`, if
446 /// specified, has a `stackSize` that is either greater than 0 or `e_UNSET_STACK_SIZE`.
447 ///
448 /// \note Note that unless the created thread is
449 /// explicitly "detached" (by invoking the `detach` class method with
450 /// `handle`) or the `k_CREATE_DETACHED` attribute is specified, a call
451 /// to `join` must be made to reclaim any system resources associated
452 /// with the newly-created thread. Also note that users are encouraged
453 /// to either explicitly provide a stack size attribute, or configure a
454 /// `bslmt`-wide default using `bslmt::Configuration`, because the
455 /// default stack size is surprisingly small on some platforms.
456 static int create(Handle *handle,
457 ThreadFunction function,
458 void *userData);
459 static int create(Handle *handle,
460 const ThreadAttributes& attributes,
461 ThreadFunction function,
462 void *userData);
463
464 /// Create a new thread of program control whose entry point will invoke
465 /// the specified `function` object, and load into the specified
466 /// `handle` an identifier that may be used to refer to this thread in
467 /// calls to other `ThreadUtil` methods. Optionally specify
468 /// `attributes` describing the properties for the new thread. If
469 /// `attributes` is not supplied, a default `ThreadAttributes` object is
470 /// used. Use the global allocator to supply memory. Return 0 on
471 /// success, and a non-zero value otherwise. `function` shall be a
472 /// reference to a type, `INVOKABLE`, that can be copy-constructed, and
473 /// where the expression `(void)function()` will execute a function call
474 /// (i.e., either a `void()()` function, or a functor object
475 /// implementing `void operator()()`). `bslmt::Configuration` is used
476 /// to determine the created thread's default stack-size if either
477 /// `attributes` is not supplied or if `attributes.stackSize()` has the unset value.
478 ///
479 /// \pre The behavior is undefined unless `attributes`, if
480 /// specified, has a `stackSize` that is either greater than 0 or `e_UNSET_STACK_SIZE`.
481 ///
482 /// \note Note that unless the created thread is
483 /// explicitly "detached" (by invoking the `detach` class method with
484 /// `handle`) or the `k_CREATE_DETACHED` attribute is specified, a call
485 /// to `join` must be made to reclaim any system resources associated
486 /// with the newly-created thread. Also note that users are encouraged
487 /// to either explicitly provide a stack size attribute, or configure a
488 /// `bslmt`-wide default using `bslmt::Configuration`, because the
489 /// default stack size is surprisingly small on some platforms.
490 template <class INVOKABLE>
491 static int create(Handle *handle,
492 const INVOKABLE& function);
493 template <class INVOKABLE>
494 static int create(Handle *handle,
495 const ThreadAttributes& attributes,
496 const INVOKABLE& function);
497
498 /// Create a new thread of program control whose entry point will be the
499 /// specified `function`, and which will be passed the specified
500 /// `userData` as its sole argument, and load into the specified
501 /// `handle` an identifier that may be used to refer to this thread in
502 /// calls to other `ThreadUtil` methods. Optionally specify
503 /// `attributes` describing the properties for the new thread. If
504 /// `attributes` is not supplied, a default `ThreadAttributes` object is
505 /// used. Use the specified `allocator` to supply memory. Return 0 on
506 /// success, and a non-zero value otherwise. `bslmt::Configuration` is
507 /// used to determine the created thread's default stack-size if either
508 /// `attributes` is not supplied or if `attributes.stackSize()` has the unset value.
509 ///
510 /// \pre The behavior is undefined unless `attributes`, if
511 /// specified, has a `stackSize` that is either greater than 0 or `e_UNSET_STACK_SIZE`.
512 ///
513 /// \note Note that unless the created thread is
514 /// explicitly "detached" (by invoking the `detach` class method with
515 /// `handle`) or the `k_CREATE_DETACHED` attribute is specified, a call
516 /// to `join` must be made to reclaim any system resources associated
517 /// with the newly-created thread. Also note that users are encouraged
518 /// to either explicitly provide a stack size attribute, or configure a
519 /// `bslmt`-wide default using `bslmt::Configuration`, because the
520 /// default stack size is surprisingly small on some platforms.
521 static int createWithAllocator(Handle *handle,
522 ThreadFunction function,
523 void *userData,
524 bslma::Allocator *allocator);
525 static int createWithAllocator(Handle *handle,
526 const ThreadAttributes& attributes,
527 ThreadFunction function,
528 void *userData,
529 bslma::Allocator *allocator);
530
531 /// Create a new thread of program control whose entry point will invoke
532 /// the specified `function` object (using the specified `allocator` to
533 /// supply memory to copy `function`), and load into the specified
534 /// `handle` an identifier that may be used to refer to this thread in
535 /// calls to other `ThreadUtil` methods. Optionally specify
536 /// `attributes` describing the properties for the new thread. If
537 /// `attributes` is not supplied, a default `ThreadAttributes` object is
538 /// used. Return 0 on success, and a non-zero value otherwise.
539 /// `function` shall be a reference to a type, `INVOKABLE`, that can be
540 /// copy-constructed, and where the expression `(void)function()` will
541 /// execute a function call (i.e., either a `void()()` function, or a
542 /// functor object implementing `void operator()()`).
543 /// `bslmt::Configuration` is used to determine the created thread's
544 /// default stack-size if either `attributes` is not supplied or if
545 /// `attributes.stackSize()` has the unset value.
546 ///
547 /// \pre The behavior is undefined unless `attributes`, if specified, has a `stackSize` that is either greater than 0 or `e_UNSET_STACK_SIZE`.
548 ///
549 /// \note Note that unless
550 /// the created thread is explicitly "detached" (by invoking the
551 /// `detach` class method with `handle`) or the `k_CREATE_DETACHED`
552 /// attribute is specified, a call to `join` must be made to reclaim any
553 /// system resources associated with the newly-created thread. Also
554 /// note that the lifetime of `allocator` must exceed the lifetime of
555 /// the thread. Also note that users are encouraged to either
556 /// explicitly provide a stack size attribute, or configure a
557 /// `bslmt`-wide default using `bslmt::Configuration`, because the
558 /// default stack size is surprisingly small on some platforms.
559 template <class INVOKABLE>
560 static int createWithAllocator(Handle *handle,
561 const INVOKABLE& function,
562 bslma::Allocator *allocator);
563 template <class INVOKABLE>
564 static int createWithAllocator(Handle *handle,
565 const ThreadAttributes& attributes,
566 const INVOKABLE& function,
567 bslma::Allocator *allocator);
568
569 /// "Detach" the thread identified by the specified `handle` such that
570 /// when it terminates, the resources associated with that thread will automatically be reclaimed.
571 ///
572 /// \pre The behavior is undefined unless
573 /// `handle` was obtained by a call to `create` or `self`.
574 ///
575 /// \note Note that once a thread is "detached", it is no longer possible to `join` the
576 /// thread to retrieve its exit status.
577 static int detach(Handle& handle);
578
579 /// Exit the current thread and return the specified `status`. If the
580 /// current thread is not "detached", then a call to `join` must be made
581 /// to reclaim any resources used by the thread, and to retrieve the exit status.
582 ///
583 /// \note Note that the preferred method of exiting a thread is
584 /// to return from the entry point function.
585 static void exit(void *status);
586
587 /// Return the minimum available priority for the specified `policy`,
588 /// where `policy` is of type `ThreadAttributes::SchedulingPolicy`.
589 /// Return `ThreadAttributes::e_UNSET_PRIORITY` if the minimum scheduling priority cannot be determined.
590 ///
591 /// \note Note that, for some
592 /// platform / policy combinations, `getMinSchedulingPriority(policy)`
593 /// and `getMaxSchedulingPriority(policy)` return the same value.
594 static int getMinSchedulingPriority(
596
597 /// Return the maximum available priority for the specified `policy`,
598 /// where `policy` is of type `ThreadAttributes::SchedulingPolicy`.
599 /// Return `ThreadAttributes::e_UNSET_PRIORITY` if the maximum scheduling priority cannot be determined.
600 ///
601 /// \note Note that, for some
602 /// platform / policy combinations, `getMinSchedulingPriority(policy)`
603 /// and `getMaxSchedulingPriority(policy)` return the same value.
604 static int getMaxSchedulingPriority(
606
607 /// Load the name of the current thread into the specified `*threadName`.
608 ///
609 /// \note Note that this method clears `*threadName` on
610 /// platforms other than Linux, Solaris, Darwin, and Windows.
611 static void getThreadName(bsl::string *threadName);
612
613 /// Suspend execution of the current thread until the thread referred to
614 /// by the specified `threadHandle` terminates, and reclaim any system
615 /// resources associated with `threadHandle`. Return 0 on success, and
616 /// a non-zero value otherwise. If the optionally specified `status` is
617 /// not 0, load into `*status` the value returned by the function
618 /// supplied at the creation of the thread identified by `threadHandle`.
619 ///
620 /// \pre The behavior is undefined unless `threadHandle` was obtained by a
621 /// call to `create`.
622 static int join(Handle& threadHandle, void **status = 0);
623
624 /// Suspend execution of the current thread for a period of at least the
625 /// specified `microseconds` and the optionally specified `seconds`
626 /// (relative time), or an interrupting signal is received.
627 ///
628 /// \note Note that the actual time suspended depends on many factors including system
629 /// scheduling and system timer resolution, and may be significantly
630 /// longer than the time requested.
631 static void microSleep(int microseconds, int seconds = 0);
632
633 /// Set the name of the current thread to the specified `threadName`.
634 /// On platforms other than Linux, Solaris, Darwin and Windows this method has no effect.
635 ///
636 /// \note Note that on those two platforms `threadName`
637 /// will be truncated to a length of 15 bytes, not including the
638 /// terminating '\0'.
639 static void setThreadName(const bslstl::StringRef& threadName);
640
641 /// Suspend execution of the current thread for a period of at least the
642 /// specified (relative) `sleepTime`, or an interrupting signal is received.
643 ///
644 /// \note Note that the actual time suspended depends on many
645 /// factors including system scheduling and system timer resolution.
646 static void sleep(const bsls::TimeInterval& sleepTime);
647
648#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
649 /// Suspend execution of the current thread for a period of at least the
650 /// specified (relative) `sleepTime`, or an interrupting signal is received.
651 ///
652 /// \note Note that the actual time suspended depends on many
653 /// factors including system scheduling and system timer resolution.
654 template <class REP_TYPE, class PERIOD_TYPE>
655 static void sleep(
656 const bsl::chrono::duration<REP_TYPE, PERIOD_TYPE>& sleepTime);
657#endif
658
659 /// Suspend execution of the current thread until the specified
660 /// `absoluteTime`, or an interrupting signal is received. Optionally
661 /// specify `clockType` which determines the epoch from which the
662 /// interval `absoluteTime` is measured (see {Supported Clock-Types} in the component documentation).
663 ///
664 /// \pre The behavior is undefined unless
665 /// `absoluteTime` represents a time after January 1, 1970 and before
666 /// the end of December 31, 9999 (i.e., a time interval greater than or equal to 0, and less than 253,402,300,800 seconds).
667 ///
668 /// \note Note that the
669 /// actual time suspended depends on many factors including system
670 /// scheduling and system timer resolution.
671 static void sleepUntil(const bsls::TimeInterval& absoluteTime,
674
675#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
676 /// Suspend execution of the current thread until the specified
677 /// `absoluteTime`, which is an *absolute* time represented as an
678 /// interval from some epoch, determined by the clock associated with the time point.
679 ///
680 /// \pre The behavior is undefined unless `absoluteTime`
681 /// represents a time after January 1, 1970 and before the end of December 31, 9999.
682 ///
683 /// \note Note that the actual time suspended depends on
684 /// many factors including system scheduling and system timer
685 /// resolution.
686 template <class CLOCK, class DURATION>
687 static void sleepUntil(
688 const bsl::chrono::time_point<CLOCK, DURATION>& absoluteTime);
689#endif
690
691 /// Move the current thread to the end of the scheduler's queue and schedule another thread to run.
692 ///
693 /// \note Note that this allows cooperating
694 /// threads of the same priority to share CPU resources equally.
695 static void yield();
696
697 // *** Thread Identification ***
698
699 /// Return `true` if the specified `a` and `b` thread handles identify
700 /// the same thread, or if both `a` and `b` are invalid handles, and `false` otherwise.
701 ///
702 /// \note Note that if *either* of `a` or `b` is an
703 /// invalid handle, but not both, this method returns `false`.
704 static bool areEqual(const Handle& a, const Handle& b);
705
706 /// Return `true` if the specified `a` thread identifier is associated
707 /// with the same thread as the specified `b` thread identifier, and
708 /// `false` otherwise.
709 static bool areEqualId(const Id& a, const Id& b);
710
711 /// Return the unique identifier of the thread having the specified
712 /// `threadHandle` within the current process.
713 ///
714 /// \pre The behavior is undefined unless `handle` was obtained by a call to `create` or `self`.
715 ///
716 /// \note Note that this value is valid only until the thread
717 /// terminates, and may be reused thereafter.
718 static Id handleToId(const Handle& threadHandle);
719
720 /// Return the unique integral identifier of a thread uniquely
721 /// identified by the specified `threadId` within the current process.
722 ///
723 /// \note Note that this representation is particularly useful for logging
724 /// purposes. Also note that this value is only valid until the thread
725 /// terminates and may be reused thereafter.
726 static bsls::Types::Uint64 idAsUint64(const Id& threadId);
727
728 /// Return the unique integral identifier of a thread uniquely
729 /// identified by the specified `threadId` within the current process.
730 ///
731 /// \note Note that this representation is particularly useful for logging
732 /// purposes. Also note that this value is only valid until the thread
733 /// terminates and may be reused thereafter.
734 ///
735 /// DEPRECATED: use `idAsUint64`.
736 static int idAsInt(const Id& threadId);
737
738 /// Return a reference to the non-modifiable `Handle` object that is
739 /// guaranteed never to be a valid thread handle.
740 static const Handle& invalidHandle();
741
742 /// Return `true` if the specified `a` and `b` thread handles identify
743 /// the same thread, or if both `a` and `b` are invalid handles, and `false` otherwise.
744 ///
745 /// \note Note that if *either* of `a` or `b` is an
746 /// invalid handle, but not both, this method returns `false`.
747 ///
748 /// DEPRECATED: use `areEqual` instead.
749 static bool isEqual(const Handle& a, const Handle& b);
750
751 /// Return `true` if the specified `lhs` thread identifier is associated
752 /// with the same thread as the specified `rhs` thread identifier, and
753 /// `false` otherwise.
754 ///
755 /// DEPRECATED: use `areEqualId` instead.
756 static bool isEqualId(const Id& a, const Id& b);
757
758 /// Return the platform-specific identifier associated with the thread
759 /// referred to by the specified `handle`.
760 ///
761 /// \pre The behavior is undefined unless `handle` was obtained by a call to `create` or `self`.
762 ///
763 /// \note Note that the returned native handle may not be a globally unique
764 /// identifier for the thread (see `selfIdAsUint`).
765 static NativeHandle nativeHandle(const Handle& handle);
766
767 /// Return an opaque thread identifier that can be used to refer to the
768 /// current thread in calls to other `ThreadUtil` methods.
769 ///
770 /// \note Note that identifier may only be used to refer to the current thread from the
771 /// current thread (the handle returned is not valid in other threads).
772 static Handle self();
773
774 /// Return an identifier that can be used to uniquely identify the current thread within the current process.
775 ///
776 /// \note Note that the identifier
777 /// is only valid until the thread terminates and may be reused
778 /// thereafter.
779 static Id selfId();
780
781 /// Return an integral identifier that can be used to uniquely identify the current thread within the current process.
782 ///
783 /// \note Note that this
784 /// representation is particularly useful for logging purposes. Also
785 /// note that this value is only valid until the thread terminates and
786 /// may be reused thereafter.
787 ///
788 /// DEPRECATED: use `selfIdAsUint64` instead.
790
791 /// Return an integral identifier that can be used to uniquely identify the current thread within the current process.
792 ///
793 /// \note Note that this
794 /// representation is particularly useful for logging purposes. Also
795 /// note that this value is valid only until the thread terminates, and
796 /// may be reused thereafter.
798
799 /// Return an integral identifier that can be used to uniquely identify the kernel thread within the current process.
800 ///
801 /// \note Note that this identifier
802 /// may be different from the identifier returned by `selfIdAsUint64()`.
803 /// Also note that this value is valid only until the thread terminates,
804 /// and may be reused thereafter. Also note that this method returns the
805 /// kernel thread id only on the operating systems which implement that (on
806 /// Windows, the thread ids returned by both methods are the same).
808
809 // *** Thread-Specific (Local) Storage (TSS or TLS) ***
810
811 /// Load into the specified `key` a new process-wide identifier that can
812 /// be used to store (via `setSpecific`) and retrieve (via
813 /// `getSpecific`) a pointer value local to each thread, and associate
814 /// with the new key the specified `threadKeyCleanupFunction`, which
815 /// will be called by each thread, if `threadKeyCleanupFunction` is
816 /// non-zero and the value associated with `key` for that thread is
817 /// non-zero, with the associated value as an argument, after the
818 /// function passed to `create` has returned and before the thread
819 /// terminates. Return 0 on success, and a non-zero value otherwise.
820 ///
821 /// \note Note that multiple keys can be defined, which can result in multiple
822 /// thread key cleanup functions being called for a given thread.
823 static int createKey(Key *key, Destructor threadKeyCleanupFunction);
824
825 /// Delete the specified `key` from the calling process, and
826 /// disassociate all threads from the thread key cleanup function
827 /// supplied when `key` was created (see `createKey`). Return 0 on
828 /// success, and a non-zero value otherwise.
829 ///
830 /// \pre The behavior is undefined unless `key` was obtained from a successful call to `createKey` and has not already been deleted.
831 ///
832 /// \note Note that deleting a key does not
833 /// delete any data referred to by the pointer values associated with
834 /// that key in any thread.
835 static int deleteKey(Key& key);
836
837 /// Return the thread-local value associated with the specified `key`.
838 /// A `key` is shared among all threads and the value associated with
839 /// `key` for each thread is 0 until it is set by that thread using `setSpecific`.
840 ///
841 /// \pre The behavior is undefined unless this method is
842 /// called outside any thread key cleanup function associated with any
843 /// key by `createKey`, `key` was obtained from a successful call to
844 /// `createKey`, and `key` has not been deleted.
845 static void *getSpecific(const Key& key);
846
847 /// Associate the specified thread-local `value` with the specified
848 /// process-wide `key`. Return 0 on success, and a non-zero value
849 /// otherwise. The value associated with a thread for a given key is 0
850 /// until it has been set by that thread using `setSpecific`.
851 ///
852 /// \pre The behavior is undefined unless this method is called outside any
853 /// thread key cleanup function associated with any key by `createKey`,
854 /// `key` was obtained from a successful call to `createKey`, and `key`
855 /// has not been deleted.
856 static int setSpecific(const Key& key, const void *value);
857
858 /// Return a *hint* at the number of concurrent threads supported by
859 /// this platform on success, and 0 otherwise.
860 static unsigned int hardwareConcurrency();
861
862 /// Enable a thread creation limit. If set to non-zero value `n`'th thread
863 /// creation will fail. The limit is disabled by setting the limit to 0.
864 /// Only intended to be used in tests to inject thread creation errors.
865 ///
866 /// \note Note that this can be called multiple times to reset the thread limit,
867 /// e.g. between subtests for example.
868 static void setThreadLimit(unsigned int n);
869};
870
871// ============================================================================
872// INLINE DEFINITIONS
873// ============================================================================
874
875 // -----------------
876 // struct ThreadUtil
877 // -----------------
878
879 // *** Thread Management ***
880
881// CLASS METHODS
882inline
884 ThreadFunction function,
885 void *userData)
886{
887 BSLS_ASSERT_SAFE(handle);
888
889 if (isThreadLimitReached()) {
890 return -1;
891 }
892
893 return Imp::create(handle, function, userData);
894}
895
896template <class INVOKABLE>
897inline
899 const INVOKABLE& function)
900{
901 BSLS_ASSERT_SAFE(handle);
902
903 return createWithAllocator(handle,
904 function,
906}
907
908template <class INVOKABLE>
909inline
911 const ThreadAttributes& attributes,
912 const INVOKABLE& function)
913{
914 BSLS_ASSERT_SAFE(handle);
915
916 return createWithAllocator(handle,
917 attributes,
918 function,
920}
921
922inline
924 Handle *handle,
925 ThreadFunction function,
926 void *userData,
928{
929 BSLS_ASSERT_SAFE(handle);
930 BSLS_ASSERT_OPT(allocator);
931
932 if (isThreadLimitReached()) {
933 return -1;
934 }
935
936 // 'allocator' is unused in this function, which is provided for symmetry
937 // and in case this function comes to need an allocator at sometime in the
938 // future.
939
940 return Imp::create(handle, function, userData);
941}
942
943template <class INVOKABLE>
944inline
946 const ThreadAttributes& attributes,
947 const INVOKABLE& function,
948 bslma::Allocator *allocator)
949{
950 BSLS_ASSERT_SAFE(handle);
951 BSLS_ASSERT_OPT(allocator);
952
953 if (isThreadLimitReached()) {
954 return -1;
955 }
956
959 function,
960 attributes.threadName(),
961 allocator);
962
963 int rc = Imp::create(handle,
964 attributes,
966 threadData.ptr());
967 if (0 == rc) {
968 threadData.release();
969 }
970 return rc;
971}
972
973template <class INVOKABLE>
974inline
976 const INVOKABLE& function,
977 bslma::Allocator *allocator)
978{
979 BSLS_ASSERT_SAFE(handle);
980 BSLS_ASSERT_OPT(allocator);
981
982 if (isThreadLimitReached()) {
983 return -1;
984 }
985
988 function,
990 allocator);
991
992 int rc = Imp::create(handle,
994 threadData.ptr());
995 if (0 == rc) {
996 threadData.release();
997 }
998 return rc;
999}
1000
1001inline
1003{
1004 return Imp::detach(handle);
1005}
1006
1007inline
1008void ThreadUtil::exit(void *status)
1009{
1010 Imp::exit(status);
1011}
1012
1013inline
1016{
1017 return Imp::getMinSchedulingPriority(policy);
1018}
1019
1020inline
1023{
1024 return Imp::getMaxSchedulingPriority(policy);
1025}
1026
1027inline
1029{
1030 BSLS_ASSERT_SAFE(threadName);
1031
1032 return Imp::getThreadName(threadName);
1033}
1034
1035inline
1036int ThreadUtil::join(Handle& threadHandle, void **status)
1037{
1038 return Imp::join(threadHandle, status);
1039}
1040
1041inline
1042void ThreadUtil::microSleep(int microseconds, int seconds)
1043{
1044 Imp::microSleep(microseconds, seconds);
1045}
1046
1047inline
1049{
1050 Imp::setThreadName(threadName);
1051}
1052
1053inline
1055{
1056 Imp::sleep(sleepTime);
1057}
1058
1059#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
1060template <class REP_TYPE, class PERIOD_TYPE>
1061inline
1063 const bsl::chrono::duration<REP_TYPE, PERIOD_TYPE>& sleepTime)
1064{
1065 ThreadUtil::sleep(ChronoUtil::durationToTimeInterval(sleepTime));
1066}
1067#endif
1068
1069inline
1072{
1073 int status = Imp::sleepUntil(absoluteTime, clockType);
1074 (void) status; // Suppress an unused variable error.
1075 BSLS_ASSERT(0 == status);
1076}
1077
1078#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
1079template <class CLOCK, class DURATION>
1081 const bsl::chrono::time_point<CLOCK, DURATION>& absoluteTime)
1082{
1083 typename CLOCK::time_point now = CLOCK::now();
1084 const bsls::SystemClockType::Enum bslsClockType
1086
1087 // Iteration is necessary because the specified 'CLOCK' type may not
1088 // progress at the same rate as the realtime system clock.
1089
1090 while (absoluteTime > now) {
1091 bsls::TimeInterval ti = bsls::SystemTime::now(bslsClockType)
1092 .addDuration(absoluteTime - now);
1094 now = CLOCK::now();
1095 }
1096}
1097#endif
1098
1099inline
1101{
1102 Imp::yield();
1103}
1104
1105 // *** Thread Identification ***
1106
1107inline
1108bool ThreadUtil::areEqual(const Handle& a, const Handle& b)
1109{
1110 // Some implementations (notably pthreads) do not define the result of
1111 // comparing invalid handles. We avoid undefined behavior by explicitly
1112 // checking for invalid handles.
1113
1114 return Imp::INVALID_HANDLE == a
1115 ? (Imp::INVALID_HANDLE == b)
1116 : (Imp::INVALID_HANDLE == b ? false : Imp::areEqual(a, b));
1117}
1118
1119inline
1120bool ThreadUtil::areEqualId(const Id& a, const Id& b)
1121{
1122 return Imp::areEqualId(a, b);
1123}
1124
1125inline
1127{
1128 return Imp::handleToId(threadHandle);
1129}
1130
1131inline
1133{
1134 return Imp::idAsUint64(threadId);
1135}
1136
1137inline
1138int ThreadUtil::idAsInt(const Id& threadId)
1139{
1140 return Imp::idAsInt(threadId);
1141}
1142
1143inline
1145{
1146 return Imp::INVALID_HANDLE;
1147}
1148
1149inline
1150bool ThreadUtil::isEqual(const Handle& a, const Handle& b)
1151{
1152 return Imp::areEqual(a, b);
1153}
1154
1155inline
1156bool ThreadUtil::isEqualId(const Id& a, const Id& b)
1157{
1158 return Imp::areEqualId(a, b);
1159}
1160
1161inline
1164{
1165 return Imp::nativeHandle(handle);
1166}
1167
1168inline
1170{
1171 return Imp::self();
1172}
1173
1174inline
1176{
1177 return Imp::selfId();
1178}
1179
1180inline
1182{
1183 return Imp::selfIdAsInt();
1184}
1185
1186inline
1188{
1189 return Imp::selfIdAsUint64();
1190}
1191
1192inline
1194{
1196 if (!ktid) {
1197 // Obtaining kernel ID can be relatively expensive; cache it
1198 ktid = Imp::selfKernelIdAsUint64();
1199 }
1200 return ktid;
1201}
1202
1203 // *** Thread-Specific (Local) Storage (TSS or TLS) ***
1204
1205inline
1206int ThreadUtil::createKey(Key *key, Destructor threadKeyCleanupFunction)
1207{
1208 return Imp::createKey(key, threadKeyCleanupFunction);
1209}
1210
1211inline
1213{
1214 return Imp::deleteKey(key);
1215}
1216
1217inline
1219{
1220 return Imp::getSpecific(key);
1221}
1222
1223inline
1224int ThreadUtil::setSpecific(const Key& key, const void *value)
1225{
1226 return Imp::setSpecific(key, value);
1227}
1228
1229inline
1231{
1232 return Imp::hardwareConcurrency();
1233}
1234
1235} // close package namespace
1236
1237
1238#endif
1239
1240// ----------------------------------------------------------------------------
1241// Copyright 2015 Bloomberg Finance L.P.
1242//
1243// Licensed under the Apache License, Version 2.0 (the "License");
1244// you may not use this file except in compliance with the License.
1245// You may obtain a copy of the License at
1246//
1247// http://www.apache.org/licenses/LICENSE-2.0
1248//
1249// Unless required by applicable law or agreed to in writing, software
1250// distributed under the License is distributed on an "AS IS" BASIS,
1251// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1252// See the License for the specific language governing permissions and
1253// limitations under the License.
1254// ----------------------------- END-OF-FILE ----------------------------------
1255
1256/** @} */
1257/** @} */
1258/** @} */
Definition bslstl_string.h:1252
Definition bslma_allocator.h:545
Definition bslma_managedptr.h:1173
TARGET_TYPE * ptr() const
Definition bslma_managedptr.h:2603
ManagedPtr_PairProxy< TARGET_TYPE, ManagedPtrDeleter > release()
Definition bslma_managedptr.h:2490
Definition bslmt_threadattributes.h:361
bslstl::StringRef threadName() const
Definition bslmt_threadattributes.h:772
SchedulingPolicy
Definition bslmt_threadattributes.h:381
Definition bsls_timeinterval.h:307
Definition bslstl_stringref.h:374
#define BSLA_MAYBE_UNUSED
Definition bsla_maybeunused.h:239
void * bslmt_EntryPointFunctorAdapter_invoker(void *argument)
void(* bslmt_KeyDestructorFunction)(void *)
Definition bslmt_threadutil.h:363
void *(* bslmt_ThreadFunction)(void *)
Definition bslmt_threadutil.h:357
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_ASSERT_OPT(X)
Definition bsls_assert.h:2045
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_THREAD_LOCAL
Definition bsls_keyword.h:701
Definition bslmt_barrier.h:344
static Allocator * globalAllocator(Allocator *basicAllocator=0)
Definition bslma_default.h:921
static void allocateAdapter(bslma::ManagedPtr< EntryPointFunctorAdapter< TYPE > > *adapter, const TYPE &invokable, const bslstl::StringRef &threadName, bslma::Allocator *basicAllocator=0)
Definition bslmt_entrypointfunctoradapter.h:396
Definition bslmt_entrypointfunctoradapter.h:221
Definition bslmt_threadutil.h:379
bslmt_ThreadFunction ThreadFunction
Prototype for thread entry-point functions.
Definition bslmt_threadutil.h:400
static void microSleep(int microseconds, int seconds=0)
Definition bslmt_threadutil.h:1042
static int create(Handle *handle, const ThreadAttributes &attributes, ThreadFunction function, void *userData)
static bool isThreadLimitReached()
static bsls::Types::Uint64 selfIdAsInt()
Definition bslmt_threadutil.h:1181
static int create(Handle *handle, ThreadFunction function, void *userData)
Definition bslmt_threadutil.h:883
static Handle self()
Definition bslmt_threadutil.h:1169
static bool areEqualId(const Id &a, const Id &b)
Definition bslmt_threadutil.h:1120
Imp::Handle Handle
Definition bslmt_threadutil.h:389
static bsls::Types::Uint64 selfIdAsUint64()
Definition bslmt_threadutil.h:1187
static Id handleToId(const Handle &threadHandle)
Definition bslmt_threadutil.h:1126
static void getThreadName(bsl::string *threadName)
Definition bslmt_threadutil.h:1028
static void sleepUntil(const bsls::TimeInterval &absoluteTime, bsls::SystemClockType::Enum clockType=bsls::SystemClockType::e_REALTIME)
Definition bslmt_threadutil.h:1070
static bool isEqualId(const Id &a, const Id &b)
Definition bslmt_threadutil.h:1156
static int detach(Handle &handle)
Definition bslmt_threadutil.h:1002
static int idAsInt(const Id &threadId)
Definition bslmt_threadutil.h:1138
static Id selfId()
Definition bslmt_threadutil.h:1175
static int deleteKey(Key &key)
Definition bslmt_threadutil.h:1212
static bool areEqual(const Handle &a, const Handle &b)
Definition bslmt_threadutil.h:1108
Imp::NativeHandle NativeHandle
Platform-specific thread handle type.
Definition bslmt_threadutil.h:392
static int join(Handle &threadHandle, void **status=0)
Definition bslmt_threadutil.h:1036
static bool isEqual(const Handle &a, const Handle &b)
Definition bslmt_threadutil.h:1150
static void setThreadName(const bslstl::StringRef &threadName)
Definition bslmt_threadutil.h:1048
static int getMaxSchedulingPriority(ThreadAttributes::SchedulingPolicy policy)
Definition bslmt_threadutil.h:1021
bslmt_KeyDestructorFunction Destructor
Prototype for thread-specific key destructors.
Definition bslmt_threadutil.h:406
static int createWithAllocator(Handle *handle, ThreadFunction function, void *userData, bslma::Allocator *allocator)
static bsls::Types::Uint64 idAsUint64(const Id &threadId)
Definition bslmt_threadutil.h:1132
static NativeHandle nativeHandle(const Handle &handle)
Definition bslmt_threadutil.h:1163
ThreadUtilImpl< Platform::ThreadPolicy > Imp
Platform-specific implementation type.
Definition bslmt_threadutil.h:385
Imp::Id Id
Definition bslmt_threadutil.h:397
static void sleep(const bsls::TimeInterval &sleepTime)
Definition bslmt_threadutil.h:1054
static const Handle & invalidHandle()
Definition bslmt_threadutil.h:1144
static int convertToSchedulingPriority(ThreadAttributes::SchedulingPolicy policy, double normalizedSchedulingPriority)
static bsls::Types::Uint64 selfKernelIdAsUint64()
Definition bslmt_threadutil.h:1193
Imp::Key Key
Thread-specific key type, used to refer to thread-specific storage.
Definition bslmt_threadutil.h:403
static void setThreadLimit(unsigned int n)
static void yield()
Definition bslmt_threadutil.h:1100
static void exit(void *status)
Definition bslmt_threadutil.h:1008
static void * getSpecific(const Key &key)
Definition bslmt_threadutil.h:1218
static int getMinSchedulingPriority(ThreadAttributes::SchedulingPolicy policy)
Definition bslmt_threadutil.h:1014
static unsigned int hardwareConcurrency()
Definition bslmt_threadutil.h:1230
static int setSpecific(const Key &key, const void *value)
Definition bslmt_threadutil.h:1224
static int createWithAllocator(Handle *handle, const ThreadAttributes &attributes, ThreadFunction function, void *userData, bslma::Allocator *allocator)
static int createKey(Key *key, Destructor threadKeyCleanupFunction)
Definition bslmt_threadutil.h:1206
Enum
Definition bsls_systemclocktype.h:119
@ e_REALTIME
Definition bsls_systemclocktype.h:122
static TimeInterval now(SystemClockType::Enum clockType)
Definition bsls_systemtime.h:177
unsigned long long Uint64
Definition bsls_types.h:139