~ubuntu-branches/ubuntu/raring/virtualbox-ose/raring

« back to all changes in this revision

Viewing changes to src/VBox/Runtime/r0drv/mpnotification-r0drv.c

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2009-12-18 16:44:29 UTC
  • mfrom: (0.3.3 upstream) (0.4.6 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091218164429-jd34ccexpv5na11a
Tags: 3.1.2-dfsg-1ubuntu1
* Merge from Debian unstable (LP: #498219), remaining changes:
  - Disable update action
    - debian/patches/u01-disable-update-action.dpatch
  - VirtualBox should go in Accessories, not in System tools (LP: #288590)
    - debian/virtualbox-ose-qt.files/virtualbox-ose.desktop
  - Add Apport hook
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Add Launchpad integration
    - debian/control
    - debian/lpi-bug.xpm
    - debian/patches/u02-lp-integration.dpatch
* Fixes the following bugs:
  - Kernel module fails to build with Linux >= 2.6.32 (LP: #474625)
  - X.Org drivers need to be rebuilt against X-Server 1.7 (LP: #495935)
  - The *-source packages try to build the kernel modules even though the
    kernel headers aren't available (LP: #473334)
* Replace *-source packages with transitional packages for *-dkms.
* Adapt u01-disable-update-action.dpatch and u02-lp-integration.dpatch for
  new upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
 * additional information or have any questions.
29
29
 */
30
30
 
 
31
 
31
32
/*******************************************************************************
32
33
*   Header Files                                                               *
33
34
*******************************************************************************/
34
35
#include <iprt/mp.h>
 
36
#include "internal/iprt.h"
 
37
 
35
38
#include <iprt/asm.h>
36
39
#include <iprt/assert.h>
37
40
#include <iprt/err.h>
38
41
#include <iprt/mem.h>
39
42
#include <iprt/spinlock.h>
40
43
#include <iprt/string.h>
 
44
#include <iprt/thread.h>
41
45
#include "r0drv/mp-r0drv.h"
42
46
 
43
47
 
76
80
 * This is increased whenever the list has been modified. The callback routine
77
81
 * make use of this to avoid having restart at the list head after each callback. */
78
82
static uint32_t volatile g_iRTMpGeneration;
79
 
/** The number of RTMpNotification users.
80
 
 * This is incremented on init and decremented on termination. */
81
 
static uint32_t volatile g_cRTMpUsers = 0;
82
83
 
83
84
 
84
85
 
91
92
 */
92
93
void rtMpNotificationDoCallbacks(RTMPEVENT enmEvent, RTCPUID idCpu)
93
94
{
94
 
    PRTMPNOTIFYREG pCur;
95
 
    RTSPINLOCKTMP Tmp;
96
 
    RTSPINLOCK hSpinlock;
 
95
    PRTMPNOTIFYREG  pCur;
 
96
    RTSPINLOCK      hSpinlock;
 
97
    RTSPINLOCKTMP   Tmp = RTSPINLOCKTMP_INITIALIZER;
97
98
 
98
99
    /*
99
100
     * This is a little bit tricky as we cannot be holding the spinlock
161
162
 
162
163
RTDECL(int) RTMpNotificationRegister(PFNRTMPNOTIFICATION pfnCallback, void *pvUser)
163
164
{
164
 
    PRTMPNOTIFYREG pCur;
165
 
    PRTMPNOTIFYREG pNew;
166
 
    RTSPINLOCKTMP Tmp;
 
165
    PRTMPNOTIFYREG  pCur;
 
166
    PRTMPNOTIFYREG  pNew;
 
167
    RTSPINLOCKTMP   Tmp = RTSPINLOCKTMP_INITIALIZER;
167
168
 
168
169
    /*
169
170
     * Validation.
170
171
     */
171
172
    AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER);
172
173
    AssertReturn(g_hRTMpNotifySpinLock != NIL_RTSPINLOCK, VERR_WRONG_ORDER);
 
174
    RT_ASSERT_PREEMPTIBLE();
173
175
 
174
176
    RTSpinlockAcquire(g_hRTMpNotifySpinLock, &Tmp);
175
177
    for (pCur = g_pRTMpCallbackHead; pCur; pCur = pCur->pNext)
223
225
 
224
226
    return VINF_SUCCESS;
225
227
}
226
 
 
 
228
RT_EXPORT_SYMBOL(RTMpNotificationRegister);
227
229
 
228
230
 
229
231
RTDECL(int) RTMpNotificationDeregister(PFNRTMPNOTIFICATION pfnCallback, void *pvUser)
230
232
{
231
 
    PRTMPNOTIFYREG pPrev;
232
 
    PRTMPNOTIFYREG pCur;
233
 
    RTSPINLOCKTMP Tmp;
 
233
    PRTMPNOTIFYREG  pPrev;
 
234
    PRTMPNOTIFYREG  pCur;
 
235
    RTSPINLOCKTMP   Tmp = RTSPINLOCKTMP_INITIALIZER;
234
236
 
235
237
    /*
236
238
     * Validation.
237
239
     */
238
240
    AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER);
239
241
    AssertReturn(g_hRTMpNotifySpinLock != NIL_RTSPINLOCK, VERR_WRONG_ORDER);
 
242
    RT_ASSERT_INTS_ON();
240
243
 
241
244
    /*
242
245
     * Find and unlink the record from the list.
272
275
 
273
276
    return VINF_SUCCESS;
274
277
}
 
278
RT_EXPORT_SYMBOL(RTMpNotificationDeregister);
275
279
 
276
280
 
277
281
int rtR0MpNotificationInit(void)
278
282
{
279
 
    int rc = VINF_SUCCESS;
280
 
 
281
 
    if (ASMAtomicIncS32(&g_cRTMpUsers) == 1)
 
283
    int rc = RTSpinlockCreate((PRTSPINLOCK)&g_hRTMpNotifySpinLock);
 
284
    if (RT_SUCCESS(rc))
282
285
    {
283
 
        rc = RTSpinlockCreate((PRTSPINLOCK)&g_hRTMpNotifySpinLock);
 
286
        rc = rtR0MpNotificationNativeInit();
284
287
        if (RT_SUCCESS(rc))
285
 
        {
286
 
            rc = rtR0MpNotificationNativeInit();
287
 
            if (RT_SUCCESS(rc))
288
 
                return rc;
 
288
            return rc;
289
289
 
290
 
            RTSpinlockDestroy(g_hRTMpNotifySpinLock);
291
 
            g_hRTMpNotifySpinLock = NIL_RTSPINLOCK;
292
 
        }
293
 
        ASMAtomicDecS32(&g_cRTMpUsers);
 
290
        RTSpinlockDestroy(g_hRTMpNotifySpinLock);
 
291
        g_hRTMpNotifySpinLock = NIL_RTSPINLOCK;
294
292
    }
295
293
    return rc;
296
294
}
298
296
 
299
297
void rtR0MpNotificationTerm(void)
300
298
{
301
 
    RTSPINLOCK hSpinlock = g_hRTMpNotifySpinLock;
302
 
    if (hSpinlock != NIL_RTSPINLOCK)
 
299
    PRTMPNOTIFYREG  pHead;
 
300
    RTSPINLOCKTMP   Tmp       = RTSPINLOCKTMP_INITIALIZER;
 
301
    RTSPINLOCK      hSpinlock = g_hRTMpNotifySpinLock;
 
302
    AssertReturnVoid(hSpinlock != NIL_RTSPINLOCK);
 
303
 
 
304
    rtR0MpNotificationNativeTerm();
 
305
 
 
306
    /* pick up the list and the spinlock. */
 
307
    RTSpinlockAcquire(hSpinlock, &Tmp);
 
308
    ASMAtomicWriteSize(&g_hRTMpNotifySpinLock, NIL_RTSPINLOCK);
 
309
    pHead = g_pRTMpCallbackHead;
 
310
    g_pRTMpCallbackHead = NULL;
 
311
    ASMAtomicIncU32(&g_iRTMpGeneration);
 
312
    RTSpinlockRelease(hSpinlock, &Tmp);
 
313
 
 
314
    /* free the list. */
 
315
    while (pHead)
303
316
    {
304
 
        AssertMsg(g_cRTMpUsers > 0, ("%d\n", g_cRTMpUsers));
305
 
        if (ASMAtomicDecS32(&g_cRTMpUsers) == 0)
306
 
        {
307
 
 
308
 
            PRTMPNOTIFYREG pHead;
309
 
            RTSPINLOCKTMP Tmp;
310
 
 
311
 
            rtR0MpNotificationNativeTerm();
312
 
 
313
 
            /* pick up the list and the spinlock. */
314
 
            RTSpinlockAcquire(hSpinlock, &Tmp);
315
 
            ASMAtomicWriteSize(&g_hRTMpNotifySpinLock, NIL_RTSPINLOCK);
316
 
            pHead = g_pRTMpCallbackHead;
317
 
            g_pRTMpCallbackHead = NULL;
318
 
            ASMAtomicIncU32(&g_iRTMpGeneration);
319
 
            RTSpinlockRelease(hSpinlock, &Tmp);
320
 
 
321
 
            /* free the list. */
322
 
            while (pHead)
323
 
            {
324
 
                PRTMPNOTIFYREG pFree = pHead;
325
 
                pHead = pHead->pNext;
326
 
 
327
 
                pFree->pNext = NULL;
328
 
                pFree->pfnCallback = NULL;
329
 
                RTMemFree(pFree);
330
 
            }
331
 
 
332
 
            RTSpinlockDestroy(hSpinlock);
333
 
        }
 
317
        PRTMPNOTIFYREG pFree = pHead;
 
318
        pHead = pHead->pNext;
 
319
 
 
320
        pFree->pNext = NULL;
 
321
        pFree->pfnCallback = NULL;
 
322
        RTMemFree(pFree);
334
323
    }
 
324
 
 
325
    RTSpinlockDestroy(hSpinlock);
335
326
}
336
327
 
337