VirtualBox

source: vbox/trunk/include/VBox/pdmthread.h@ 12977

Last change on this file since 12977 was 12324, checked in by vboxsync, 16 years ago

PDMThread: New API PDMR3ThreadSleep. Fixed a per thread event sem leak.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 12.9 KB
Line 
1/** @file
2 * PDM - Pluggable Device Manager, Threads.
3 */
4
5/*
6 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
26 * Clara, CA 95054 USA or visit http://www.sun.com if you need
27 * additional information or have any questions.
28 */
29
30#ifndef ___VBox_pdmthread_h
31#define ___VBox_pdmthread_h
32
33#include <VBox/cdefs.h>
34#include <VBox/types.h>
35#ifdef IN_RING3
36# include <iprt/thread.h>
37#endif
38
39__BEGIN_DECLS
40
41/** @group grp_pdm_thread Threads
42 * @ingroup grp_pdm
43 * @{
44 */
45
46/**
47 * The thread state
48 */
49typedef enum PDMTHREADSTATE
50{
51 /** The usual invalid 0 entry. */
52 PDMTHREADSTATE_INVALID = 0,
53 /** The thread is initializing.
54 * Prev state: none
55 * Next state: suspended, terminating (error) */
56 PDMTHREADSTATE_INITIALIZING,
57 /** The thread has been asked to suspend.
58 * Prev state: running
59 * Next state: suspended */
60 PDMTHREADSTATE_SUSPENDING,
61 /** The thread is supended.
62 * Prev state: suspending, initializing
63 * Next state: resuming, terminated. */
64 PDMTHREADSTATE_SUSPENDED,
65 /** The thread is active.
66 * Prev state: suspended
67 * Next state: running, terminating. */
68 PDMTHREADSTATE_RESUMING,
69 /** The thread is active.
70 * Prev state: resuming
71 * Next state: suspending, terminating. */
72 PDMTHREADSTATE_RUNNING,
73 /** The thread has been asked to terminate.
74 * Prev state: initializing, suspended, resuming, running
75 * Next state: terminated. */
76 PDMTHREADSTATE_TERMINATING,
77 /** The thread is terminating / has terminated.
78 * Prev state: terminating
79 * Next state: none */
80 PDMTHREADSTATE_TERMINATED,
81 /** The usual 32-bit hack. */
82 PDMTHREADSTATE_32BIT_HACK = 0x7fffffff
83} PDMTHREADSTATE;
84
85/** A pointer to a PDM thread. */
86typedef R3PTRTYPE(struct PDMTHREAD *) PPDMTHREAD;
87/** A pointer to a pointer to a PDM thread. */
88typedef PPDMTHREAD *PPPDMTHREAD;
89
90/**
91 * PDM thread, device variation.
92 *
93 * @returns VBox status code.
94 * @param pDevIns The device instance.
95 * @param pThread The PDM thread data.
96 */
97typedef int FNPDMTHREADDEV(PPDMDEVINS pDevIns, PPDMTHREAD pThread);
98/** Pointer to a FNPDMTHREADDEV(). */
99typedef FNPDMTHREADDEV *PFNPDMTHREADDEV;
100
101/**
102 * PDM thread, USB device variation.
103 *
104 * @returns VBox status code.
105 * @param pUsbIns The USB device instance.
106 * @param pThread The PDM thread data.
107 */
108typedef int FNPDMTHREADUSB(PPDMUSBINS pUsbIns, PPDMTHREAD pThread);
109/** Pointer to a FNPDMTHREADUSB(). */
110typedef FNPDMTHREADUSB *PFNPDMTHREADUSB;
111
112/**
113 * PDM thread, driver variation.
114 *
115 * @returns VBox status code.
116 * @param pDrvIns The driver instance.
117 * @param pThread The PDM thread data.
118 */
119typedef int FNPDMTHREADDRV(PPDMDRVINS pDrvIns, PPDMTHREAD pThread);
120/** Pointer to a FNPDMTHREADDRV(). */
121typedef FNPDMTHREADDRV *PFNPDMTHREADDRV;
122
123/**
124 * PDM thread, driver variation.
125 *
126 * @returns VBox status code.
127 * @param pVM The VM handle.
128 * @param pThread The PDM thread data.
129 */
130typedef int FNPDMTHREADINT(PVM pVM, PPDMTHREAD pThread);
131/** Pointer to a FNPDMTHREADINT(). */
132typedef FNPDMTHREADINT *PFNPDMTHREADINT;
133
134/**
135 * PDM thread, driver variation.
136 *
137 * @returns VBox status code.
138 * @param pThread The PDM thread data.
139 */
140typedef int FNPDMTHREADEXT(PPDMTHREAD pThread);
141/** Pointer to a FNPDMTHREADEXT(). */
142typedef FNPDMTHREADEXT *PFNPDMTHREADEXT;
143
144
145
146/**
147 * PDM thread wakeup call, device variation.
148 *
149 * @returns VBox status code.
150 * @param pDevIns The device instance.
151 * @param pThread The PDM thread data.
152 */
153typedef int FNPDMTHREADWAKEUPDEV(PPDMDEVINS pDevIns, PPDMTHREAD pThread);
154/** Pointer to a FNPDMTHREADDEV(). */
155typedef FNPDMTHREADWAKEUPDEV *PFNPDMTHREADWAKEUPDEV;
156
157/**
158 * PDM thread wakeup call, device variation.
159 *
160 * @returns VBox status code.
161 * @param pUsbIns The USB device instance.
162 * @param pThread The PDM thread data.
163 */
164typedef int FNPDMTHREADWAKEUPUSB(PPDMUSBINS pUsbIns, PPDMTHREAD pThread);
165/** Pointer to a FNPDMTHREADUSB(). */
166typedef FNPDMTHREADWAKEUPUSB *PFNPDMTHREADWAKEUPUSB;
167
168/**
169 * PDM thread wakeup call, driver variation.
170 *
171 * @returns VBox status code.
172 * @param pDrvIns The driver instance.
173 * @param pThread The PDM thread data.
174 */
175typedef int FNPDMTHREADWAKEUPDRV(PPDMDRVINS pDrvIns, PPDMTHREAD pThread);
176/** Pointer to a FNPDMTHREADDRV(). */
177typedef FNPDMTHREADWAKEUPDRV *PFNPDMTHREADWAKEUPDRV;
178
179/**
180 * PDM thread wakeup call, internal variation.
181 *
182 * @returns VBox status code.
183 * @param pVM The VM handle.
184 * @param pThread The PDM thread data.
185 */
186typedef int FNPDMTHREADWAKEUPINT(PVM pVM, PPDMTHREAD pThread);
187/** Pointer to a FNPDMTHREADWAKEUPINT(). */
188typedef FNPDMTHREADWAKEUPINT *PFNPDMTHREADWAKEUPINT;
189
190/**
191 * PDM thread wakeup call, external variation.
192 *
193 * @returns VBox status code.
194 * @param pThread The PDM thread data.
195 */
196typedef int FNPDMTHREADWAKEUPEXT(PPDMTHREAD pThread);
197/** Pointer to a FNPDMTHREADEXT(). */
198typedef FNPDMTHREADWAKEUPEXT *PFNPDMTHREADWAKEUPEXT;
199
200
201/**
202 * PDM Thread instance data.
203 */
204typedef struct PDMTHREAD
205{
206 /** PDMTHREAD_VERSION. */
207 uint32_t u32Version;
208 /** The thread state. */
209 PDMTHREADSTATE volatile enmState;
210 /** The thread handle. */
211 RTTHREAD Thread;
212 /** The user parameter. */
213 R3PTRTYPE(void *) pvUser;
214 /** Data specific to the kind of thread.
215 * This should really be in PDMTHREADINT, but is placed here because of the
216 * function pointer typedefs. So, don't touch these, please.
217 */
218 union
219 {
220 /** PDMTHREADTYPE_DEVICE data. */
221 struct
222 {
223 /** The device instance. */
224 PPDMDEVINSR3 pDevIns;
225 /** The thread function. */
226 R3PTRTYPE(PFNPDMTHREADDEV) pfnThread;
227 /** Thread. */
228 R3PTRTYPE(PFNPDMTHREADWAKEUPDEV) pfnWakeUp;
229 } Dev;
230
231 /** PDMTHREADTYPE_USB data. */
232 struct
233 {
234 /** The device instance. */
235 PPDMUSBINS pUsbIns;
236 /** The thread function. */
237 R3PTRTYPE(PFNPDMTHREADUSB) pfnThread;
238 /** Thread. */
239 R3PTRTYPE(PFNPDMTHREADWAKEUPUSB) pfnWakeUp;
240 } Usb;
241
242 /** PDMTHREADTYPE_DRIVER data. */
243 struct
244 {
245 /** The driver instance. */
246 R3PTRTYPE(PPDMDRVINS) pDrvIns;
247 /** The thread function. */
248 R3PTRTYPE(PFNPDMTHREADDRV) pfnThread;
249 /** Thread. */
250 R3PTRTYPE(PFNPDMTHREADWAKEUPDRV) pfnWakeUp;
251 } Drv;
252
253 /** PDMTHREADTYPE_INTERNAL data. */
254 struct
255 {
256 /** The thread function. */
257 R3PTRTYPE(PFNPDMTHREADINT) pfnThread;
258 /** Thread. */
259 R3PTRTYPE(PFNPDMTHREADWAKEUPINT) pfnWakeUp;
260 } Int;
261
262 /** PDMTHREADTYPE_EXTERNAL data. */
263 struct
264 {
265 /** The thread function. */
266 R3PTRTYPE(PFNPDMTHREADEXT) pfnThread;
267 /** Thread. */
268 R3PTRTYPE(PFNPDMTHREADWAKEUPEXT) pfnWakeUp;
269 } Ext;
270 } u;
271
272 /** Internal data. */
273 union
274 {
275#ifdef PDMTHREADINT_DECLARED
276 PDMTHREADINT s;
277#endif
278 uint8_t padding[64];
279 } Internal;
280} PDMTHREAD;
281
282/** PDMTHREAD::u32Version value. */
283#define PDMTHREAD_VERSION 0xef010000
284
285#ifdef IN_RING3
286/**
287 * Creates a PDM thread for internal use in the VM.
288 *
289 * @returns VBox status code.
290 * @param pVM The VM handle.
291 * @param ppThread Where to store the thread 'handle'.
292 * @param pvUser The user argument to the thread function.
293 * @param pfnThread The thread function.
294 * @param pfnWakeUp The wakup callback. This is called on the EMT thread when
295 * a state change is pending.
296 * @param cbStack See RTThreadCreate.
297 * @param enmType See RTThreadCreate.
298 * @param pszName See RTThreadCreate.
299 */
300PDMR3DECL(int) PDMR3ThreadCreate(PVM pVM, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADINT pfnThread,
301 PFNPDMTHREADWAKEUPINT pfnWakeUp, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
302
303/**
304 * Creates a PDM thread for VM use by some external party.
305 *
306 * @returns VBox status code.
307 * @param pVM The VM handle.
308 * @param ppThread Where to store the thread 'handle'.
309 * @param pvUser The user argument to the thread function.
310 * @param pfnThread The thread function.
311 * @param pfnWakeUp The wakup callback. This is called on the EMT thread when
312 * a state change is pending.
313 * @param cbStack See RTThreadCreate.
314 * @param enmType See RTThreadCreate.
315 * @param pszName See RTThreadCreate.
316 */
317PDMR3DECL(int) PDMR3ThreadCreateExternal(PVM pVM, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADEXT pfnThread,
318 PFNPDMTHREADWAKEUPEXT pfnWakeUp, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
319
320/**
321 * Destroys a PDM thread.
322 *
323 * This will wakeup the thread, tell it to terminate, and wait for it terminate.
324 *
325 * @returns VBox status code.
326 * This reflects the success off destroying the thread and not the exit code
327 * of the thread as this is stored in *pRcThread.
328 * @param pThread The thread to destroy.
329 * @param pRcThread Where to store the thread exit code. Optional.
330 * @thread The emulation thread (EMT).
331 */
332PDMR3DECL(int) PDMR3ThreadDestroy(PPDMTHREAD pThread, int *pRcThread);
333
334/**
335 * Called by the PDM thread in response to a wakeup call with
336 * suspending as the new state.
337 *
338 * The thread will block in side this call until the state is changed in
339 * response to a VM state change or to the device/driver/whatever calling the
340 * PDMR3ThreadResume API.
341 *
342 * @returns VBox status code.
343 * On failure, terminate the thread.
344 * @param pThread The PDM thread.
345 */
346PDMR3DECL(int) PDMR3ThreadIAmSuspending(PPDMTHREAD pThread);
347
348/**
349 * Called by the PDM thread in response to a resuming state.
350 *
351 * The purpose of this API is to tell the PDMR3ThreadResume caller that
352 * the the PDM thread has successfully resumed. It will also do the
353 * state transition from the resuming to the running state.
354 *
355 * @returns VBox status code.
356 * On failure, terminate the thread.
357 * @param pThread The PDM thread.
358 */
359PDMR3DECL(int) PDMR3ThreadIAmRunning(PPDMTHREAD pThread);
360
361/**
362 * Called by the PDM thread instead of RTThreadSleep.
363 *
364 * The difference is that the sleep will be interrupted on state change. The
365 * thread must be in the running state, otherwise it will return immediately.
366 *
367 * @returns VBox status code.
368 * @retval VINF_SUCCESS on success or state change.
369 * @retval VERR_INTERRUPTED on signal or APC.
370 *
371 * @param pThread The PDM thread.
372 * @param cMillies The number of milliseconds to sleep.
373 */
374PDMR3DECL(int) PDMR3ThreadSleep(PPDMTHREAD pThread, unsigned cMillies);
375
376/**
377 * Suspends the thread.
378 *
379 * This can be called at the power off / suspend notifications to suspend the
380 * PDM thread a bit early. The thread will be automatically suspend upon
381 * completion of the device/driver notification cycle.
382 *
383 * The caller is responsible for serializing the control operations on the
384 * thread. That basically means, always do these calls from the EMT.
385 *
386 * @returns VBox status code.
387 * @param pThread The PDM thread.
388 */
389PDMR3DECL(int) PDMR3ThreadSuspend(PPDMTHREAD pThread);
390
391/**
392 * Resumes the thread.
393 *
394 * This can be called the power on / resume notifications to resume the
395 * PDM thread a bit early. The thread will be automatically resumed upon
396 * return from these two notification callbacks (devices/drivers).
397 *
398 * The caller is responsible for serializing the control operations on the
399 * thread. That basically means, always do these calls from the EMT.
400 *
401 * @returns VBox status code.
402 * @param pThread The PDM thread.
403 */
404PDMR3DECL(int) PDMR3ThreadResume(PPDMTHREAD pThread);
405#endif /* IN_RING3 */
406
407/** @} */
408
409__END_DECLS
410
411#endif
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