Exemple #1
0
/*
 *  ======== notifySpinLock ========
 */
UInt Core_notifySpinLock()
{
    UInt key;

    key = Hwi_disable();

    while (1) {
        if (!Core_module->notifyLock) {
            Core_module->notifyLock = TRUE;
            break;
        }
        else {
            /* Re-enable interrupts and release inter-core lock */
            Hwi_restore(key);
            /* Wait for lock to be released */
            while (Core_module->notifyLock);
            key = Hwi_disable();
        }
    }

    /* Release inter-core lock */
    Core_unlock();

    return (key);
}
Exemple #2
0
/*
 *  ======== SysMin_abort ========
 */
Void SysMin_abort(String str)
{
    Char ch;    
    
    if (SysMin_bufSize != 0) {
        if (str != NULL) {
            while ((ch = *str++) != '\0') {
                SysMin_putch(ch);
            }
        }

        /* Only flush if configured to do so */
        if (SysMin_flushAtExit) {
            SysMin_flush();
        }
    }
    
    /* 
     *  System_abort() in xdc/runtime/System.c enters the System gate
     *  before aborting, but does not leave the gate. Aforementioned 
     *  System gate maps to the Inter-core gate entered by the Hwi lock. 
     *  Since Hwi lock is never released, the other core's dispacther
     *  may spin forever, waiting to acquire the Hwi lock.
     *
     *  We Unlock Hwi before returning so all locks are released before 
     *  exiting.
     */
     Core_unlock();
}
Exemple #3
0
/*
 *  ======== Core_atexit ========
 */
Void Core_atexit(Int arg)
{
    if ((Core_module->exitFlag == TRUE) || (Core_syncExits == FALSE)) {
        Core_module->exitFlag = FALSE;
        Task_unlockSched();
        Swi_unlockSched();
        Core_unlock();
        return;
    }

    Core_module->exitFlag = TRUE;
    Task_unlockSched();
    Swi_unlockSched();
    Core_unlock();

    /* interrupt the other core */
    Core_interruptCore(Core_getId() ^ 1);

    while (Core_module->exitFlag);
}
Exemple #4
0
/*
 *  ======== Core_atexit ========
 */
Void Core_atexit(Int arg)
{
    UInt key;
    UInt coreId = Core_getId();

    Task_unlockSched();
    Swi_unlockSched();
    Core_unlock();

    /* force other cores to exit */
    key = Core_notifySpinLock();
    Core_notify(&Core_exit, (UArg)coreId, (Core_CPUMASK ^ (0x1 << coreId)));
    Core_notifySpinUnlock(key);
}
Exemple #5
0
/*
 *  ======== Core_exit ========
 */
Void Core_exit(UArg arg)
{
    Task_unlockSched();
    Swi_unlockSched();
    Core_unlock();

    /* Signal operation complete */
    Core_module->syncCores[arg][Core_getId()] = TRUE;

    /*
     * Call _exit() instead of abort. abort() internally
     * calls raise() which will invoke ReentSupport_getReent()
     * from a Hwi context and cause an assertion failure.
     */
    _exit(0);
}
Exemple #6
0
/*
 *  ======== Core_hwiFunc ========
 */
Void Core_hwiFunc(UArg arg)
{
    UInt coreId = Core_getId();

    Core_module->schedulerInts[coreId] += 1;

    if (Core_module->exitFlag == TRUE) {
        Core_module->exitFlag = FALSE;
        Task_unlockSched();
        Swi_unlockSched();
        Core_unlock();
        abort();
    }

    if (coreId == 0) {
        Hwi_flushVnvic();
    }
}
Exemple #7
0
/*
 *  ======== SysMin_exit ========
 */
Void SysMin_exit(Int stat)
{
    /*
     *  System_rtsExit() in xdc/runtime/System.c enters the System gate
     *  before exiting, but does not leave the gate. The BASEPRI
     *  register on Arm M3 is therefore not restored to 0 (disabled state).
     *  When SysMin_flush() enters Hwi gate, the key returned by
     *  Hwi_disable() is incorrect (Its equal to Hwi disable priority
     *  instead of 0). This prevents the Hwi_restore() function, 
     *  called when SysMin_flush() exits, from freeing the Hwi lock.
     *  Since Hwi lock is never released, the other core's dispacther
     *  may spin forever, waiting to acquire the Hwi lock.
     *
     *  We Unlock Hwi before returning so all locks are released before 
     *  exiting.
     */
    if ((SysMin_flushAtExit) && (SysMin_bufSize != 0)) {
        SysMin_flush();
        Core_unlock();
    }
}