VirtualBox

source: vbox/trunk/include/iprt/thread.h@ 39654

Last change on this file since 39654 was 39443, checked in by vboxsync, 13 years ago

Introduced RTThreadSleepNoLog for spinlocking in the electric fence heap. (Caused trouble with all logging enabled.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.3 KB
Line 
1/** @file
2 * IPRT - Threads.
3 */
4
5/*
6 * Copyright (C) 2006-2007 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___iprt_thread_h
27#define ___iprt_thread_h
28
29#include <iprt/cdefs.h>
30#include <iprt/types.h>
31#include <iprt/stdarg.h>
32
33
34RT_C_DECLS_BEGIN
35
36/** @defgroup grp_rt_thread RTThread - Thread Management
37 * @ingroup grp_rt
38 * @{
39 */
40
41/**
42 * The thread state.
43 */
44typedef enum RTTHREADSTATE
45{
46 /** The usual invalid 0 value. */
47 RTTHREADSTATE_INVALID = 0,
48 /** The thread is being initialized. */
49 RTTHREADSTATE_INITIALIZING,
50 /** The thread has terminated */
51 RTTHREADSTATE_TERMINATED,
52 /** Probably running. */
53 RTTHREADSTATE_RUNNING,
54
55 /** Waiting on a critical section. */
56 RTTHREADSTATE_CRITSECT,
57 /** Waiting on a event semaphore. */
58 RTTHREADSTATE_EVENT,
59 /** Waiting on a event multiple wakeup semaphore. */
60 RTTHREADSTATE_EVENT_MULTI,
61 /** Waiting on a fast mutex. */
62 RTTHREADSTATE_FAST_MUTEX,
63 /** Waiting on a mutex. */
64 RTTHREADSTATE_MUTEX,
65 /** Waiting on a read write semaphore, read (shared) access. */
66 RTTHREADSTATE_RW_READ,
67 /** Waiting on a read write semaphore, write (exclusive) access. */
68 RTTHREADSTATE_RW_WRITE,
69 /** The thread is sleeping. */
70 RTTHREADSTATE_SLEEP,
71 /** Waiting on a spin mutex. */
72 RTTHREADSTATE_SPIN_MUTEX,
73 /** End of the thread states. */
74 RTTHREADSTATE_END,
75
76 /** The usual 32-bit size hack. */
77 RTTHREADSTATE_32BIT_HACK = 0x7fffffff
78} RTTHREADSTATE;
79
80/** Checks if a thread state indicates that the thread is sleeping. */
81#define RTTHREAD_IS_SLEEPING(enmState) ((enmState) >= RTTHREADSTATE_CRITSECT)
82
83/**
84 * Thread types.
85 * Besides identifying the purpose of the thread, the thread type is
86 * used to select the scheduling properties.
87 *
88 * The types in are placed in a rough order of ascending priority.
89 */
90typedef enum RTTHREADTYPE
91{
92 /** Invalid type. */
93 RTTHREADTYPE_INVALID = 0,
94 /** Infrequent poller thread.
95 * This type of thread will sleep for the most of the time, and do
96 * infrequent polls on resources at 0.5 sec or higher intervals.
97 */
98 RTTHREADTYPE_INFREQUENT_POLLER,
99 /** Main heavy worker thread.
100 * Thread of this type is driving asynchronous tasks in the Main
101 * API which takes a long time and might involve a bit of CPU. Like
102 * for instance creating a fixed sized VDI.
103 */
104 RTTHREADTYPE_MAIN_HEAVY_WORKER,
105 /** The emulation thread type.
106 * While being a thread with very high workload it still is vital
107 * that it gets scheduled frequently. When possible all other thread
108 * types except DEFAULT and GUI should interrupt this one ASAP when
109 * they become ready.
110 */
111 RTTHREADTYPE_EMULATION,
112 /** The default thread type.
113 * Since it doesn't say much about the purpose of the thread
114 * nothing special is normally done to the scheduling. This type
115 * should be avoided.
116 * The main thread is registered with default type during RTR3Init()
117 * and that's what the default process priority is derived from.
118 */
119 RTTHREADTYPE_DEFAULT,
120 /** The GUI thread type
121 * The GUI normally have a low workload but is frequently scheduled
122 * to handle events. When possible the scheduler should not leave
123 * threads of this kind waiting for too long (~50ms).
124 */
125 RTTHREADTYPE_GUI,
126 /** Main worker thread.
127 * Thread of this type is driving asynchronous tasks in the Main API.
128 * In most cases this means little work an a lot of waiting.
129 */
130 RTTHREADTYPE_MAIN_WORKER,
131 /** VRDP I/O thread.
132 * These threads are I/O threads in the RDP server will hang around
133 * waiting for data, process it and pass it on.
134 */
135 RTTHREADTYPE_VRDP_IO,
136 /** The debugger type.
137 * Threads involved in servicing the debugger. It must remain
138 * responsive even when things are running wild in.
139 */
140 RTTHREADTYPE_DEBUGGER,
141 /** Message pump thread.
142 * Thread pumping messages from one thread/process to another
143 * thread/process. The workload is very small, most of the time
144 * it's blocked waiting for messages to be procduced or processed.
145 * This type of thread will be favored after I/O threads.
146 */
147 RTTHREADTYPE_MSG_PUMP,
148 /** The I/O thread type.
149 * Doing I/O means shuffling data, waiting for request to arrive and
150 * for them to complete. The thread should be favored when competing
151 * with any other threads except timer threads.
152 */
153 RTTHREADTYPE_IO,
154 /** The timer thread type.
155 * A timer thread is mostly waiting for the timer to tick
156 * and then perform a little bit of work. Accuracy is important here,
157 * so the thread should be favoured over all threads. If premention can
158 * be configured at thread level, it could be made very short.
159 */
160 RTTHREADTYPE_TIMER,
161 /** Only used for validation. */
162 RTTHREADTYPE_END
163} RTTHREADTYPE;
164
165
166#ifndef IN_RC
167
168/**
169 * Checks if the IPRT thread component has been initialized.
170 *
171 * This is used to avoid calling into RTThread before the runtime has been
172 * initialized.
173 *
174 * @returns @c true if it's initialized, @c false if not.
175 */
176RTDECL(bool) RTThreadIsInitialized(void);
177
178/**
179 * Get the thread handle of the current thread.
180 *
181 * @returns Thread handle.
182 */
183RTDECL(RTTHREAD) RTThreadSelf(void);
184
185/**
186 * Get the native thread handle of the current thread.
187 *
188 * @returns Native thread handle.
189 */
190RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void);
191
192/**
193 * Millisecond granular sleep function.
194 *
195 * @returns VINF_SUCCESS on success.
196 * @returns VERR_INTERRUPTED if a signal or other asynchronous stuff happened
197 * which interrupt the peaceful sleep.
198 * @param cMillies Number of milliseconds to sleep.
199 * 0 milliseconds means yielding the timeslice - deprecated!
200 * @remark See RTThreadNanoSleep() for sleeping for smaller periods of time.
201 */
202RTDECL(int) RTThreadSleep(RTMSINTERVAL cMillies);
203
204/**
205 * Millisecond granular sleep function, no logger calls.
206 *
207 * Same as RTThreadSleep, except it will never call into the IPRT logger. It
208 * can therefore safely be used in places where the logger is off limits, like
209 * at termination or init time. The electric fence heap is one consumer of
210 * this API.
211 *
212 * @returns VINF_SUCCESS on success.
213 * @returns VERR_INTERRUPTED if a signal or other asynchronous stuff happened
214 * which interrupt the peaceful sleep.
215 * @param cMillies Number of milliseconds to sleep.
216 * 0 milliseconds means yielding the timeslice - deprecated!
217 */
218RTDECL(int) RTThreadSleepNoLog(RTMSINTERVAL cMillies);
219
220/**
221 * Yields the CPU.
222 *
223 * @returns true if we yielded.
224 * @returns false if it's probable that we didn't yield.
225 */
226RTDECL(bool) RTThreadYield(void);
227
228
229
230/**
231 * Thread function.
232 *
233 * @returns 0 on success.
234 * @param ThreadSelf Thread handle to this thread.
235 * @param pvUser User argument.
236 */
237typedef DECLCALLBACK(int) FNRTTHREAD(RTTHREAD ThreadSelf, void *pvUser);
238/** Pointer to a FNRTTHREAD(). */
239typedef FNRTTHREAD *PFNRTTHREAD;
240
241/**
242 * Thread creation flags.
243 */
244typedef enum RTTHREADFLAGS
245{
246 /**
247 * This flag is used to keep the thread structure around so it can
248 * be waited on after termination.
249 */
250 RTTHREADFLAGS_WAITABLE = RT_BIT(0),
251 /** The bit number corresponding to the RTTHREADFLAGS_WAITABLE mask. */
252 RTTHREADFLAGS_WAITABLE_BIT = 0,
253
254 /** Mask of valid flags, use for validation. */
255 RTTHREADFLAGS_MASK = RT_BIT(0)
256} RTTHREADFLAGS;
257
258
259/**
260 * Create a new thread.
261 *
262 * @returns iprt status code.
263 * @param pThread Where to store the thread handle to the new thread. (optional)
264 * @param pfnThread The thread function.
265 * @param pvUser User argument.
266 * @param cbStack The size of the stack for the new thread.
267 * Use 0 for the default stack size.
268 * @param enmType The thread type. Used for deciding scheduling attributes
269 * of the thread.
270 * @param fFlags Flags of the RTTHREADFLAGS type (ORed together).
271 * @param pszName Thread name.
272 *
273 * @remark When called in Ring-0, this API will create a new kernel thread and not a thread in
274 * the context of the calling process.
275 */
276RTDECL(int) RTThreadCreate(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
277 RTTHREADTYPE enmType, unsigned fFlags, const char *pszName);
278
279/**
280 * Create a new thread.
281 *
282 * Same as RTThreadCreate except the name is given in the RTStrPrintfV form.
283 *
284 * @returns iprt status code.
285 * @param pThread See RTThreadCreate.
286 * @param pfnThread See RTThreadCreate.
287 * @param pvUser See RTThreadCreate.
288 * @param cbStack See RTThreadCreate.
289 * @param enmType See RTThreadCreate.
290 * @param fFlags See RTThreadCreate.
291 * @param pszName Thread name format.
292 * @param va Format arguments.
293 */
294RTDECL(int) RTThreadCreateV(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
295 RTTHREADTYPE enmType, uint32_t fFlags, const char *pszNameFmt, va_list va);
296
297/**
298 * Create a new thread.
299 *
300 * Same as RTThreadCreate except the name is given in the RTStrPrintf form.
301 *
302 * @returns iprt status code.
303 * @param pThread See RTThreadCreate.
304 * @param pfnThread See RTThreadCreate.
305 * @param pvUser See RTThreadCreate.
306 * @param cbStack See RTThreadCreate.
307 * @param enmType See RTThreadCreate.
308 * @param fFlags See RTThreadCreate.
309 * @param pszName Thread name format.
310 * @param ... Format arguments.
311 */
312RTDECL(int) RTThreadCreateF(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
313 RTTHREADTYPE enmType, uint32_t fFlags, const char *pszNameFmt, ...);
314
315/**
316 * Gets the native thread id of a IPRT thread.
317 *
318 * @returns The native thread id.
319 * @param Thread The IPRT thread.
320 */
321RTDECL(RTNATIVETHREAD) RTThreadGetNative(RTTHREAD Thread);
322
323/**
324 * Gets the IPRT thread of a native thread.
325 *
326 * @returns The IPRT thread handle
327 * @returns NIL_RTTHREAD if not a thread known to IPRT.
328 * @param NativeThread The native thread handle/id.
329 */
330RTDECL(RTTHREAD) RTThreadFromNative(RTNATIVETHREAD NativeThread);
331
332/**
333 * Changes the type of the specified thread.
334 *
335 * @returns iprt status code.
336 * @param Thread The thread which type should be changed.
337 * @param enmType The new thread type.
338 * @remark In Ring-0 it only works if Thread == RTThreadSelf().
339 */
340RTDECL(int) RTThreadSetType(RTTHREAD Thread, RTTHREADTYPE enmType);
341
342/**
343 * Wait for the thread to terminate, resume on interruption.
344 *
345 * @returns iprt status code.
346 * Will not return VERR_INTERRUPTED.
347 * @param Thread The thread to wait for.
348 * @param cMillies The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
349 * an indefinite wait.
350 * @param prc Where to store the return code of the thread. Optional.
351 */
352RTDECL(int) RTThreadWait(RTTHREAD Thread, RTMSINTERVAL cMillies, int *prc);
353
354/**
355 * Wait for the thread to terminate, return on interruption.
356 *
357 * @returns iprt status code.
358 * @param Thread The thread to wait for.
359 * @param cMillies The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
360 * an indefinite wait.
361 * @param prc Where to store the return code of the thread. Optional.
362 */
363RTDECL(int) RTThreadWaitNoResume(RTTHREAD Thread, RTMSINTERVAL cMillies, int *prc);
364
365/**
366 * Gets the name of the current thread thread.
367 *
368 * @returns Pointer to readonly name string.
369 * @returns NULL on failure.
370 */
371RTDECL(const char *) RTThreadSelfName(void);
372
373/**
374 * Gets the name of a thread.
375 *
376 * @returns Pointer to readonly name string.
377 * @returns NULL on failure.
378 * @param Thread Thread handle of the thread to query the name of.
379 */
380RTDECL(const char *) RTThreadGetName(RTTHREAD Thread);
381
382/**
383 * Gets the type of the specified thread.
384 *
385 * @returns The thread type.
386 * @returns RTTHREADTYPE_INVALID if the thread handle is invalid.
387 * @param Thread The thread in question.
388 */
389RTDECL(RTTHREADTYPE) RTThreadGetType(RTTHREAD Thread);
390
391/**
392 * Sets the name of a thread.
393 *
394 * @returns iprt status code.
395 * @param Thread Thread handle of the thread to query the name of.
396 * @param pszName The thread name.
397 */
398RTDECL(int) RTThreadSetName(RTTHREAD Thread, const char *pszName);
399
400/**
401 * Checks if the specified thread is the main thread.
402 *
403 * @returns true if it is, false if it isn't.
404 *
405 * @param hThread The thread handle.
406 */
407RTDECL(bool) RTThreadIsMain(RTTHREAD hThread);
408
409/**
410 * Checks if the calling thread is known to IPRT.
411 *
412 * @returns @c true if it is, @c false if it isn't.
413 */
414RTDECL(bool) RTThreadIsSelfKnown(void);
415
416/**
417 * Checks if the calling thread is know to IPRT and is alive.
418 *
419 * @returns @c true if it is, @c false if it isn't.
420 */
421RTDECL(bool) RTThreadIsSelfAlive(void);
422
423/**
424 * Checks if the calling thread is known to IPRT.
425 *
426 * @returns @c true if it is, @c false if it isn't.
427 */
428RTDECL(bool) RTThreadIsOperational(void);
429
430/**
431 * Signal the user event.
432 *
433 * @returns iprt status code.
434 */
435RTDECL(int) RTThreadUserSignal(RTTHREAD Thread);
436
437/**
438 * Wait for the user event.
439 *
440 * @returns iprt status code.
441 * @param Thread The thread to wait for.
442 * @param cMillies The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
443 * an indefinite wait.
444 */
445RTDECL(int) RTThreadUserWait(RTTHREAD Thread, RTMSINTERVAL cMillies);
446
447/**
448 * Wait for the user event, return on interruption.
449 *
450 * @returns iprt status code.
451 * @param Thread The thread to wait for.
452 * @param cMillies The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
453 * an indefinite wait.
454 */
455RTDECL(int) RTThreadUserWaitNoResume(RTTHREAD Thread, RTMSINTERVAL cMillies);
456
457/**
458 * Reset the user event.
459 *
460 * @returns iprt status code.
461 * @param Thread The thread to reset.
462 */
463RTDECL(int) RTThreadUserReset(RTTHREAD Thread);
464
465/**
466 * Pokes the thread.
467 *
468 * This will signal the thread, attempting to interrupt whatever it's currently
469 * doing. This is *NOT* implemented on all platforms and may cause unresolved
470 * symbols during linking or VERR_NOT_IMPLEMENTED at runtime.
471 *
472 * @returns IPRT status code.
473 *
474 * @param hThread The thread to poke. This must not be the
475 * calling thread.
476 */
477RTDECL(int) RTThreadPoke(RTTHREAD hThread);
478
479# ifdef IN_RING0
480
481/**
482 * Check if preemption is currently enabled or not for the current thread.
483 *
484 * @note This may return true even on systems where preemption isn't
485 * possible. In that case, it means no call to RTThreadPreemptDisable
486 * has been made and interrupts are still enabled.
487 *
488 * @returns true if preemption is enabled, false if preemetion is disabled.
489 * @param hThread Must be NIL_RTTHREAD for now.
490 */
491RTDECL(bool) RTThreadPreemptIsEnabled(RTTHREAD hThread);
492
493/**
494 * Check if preemption is pending for the current thread.
495 *
496 * This function should be called regularly when executing larger portions of
497 * code with preemption disabled.
498 *
499 * @returns true if pending, false if not.
500 * @param hThread Must be NIL_RTTHREAD for now.
501 */
502RTDECL(bool) RTThreadPreemptIsPending(RTTHREAD hThread);
503
504/**
505 * Is RTThreadPreemptIsPending reliable?
506 *
507 * @returns true if reliable, false if not.
508 */
509RTDECL(bool) RTThreadPreemptIsPendingTrusty(void);
510
511/**
512 * Is preemption possible on this system.
513 *
514 * @returns true if possible, false if not.
515 */
516RTDECL(bool) RTThreadPreemptIsPossible(void);
517
518/**
519 * Preemption state saved by RTThreadPreemptDisable and used by
520 * RTThreadPreemptRestore to restore the previous state.
521 */
522typedef struct RTTHREADPREEMPTSTATE
523{
524 /** In debug builds this will be used to check for cpu migration. */
525 RTCPUID idCpu;
526# ifdef RT_OS_WINDOWS
527 /** The old IRQL. Don't touch! */
528 unsigned char uchOldIrql;
529 /** Reserved, MBZ. */
530 uint8_t bReserved1;
531 /** Reserved, MBZ. */
532 uint8_t bReserved2;
533 /** Reserved, MBZ. */
534 uint8_t bReserved3;
535# define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, 255, 0, 0, 0 }
536# elif defined(RT_OS_SOLARIS)
537 /** The Old PIL. Don't touch! */
538 uint32_t uOldPil;
539# define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, UINT32_MAX }
540# else
541 /** Reserved, MBZ. */
542 uint32_t u32Reserved;
543# define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, 0 }
544# endif
545} RTTHREADPREEMPTSTATE;
546/** Pointer to a preemption state. */
547typedef RTTHREADPREEMPTSTATE *PRTTHREADPREEMPTSTATE;
548
549/**
550 * Disable preemption.
551 *
552 * A call to this function must be matched by exactly one call to
553 * RTThreadPreemptRestore().
554 *
555 * @param pState Where to store the preemption state.
556 */
557RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState);
558
559/**
560 * Restores the preemption state, undoing a previous call to
561 * RTThreadPreemptDisable.
562 *
563 * A call to this function must be matching a previous call to
564 * RTThreadPreemptDisable.
565 *
566 * @param pState The state return by RTThreadPreemptDisable.
567 */
568RTDECL(void) RTThreadPreemptRestore(PRTTHREADPREEMPTSTATE pState);
569
570/**
571 * Check if the thread is executing in interrupt context.
572 *
573 * @returns true if in interrupt context, false if not.
574 * @param hThread Must be NIL_RTTHREAD for now.
575 */
576RTDECL(bool) RTThreadIsInInterrupt(RTTHREAD hThread);
577
578# endif /* IN_RING0 */
579
580
581# ifdef IN_RING3
582
583/**
584 * Adopts a non-IPRT thread.
585 *
586 * @returns IPRT status code.
587 * @param enmType The thread type.
588 * @param fFlags The thread flags. RTTHREADFLAGS_WAITABLE is not currently allowed.
589 * @param pszName The thread name. Optional
590 * @param pThread Where to store the thread handle. Optional.
591 */
592RTDECL(int) RTThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, const char *pszName, PRTTHREAD pThread);
593
594/**
595 * Get the thread handle of the current thread, automatically adopting alien
596 * threads.
597 *
598 * @returns Thread handle.
599 */
600RTDECL(RTTHREAD) RTThreadSelfAutoAdopt(void);
601
602/**
603 * Gets the affinity mask of the current thread.
604 *
605 * @returns IPRT status code.
606 * @param pCpuSet Where to return the CPU affienty set of the calling
607 * thread.
608 */
609RTR3DECL(int) RTThreadGetAffinity(PRTCPUSET pCpuSet);
610
611/**
612 * Sets the affinity mask of the current thread.
613 *
614 * @returns iprt status code.
615 * @param pCpuSet The set of CPUs this thread can run on. NULL means
616 * all CPUs.
617 */
618RTR3DECL(int) RTThreadSetAffinity(PCRTCPUSET pCpuSet);
619
620/**
621 * Binds the thread to one specific CPU.
622 *
623 * @returns iprt status code.
624 * @param idCpu The ID of the CPU to bind this thread to. Use
625 * NIL_RTCPUID to unbind it.
626 */
627RTR3DECL(int) RTThreadSetAffinityToCpu(RTCPUID idCpu);
628
629/**
630 * Unblocks a thread.
631 *
632 * This function is paired with RTThreadBlocking and RTThreadBlockingDebug.
633 *
634 * @param hThread The current thread.
635 * @param enmCurState The current state, used to check for nested blocking.
636 * The new state will be running.
637 */
638RTDECL(void) RTThreadUnblocked(RTTHREAD hThread, RTTHREADSTATE enmCurState);
639
640/**
641 * Change the thread state to blocking.
642 *
643 * @param hThread The current thread.
644 * @param enmState The sleep state.
645 * @param fReallySleeping Really going to sleep now. Use false before calls
646 * to other IPRT synchronization methods.
647 */
648RTDECL(void) RTThreadBlocking(RTTHREAD hThread, RTTHREADSTATE enmState, bool fReallySleeping);
649
650/**
651 * Get the current thread state.
652 *
653 * A thread that is reported as sleeping may actually still be running inside
654 * the lock validator or/and in the code of some other IPRT synchronization
655 * primitive. Use RTThreadGetReallySleeping
656 *
657 * @returns The thread state.
658 * @param hThread The thread.
659 */
660RTDECL(RTTHREADSTATE) RTThreadGetState(RTTHREAD hThread);
661
662/**
663 * Checks if the thread is really sleeping or not.
664 *
665 * @returns RTTHREADSTATE_RUNNING if not really sleeping, otherwise the state it
666 * is sleeping in.
667 * @param hThread The thread.
668 */
669RTDECL(RTTHREADSTATE) RTThreadGetReallySleeping(RTTHREAD hThread);
670
671/**
672 * Translate a thread state into a string.
673 *
674 * @returns Pointer to a read-only string containing the state name.
675 * @param enmState The state.
676 */
677RTDECL(const char *) RTThreadStateName(RTTHREADSTATE enmState);
678
679
680/**
681 * Native thread states returned by RTThreadNativeState.
682 */
683typedef enum RTTHREADNATIVESTATE
684{
685 /** Invalid thread handle. */
686 RTTHREADNATIVESTATE_INVALID = 0,
687 /** Unable to determine the thread state. */
688 RTTHREADNATIVESTATE_UNKNOWN,
689 /** The thread is running. */
690 RTTHREADNATIVESTATE_RUNNING,
691 /** The thread is blocked. */
692 RTTHREADNATIVESTATE_BLOCKED,
693 /** The thread is suspended / stopped. */
694 RTTHREADNATIVESTATE_SUSPENDED,
695 /** The thread has terminated. */
696 RTTHREADNATIVESTATE_TERMINATED,
697 /** Make sure it's a 32-bit type. */
698 RTTHREADNATIVESTATE_32BIT_HACK = 0x7fffffff
699} RTTHREADNATIVESTATE;
700
701
702/**
703 * Get the native state of a thread.
704 *
705 * @returns Native state.
706 * @param hThread The thread handle.
707 *
708 * @remarks Not yet implemented on all systems, so have a backup plan for
709 * RTTHREADNATIVESTATE_UNKNOWN.
710 */
711RTDECL(RTTHREADNATIVESTATE) RTThreadGetNativeState(RTTHREAD hThread);
712
713
714/**
715 * Get the execution times of the specified thread
716 *
717 * @returns IPRT status code.
718 * @param pKernelTime Kernel execution time in ms (out)
719 * @param pUserTime User execution time in ms (out)
720 *
721 */
722RTR3DECL(int) RTThreadGetExecutionTimeMilli(uint64_t *pKernelTime, uint64_t *pUserTime);
723
724/** @name Thread Local Storage
725 * @{
726 */
727/**
728 * Thread termination callback for destroying a non-zero TLS entry.
729 *
730 * @remarks It is not permitable to use any RTTls APIs at this time. Doing so
731 * may lead to endless loops, crashes, and other bad stuff.
732 *
733 * @param pvValue The current value.
734 */
735typedef DECLCALLBACK(void) FNRTTLSDTOR(void *pvValue);
736/** Pointer to a FNRTTLSDTOR. */
737typedef FNRTTLSDTOR *PFNRTTLSDTOR;
738
739/**
740 * Allocates a TLS entry (index).
741 *
742 * Example code:
743 * @code
744 RTTLS g_iTls = NIL_RTTLS;
745
746 ...
747
748 // once for the process, allocate the TLS index
749 if (g_iTls == NIL_RTTLS)
750 g_iTls = RTTlsAlloc();
751
752 // set the thread-local value.
753 RTTlsSet(g_iTls, pMyData);
754
755 ...
756
757 // get the thread-local value
758 PMYDATA pMyData = (PMYDATA)RTTlsGet(g_iTls);
759
760 @endcode
761 *
762 * @returns the index of the allocated TLS entry.
763 * @returns NIL_RTTLS on failure.
764 */
765RTR3DECL(RTTLS) RTTlsAlloc(void);
766
767/**
768 * Variant of RTTlsAlloc that returns a status code.
769 *
770 * @returns IPRT status code.
771 * @retval VERR_NOT_SUPPORTED if pfnDestructor is non-NULL and the platform
772 * doesn't support this feature.
773 *
774 * @param piTls Where to store the index of the allocated TLS entry.
775 * This is set to NIL_RTTLS on failure.
776 * @param pfnDestructor Optional callback function for cleaning up on
777 * thread termination. WARNING! This feature may not
778 * be implemented everywhere.
779 */
780RTR3DECL(int) RTTlsAllocEx(PRTTLS piTls, PFNRTTLSDTOR pfnDestructor);
781
782/**
783 * Frees a TLS entry.
784 *
785 * @returns IPRT status code.
786 * @param iTls The index of the TLS entry.
787 */
788RTR3DECL(int) RTTlsFree(RTTLS iTls);
789
790/**
791 * Get the (thread-local) value stored in a TLS entry.
792 *
793 * @returns value in given TLS entry.
794 * @retval NULL if RTTlsSet() has not yet been called on this thread, or if the
795 * TLS index is invalid.
796 *
797 * @param iTls The index of the TLS entry.
798 */
799RTR3DECL(void *) RTTlsGet(RTTLS iTls);
800
801/**
802 * Get the value stored in a TLS entry.
803 *
804 * @returns IPRT status code.
805 * @param iTls The index of the TLS entry.
806 * @param ppvValue Where to store the value. The value will be NULL if
807 * RTTlsSet has not yet been called on this thread.
808 */
809RTR3DECL(int) RTTlsGetEx(RTTLS iTls, void **ppvValue);
810
811/**
812 * Set the value stored in an allocated TLS entry.
813 *
814 * @returns IPRT status.
815 * @param iTls The index of the TLS entry.
816 * @param pvValue The value to store.
817 *
818 * @remarks Note that NULL is considered a special value.
819 */
820RTR3DECL(int) RTTlsSet(RTTLS iTls, void *pvValue);
821
822/** @} */
823
824# endif /* IN_RING3 */
825# endif /* !IN_RC */
826
827/** @} */
828
829RT_C_DECLS_END
830
831#endif
832
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette