VirtualBox

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

Last change on this file since 56118 was 55863, checked in by vboxsync, 10 years ago

IPRT,SUPDrv,VMM: Revised the context switching hook interface. Do less work when enabling the hook (formerly 'registration'). Drop the reference counting (kept internally for solaris) as it complicates restrictions wrt destroying enabled hooks. Bumped support driver version.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 29.7 KB
Line 
1/** @file
2 * IPRT - Threads.
3 */
4
5/*
6 * Copyright (C) 2006-2013 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 produced 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 /** This flag is used to keep the thread structure around so it can
247 * be waited on after termination. @sa RTThreadWait and
248 * RTThreadWaitNoResume. Not required for RTThreadUserWait and friends!
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#ifndef RT_OS_LINUX /* XXX crashes genksyms at least on 32-bit Linux hosts */
279/** @copydoc RTThreadCreate */
280typedef DECLCALLBACKPTR(int, PFNRTTHREADCREATE)(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
281 RTTHREADTYPE enmType, unsigned fFlags, const char *pszName);
282#endif
283
284
285/**
286 * Create a new thread.
287 *
288 * Same as RTThreadCreate except the name is given in the RTStrPrintfV form.
289 *
290 * @returns iprt status code.
291 * @param pThread See RTThreadCreate.
292 * @param pfnThread See RTThreadCreate.
293 * @param pvUser See RTThreadCreate.
294 * @param cbStack See RTThreadCreate.
295 * @param enmType See RTThreadCreate.
296 * @param fFlags See RTThreadCreate.
297 * @param pszName Thread name format.
298 * @param va Format arguments.
299 */
300RTDECL(int) RTThreadCreateV(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
301 RTTHREADTYPE enmType, uint32_t fFlags, const char *pszNameFmt, va_list va);
302
303/**
304 * Create a new thread.
305 *
306 * Same as RTThreadCreate except the name is given in the RTStrPrintf form.
307 *
308 * @returns iprt status code.
309 * @param pThread See RTThreadCreate.
310 * @param pfnThread See RTThreadCreate.
311 * @param pvUser See RTThreadCreate.
312 * @param cbStack See RTThreadCreate.
313 * @param enmType See RTThreadCreate.
314 * @param fFlags See RTThreadCreate.
315 * @param pszName Thread name format.
316 * @param ... Format arguments.
317 */
318RTDECL(int) RTThreadCreateF(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
319 RTTHREADTYPE enmType, uint32_t fFlags, const char *pszNameFmt, ...);
320
321/**
322 * Gets the native thread id of a IPRT thread.
323 *
324 * @returns The native thread id.
325 * @param Thread The IPRT thread.
326 */
327RTDECL(RTNATIVETHREAD) RTThreadGetNative(RTTHREAD Thread);
328
329/**
330 * Gets the IPRT thread of a native thread.
331 *
332 * @returns The IPRT thread handle
333 * @returns NIL_RTTHREAD if not a thread known to IPRT.
334 * @param NativeThread The native thread handle/id.
335 */
336RTDECL(RTTHREAD) RTThreadFromNative(RTNATIVETHREAD NativeThread);
337
338/**
339 * Changes the type of the specified thread.
340 *
341 * @returns iprt status code.
342 * @param Thread The thread which type should be changed.
343 * @param enmType The new thread type.
344 * @remark In Ring-0 it only works if Thread == RTThreadSelf().
345 */
346RTDECL(int) RTThreadSetType(RTTHREAD Thread, RTTHREADTYPE enmType);
347
348/**
349 * Wait for the thread to terminate, resume on interruption.
350 *
351 * @returns iprt status code.
352 * Will not return VERR_INTERRUPTED.
353 * @param Thread The thread to wait for.
354 * @param cMillies The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
355 * an indefinite wait.
356 * @param prc Where to store the return code of the thread. Optional.
357 */
358RTDECL(int) RTThreadWait(RTTHREAD Thread, RTMSINTERVAL cMillies, int *prc);
359
360/**
361 * Wait for the thread to terminate, return on interruption.
362 *
363 * @returns iprt status code.
364 * @param Thread The thread to wait for.
365 * @param cMillies The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
366 * an indefinite wait.
367 * @param prc Where to store the return code of the thread. Optional.
368 */
369RTDECL(int) RTThreadWaitNoResume(RTTHREAD Thread, RTMSINTERVAL cMillies, int *prc);
370
371/**
372 * Gets the name of the current thread thread.
373 *
374 * @returns Pointer to readonly name string.
375 * @returns NULL on failure.
376 */
377RTDECL(const char *) RTThreadSelfName(void);
378
379/**
380 * Gets the name of a thread.
381 *
382 * @returns Pointer to readonly name string.
383 * @returns NULL on failure.
384 * @param Thread Thread handle of the thread to query the name of.
385 */
386RTDECL(const char *) RTThreadGetName(RTTHREAD Thread);
387
388/**
389 * Gets the type of the specified thread.
390 *
391 * @returns The thread type.
392 * @returns RTTHREADTYPE_INVALID if the thread handle is invalid.
393 * @param Thread The thread in question.
394 */
395RTDECL(RTTHREADTYPE) RTThreadGetType(RTTHREAD Thread);
396
397/**
398 * Sets the name of a thread.
399 *
400 * @returns iprt status code.
401 * @param Thread Thread handle of the thread to query the name of.
402 * @param pszName The thread name.
403 */
404RTDECL(int) RTThreadSetName(RTTHREAD Thread, const char *pszName);
405
406/**
407 * Checks if the specified thread is the main thread.
408 *
409 * @returns true if it is, false if it isn't.
410 *
411 * @param hThread The thread handle.
412 */
413RTDECL(bool) RTThreadIsMain(RTTHREAD hThread);
414
415/**
416 * Checks if the calling thread is known to IPRT.
417 *
418 * @returns @c true if it is, @c false if it isn't.
419 */
420RTDECL(bool) RTThreadIsSelfKnown(void);
421
422/**
423 * Checks if the calling thread is know to IPRT and is alive.
424 *
425 * @returns @c true if it is, @c false if it isn't.
426 */
427RTDECL(bool) RTThreadIsSelfAlive(void);
428
429/**
430 * Checks if the calling thread is known to IPRT.
431 *
432 * @returns @c true if it is, @c false if it isn't.
433 */
434RTDECL(bool) RTThreadIsOperational(void);
435
436/**
437 * Signal the user event.
438 *
439 * @returns iprt status code.
440 */
441RTDECL(int) RTThreadUserSignal(RTTHREAD Thread);
442
443/**
444 * Wait for the user event.
445 *
446 * @returns iprt status code.
447 * @param Thread The thread to wait for.
448 * @param cMillies The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
449 * an indefinite wait.
450 */
451RTDECL(int) RTThreadUserWait(RTTHREAD Thread, RTMSINTERVAL cMillies);
452
453/**
454 * Wait for the user event, return on interruption.
455 *
456 * @returns iprt status code.
457 * @param Thread The thread to wait for.
458 * @param cMillies The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
459 * an indefinite wait.
460 */
461RTDECL(int) RTThreadUserWaitNoResume(RTTHREAD Thread, RTMSINTERVAL cMillies);
462
463/**
464 * Reset the user event.
465 *
466 * @returns iprt status code.
467 * @param Thread The thread to reset.
468 */
469RTDECL(int) RTThreadUserReset(RTTHREAD Thread);
470
471/**
472 * Pokes the thread.
473 *
474 * This will signal the thread, attempting to interrupt whatever it's currently
475 * doing. This is *NOT* implemented on all platforms and may cause unresolved
476 * symbols during linking or VERR_NOT_IMPLEMENTED at runtime.
477 *
478 * @returns IPRT status code.
479 *
480 * @param hThread The thread to poke. This must not be the
481 * calling thread.
482 */
483RTDECL(int) RTThreadPoke(RTTHREAD hThread);
484
485# ifdef IN_RING0
486
487/**
488 * Check if preemption is currently enabled or not for the current thread.
489 *
490 * @note This may return true even on systems where preemption isn't
491 * possible. In that case, it means no call to RTThreadPreemptDisable
492 * has been made and interrupts are still enabled.
493 *
494 * @returns true if preemption is enabled, false if preemetion is disabled.
495 * @param hThread Must be NIL_RTTHREAD for now.
496 */
497RTDECL(bool) RTThreadPreemptIsEnabled(RTTHREAD hThread);
498
499/**
500 * Check if preemption is pending for the current thread.
501 *
502 * This function should be called regularly when executing larger portions of
503 * code with preemption disabled.
504 *
505 * @returns true if pending, false if not.
506 * @param hThread Must be NIL_RTTHREAD for now.
507 */
508RTDECL(bool) RTThreadPreemptIsPending(RTTHREAD hThread);
509
510/**
511 * Is RTThreadPreemptIsPending reliable?
512 *
513 * @returns true if reliable, false if not.
514 */
515RTDECL(bool) RTThreadPreemptIsPendingTrusty(void);
516
517/**
518 * Is preemption possible on this system.
519 *
520 * @returns true if possible, false if not.
521 */
522RTDECL(bool) RTThreadPreemptIsPossible(void);
523
524/**
525 * Preemption state saved by RTThreadPreemptDisable and used by
526 * RTThreadPreemptRestore to restore the previous state.
527 */
528typedef struct RTTHREADPREEMPTSTATE
529{
530 /** In debug builds this will be used to check for cpu migration. */
531 RTCPUID idCpu;
532# ifdef RT_OS_WINDOWS
533 /** The old IRQL. Don't touch! */
534 unsigned char uchOldIrql;
535 /** Reserved, MBZ. */
536 uint8_t bReserved1;
537 /** Reserved, MBZ. */
538 uint8_t bReserved2;
539 /** Reserved, MBZ. */
540 uint8_t bReserved3;
541# define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, 255, 0, 0, 0 }
542# elif defined(RT_OS_HAIKU)
543 /** The cpu_state. Don't touch! */
544 uint32_t uOldCpuState;
545# define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, 0 }
546# elif defined(RT_OS_SOLARIS)
547 /** The Old PIL. Don't touch! */
548 uint32_t uOldPil;
549# define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, UINT32_MAX }
550# else
551 /** Reserved, MBZ. */
552 uint32_t u32Reserved;
553# define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, 0 }
554# endif
555} RTTHREADPREEMPTSTATE;
556/** Pointer to a preemption state. */
557typedef RTTHREADPREEMPTSTATE *PRTTHREADPREEMPTSTATE;
558
559/**
560 * Disable preemption.
561 *
562 * A call to this function must be matched by exactly one call to
563 * RTThreadPreemptRestore().
564 *
565 * @param pState Where to store the preemption state.
566 */
567RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState);
568
569/**
570 * Restores the preemption state, undoing a previous call to
571 * RTThreadPreemptDisable.
572 *
573 * A call to this function must be matching a previous call to
574 * RTThreadPreemptDisable.
575 *
576 * @param pState The state return by RTThreadPreemptDisable.
577 */
578RTDECL(void) RTThreadPreemptRestore(PRTTHREADPREEMPTSTATE pState);
579
580/**
581 * Check if the thread is executing in interrupt context.
582 *
583 * @returns true if in interrupt context, false if not.
584 * @param hThread Must be NIL_RTTHREAD for now.
585 */
586RTDECL(bool) RTThreadIsInInterrupt(RTTHREAD hThread);
587
588
589/**
590 * Thread context swithcing events.
591 */
592typedef enum RTTHREADCTXEVENT
593{
594 /** This thread is being scheduled out on the current CPU (includes preemption,
595 * waiting, sleep and whatever else may trigger scheduling). */
596 RTTHREADCTXEVENT_OUT = 0,
597 /** This thread is being scheduled in on the current CPU and will resume
598 * execution. */
599 RTTHREADCTXEVENT_IN,
600 /** The usual 32-bit size hack. */
601 RTTHREADCTXEVENT_32BIT_HACK = 0x7fffffff
602} RTTHREADCTXEVENT;
603
604/**
605 * Thread context switching hook callback.
606 *
607 * This hook function is called when a thread is scheduled and preempted. Check
608 * @a enmEvent to see which it is. Since the function is being called from
609 * hooks inside the scheduler, it is limited what you can do from this function.
610 * Do NOT acquire locks, sleep or yield the thread for instance. IRQ safe
611 * spinlocks are fine though.
612 *
613 * @returns IPRT status code.
614 * @param enmEvent The thread-context event. Please quitely ignore unknown
615 * events, we may add more (thread exit, ++) later.
616 * @param pvUser User argument.
617 */
618typedef DECLCALLBACK(void) FNRTTHREADCTXHOOK(RTTHREADCTXEVENT enmEvent, void *pvUser);
619/** Pointer to a context switching hook. */
620typedef FNRTTHREADCTXHOOK *PFNRTTHREADCTXHOOK;
621
622/**
623 * Initializes a thread context switching hook for the current thread.
624 *
625 * The hook is created as disabled, use RTThreadCtxHookEnable to enable it.
626 *
627 * @returns IPRT status code.
628 * @param phCtxHook Where to store the hook handle.
629 * @param fFlags Reserved for future extensions, must be zero.
630 * @param pfnCallback Pointer to a the hook function (callback) that
631 * should be called for all context switching events
632 * involving the current thread.
633 * @param pvUser User argument that will be passed to @a pfnCallback.
634 * @remarks Preemption must be enabled.
635 */
636RTDECL(int) RTThreadCtxHookCreate(PRTTHREADCTXHOOK phCtxHook, uint32_t fFlags, PFNRTTHREADCTXHOOK pfnCallback, void *pvUser);
637
638/**
639 * Destroys a thread context switching hook.
640 *
641 * Caller must make sure the hook is disabled before the final reference is
642 * released. Recommended to call this on the owning thread, otherwise the
643 * memory backing it may on some systems only be released when the thread
644 * terminates.
645 *
646 * @returns IPRT status code.
647 *
648 * @param hCtxHook The context hook handle. NIL_RTTHREADCTXHOOK is
649 * ignored and the function will return VINF_SUCCESS.
650 * @remarks Preemption must be enabled.
651 * @remarks Do not call from FNRTTHREADCTXHOOK.
652 */
653RTDECL(int) RTThreadCtxHookDestroy(RTTHREADCTXHOOK hCtxHook);
654
655/**
656 * Enables the context switching hooks for the current thread.
657 *
658 * @returns IPRT status code.
659 * @param hCtxHook The context hook handle.
660 * @remarks Should be called with preemption disabled.
661 */
662RTDECL(int) RTThreadCtxHookEnable(RTTHREADCTXHOOK hCtxHook);
663
664/**
665 * Disables the thread context switching hook for the current thread.
666 *
667 * Will not assert or fail if called twice or with a NIL handle.
668 *
669 * @returns IPRT status code.
670 * @param hCtxHook The context hook handle. NIL_RTTHREADCTXHOOK is
671 * ignored and the function wil return VINF_SUCCESS.
672 * @remarks Should be called with preemption disabled.
673 * @remarks Do not call from FNRTTHREADCTXHOOK.
674 */
675RTDECL(int) RTThreadCtxHookDisable(RTTHREADCTXHOOK hCtxHook);
676
677/**
678 * Is the thread context switching hook enabled?
679 *
680 * @returns true if registered, false if not supported or not registered.
681 * @param hCtxHook The context hook handle. NIL_RTTHREADCTXHOOK is
682 * ignored and the function will return false.
683 *
684 * @remarks Can be called from any thread, though is naturally subject to races
685 * when not called from the thread associated with the hook.
686 */
687RTDECL(bool) RTThreadCtxHookIsEnabled(RTTHREADCTXHOOK hCtxHook);
688
689# endif /* IN_RING0 */
690
691
692# ifdef IN_RING3
693
694/**
695 * Adopts a non-IPRT thread.
696 *
697 * @returns IPRT status code.
698 * @param enmType The thread type.
699 * @param fFlags The thread flags. RTTHREADFLAGS_WAITABLE is not currently allowed.
700 * @param pszName The thread name. Optional
701 * @param pThread Where to store the thread handle. Optional.
702 */
703RTDECL(int) RTThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, const char *pszName, PRTTHREAD pThread);
704
705/**
706 * Get the thread handle of the current thread, automatically adopting alien
707 * threads.
708 *
709 * @returns Thread handle.
710 */
711RTDECL(RTTHREAD) RTThreadSelfAutoAdopt(void);
712
713/**
714 * Gets the affinity mask of the current thread.
715 *
716 * @returns IPRT status code.
717 * @param pCpuSet Where to return the CPU affienty set of the calling
718 * thread.
719 */
720RTR3DECL(int) RTThreadGetAffinity(PRTCPUSET pCpuSet);
721
722/**
723 * Sets the affinity mask of the current thread.
724 *
725 * @returns iprt status code.
726 * @param pCpuSet The set of CPUs this thread can run on. NULL means
727 * all CPUs.
728 */
729RTR3DECL(int) RTThreadSetAffinity(PCRTCPUSET pCpuSet);
730
731/**
732 * Binds the thread to one specific CPU.
733 *
734 * @returns iprt status code.
735 * @param idCpu The ID of the CPU to bind this thread to. Use
736 * NIL_RTCPUID to unbind it.
737 */
738RTR3DECL(int) RTThreadSetAffinityToCpu(RTCPUID idCpu);
739
740/**
741 * Unblocks a thread.
742 *
743 * This function is paired with RTThreadBlocking and RTThreadBlockingDebug.
744 *
745 * @param hThread The current thread.
746 * @param enmCurState The current state, used to check for nested blocking.
747 * The new state will be running.
748 */
749RTDECL(void) RTThreadUnblocked(RTTHREAD hThread, RTTHREADSTATE enmCurState);
750
751/**
752 * Change the thread state to blocking.
753 *
754 * @param hThread The current thread.
755 * @param enmState The sleep state.
756 * @param fReallySleeping Really going to sleep now. Use false before calls
757 * to other IPRT synchronization methods.
758 */
759RTDECL(void) RTThreadBlocking(RTTHREAD hThread, RTTHREADSTATE enmState, bool fReallySleeping);
760
761/**
762 * Get the current thread state.
763 *
764 * A thread that is reported as sleeping may actually still be running inside
765 * the lock validator or/and in the code of some other IPRT synchronization
766 * primitive. Use RTThreadGetReallySleeping
767 *
768 * @returns The thread state.
769 * @param hThread The thread.
770 */
771RTDECL(RTTHREADSTATE) RTThreadGetState(RTTHREAD hThread);
772
773/**
774 * Checks if the thread is really sleeping or not.
775 *
776 * @returns RTTHREADSTATE_RUNNING if not really sleeping, otherwise the state it
777 * is sleeping in.
778 * @param hThread The thread.
779 */
780RTDECL(RTTHREADSTATE) RTThreadGetReallySleeping(RTTHREAD hThread);
781
782/**
783 * Translate a thread state into a string.
784 *
785 * @returns Pointer to a read-only string containing the state name.
786 * @param enmState The state.
787 */
788RTDECL(const char *) RTThreadStateName(RTTHREADSTATE enmState);
789
790
791/**
792 * Native thread states returned by RTThreadNativeState.
793 */
794typedef enum RTTHREADNATIVESTATE
795{
796 /** Invalid thread handle. */
797 RTTHREADNATIVESTATE_INVALID = 0,
798 /** Unable to determine the thread state. */
799 RTTHREADNATIVESTATE_UNKNOWN,
800 /** The thread is running. */
801 RTTHREADNATIVESTATE_RUNNING,
802 /** The thread is blocked. */
803 RTTHREADNATIVESTATE_BLOCKED,
804 /** The thread is suspended / stopped. */
805 RTTHREADNATIVESTATE_SUSPENDED,
806 /** The thread has terminated. */
807 RTTHREADNATIVESTATE_TERMINATED,
808 /** Make sure it's a 32-bit type. */
809 RTTHREADNATIVESTATE_32BIT_HACK = 0x7fffffff
810} RTTHREADNATIVESTATE;
811
812
813/**
814 * Get the native state of a thread.
815 *
816 * @returns Native state.
817 * @param hThread The thread handle.
818 *
819 * @remarks Not yet implemented on all systems, so have a backup plan for
820 * RTTHREADNATIVESTATE_UNKNOWN.
821 */
822RTDECL(RTTHREADNATIVESTATE) RTThreadGetNativeState(RTTHREAD hThread);
823
824
825/**
826 * Get the execution times of the specified thread
827 *
828 * @returns IPRT status code.
829 * @param pKernelTime Kernel execution time in ms (out)
830 * @param pUserTime User execution time in ms (out)
831 *
832 */
833RTR3DECL(int) RTThreadGetExecutionTimeMilli(uint64_t *pKernelTime, uint64_t *pUserTime);
834
835/** @name Thread Local Storage
836 * @{
837 */
838/**
839 * Thread termination callback for destroying a non-zero TLS entry.
840 *
841 * @remarks It is not permitable to use any RTTls APIs at this time. Doing so
842 * may lead to endless loops, crashes, and other bad stuff.
843 *
844 * @param pvValue The current value.
845 */
846typedef DECLCALLBACK(void) FNRTTLSDTOR(void *pvValue);
847/** Pointer to a FNRTTLSDTOR. */
848typedef FNRTTLSDTOR *PFNRTTLSDTOR;
849
850/**
851 * Allocates a TLS entry (index).
852 *
853 * Example code:
854 * @code
855 RTTLS g_iTls = NIL_RTTLS;
856
857 ...
858
859 // once for the process, allocate the TLS index
860 if (g_iTls == NIL_RTTLS)
861 g_iTls = RTTlsAlloc();
862
863 // set the thread-local value.
864 RTTlsSet(g_iTls, pMyData);
865
866 ...
867
868 // get the thread-local value
869 PMYDATA pMyData = (PMYDATA)RTTlsGet(g_iTls);
870
871 @endcode
872 *
873 * @returns the index of the allocated TLS entry.
874 * @returns NIL_RTTLS on failure.
875 */
876RTR3DECL(RTTLS) RTTlsAlloc(void);
877
878/**
879 * Variant of RTTlsAlloc that returns a status code.
880 *
881 * @returns IPRT status code.
882 * @retval VERR_NOT_SUPPORTED if pfnDestructor is non-NULL and the platform
883 * doesn't support this feature.
884 *
885 * @param piTls Where to store the index of the allocated TLS entry.
886 * This is set to NIL_RTTLS on failure.
887 * @param pfnDestructor Optional callback function for cleaning up on
888 * thread termination. WARNING! This feature may not
889 * be implemented everywhere.
890 */
891RTR3DECL(int) RTTlsAllocEx(PRTTLS piTls, PFNRTTLSDTOR pfnDestructor);
892
893/**
894 * Frees a TLS entry.
895 *
896 * @returns IPRT status code.
897 * @param iTls The index of the TLS entry.
898 */
899RTR3DECL(int) RTTlsFree(RTTLS iTls);
900
901/**
902 * Get the (thread-local) value stored in a TLS entry.
903 *
904 * @returns value in given TLS entry.
905 * @retval NULL if RTTlsSet() has not yet been called on this thread, or if the
906 * TLS index is invalid.
907 *
908 * @param iTls The index of the TLS entry.
909 */
910RTR3DECL(void *) RTTlsGet(RTTLS iTls);
911
912/**
913 * Get the value stored in a TLS entry.
914 *
915 * @returns IPRT status code.
916 * @param iTls The index of the TLS entry.
917 * @param ppvValue Where to store the value. The value will be NULL if
918 * RTTlsSet has not yet been called on this thread.
919 */
920RTR3DECL(int) RTTlsGetEx(RTTLS iTls, void **ppvValue);
921
922/**
923 * Set the value stored in an allocated TLS entry.
924 *
925 * @returns IPRT status.
926 * @param iTls The index of the TLS entry.
927 * @param pvValue The value to store.
928 *
929 * @remarks Note that NULL is considered a special value.
930 */
931RTR3DECL(int) RTTlsSet(RTTLS iTls, void *pvValue);
932
933/** @} */
934
935# endif /* IN_RING3 */
936# endif /* !IN_RC */
937
938/** @} */
939
940RT_C_DECLS_END
941
942#endif
943
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