Exemplo n.º 1
0
LW_API  
ULONG  API_CpuDown (ULONG  ulCPUId)
{
    INTREG          iregInterLevel;
    PLW_CLASS_CPU   pcpu;

    if ((ulCPUId == 0) || (ulCPUId >= LW_NCPUS)) {
        _ErrorHandle(EINVAL);
        return  (EINVAL);
    }
    
    __KERNEL_ENTER();
    pcpu = LW_CPU_GET(ulCPUId);
    if (!LW_CPU_IS_ACTIVE(pcpu) || 
        (LW_CPU_GET_IPI_PEND2(pcpu) & LW_IPI_DOWN_MSK)) {
        __KERNEL_EXIT();
        return  (ERROR_NONE);
    }
    
    LW_SPIN_LOCK_QUICK(&pcpu->CPU_slIpi, &iregInterLevel);
    LW_CPU_ADD_IPI_PEND2(pcpu, LW_IPI_DOWN_MSK);
    LW_SPIN_UNLOCK_QUICK(&pcpu->CPU_slIpi, iregInterLevel);
    
    _ThreadOffAffinity(pcpu);                                           /*  关闭与此 CPU 有关的亲和度   */
    __KERNEL_EXIT();
    
    _SmpSendIpi(ulCPUId, LW_IPI_DOWN, 0, LW_FALSE);                     /*  使用核间中断通知 CPU 停止   */
    
    return  (ERROR_NONE);
}
Exemplo n.º 2
0
/*********************************************************************************************************
** 函数名称: _SchedTick
** 功能描述: 时间片处理 (tick 中断服务程序中被调用, 进入内核且关闭中断状态)
** 输 入  : NONE
** 输 出  : NONE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
VOID  _SchedTick (VOID)
{
    REGISTER PLW_CLASS_CPU  pcpu;
    REGISTER PLW_CLASS_TCB  ptcb;
    UINT8          ucPriority;
    INT            i;

#if LW_CFG_SMP_EN > 0
    for (i = 0; i < LW_NCPUS; i++) {
#else
    i = 0;
#endif                                                                  /*  LW_CFG_SMP_EN               */

        pcpu = LW_CPU_GET(i);
        if (LW_CPU_IS_ACTIVE(pcpu)) {                                   /*  CPU 必须激活                */
            ptcb = pcpu->CPU_ptcbTCBCur;
            if (ptcb->TCB_ucSchedPolicy == LW_OPTION_SCHED_RR) {        /*  round-robin 线程            */
                if (ptcb->TCB_usSchedCounter == 0) {                    /*  时间片已经耗尽              */
                    if (LW_CAND_ROT(pcpu) == LW_FALSE) {
                        if (_SchedSeekPriority(pcpu, &ucPriority) &&    /*  就绪未运行任务的最高优先级  */
                                LW_PRIO_IS_HIGH_OR_EQU(ucPriority,
                                                       ptcb->TCB_ucPriority)) {
                            LW_CAND_ROT(pcpu) = LW_TRUE;                /*  下次调度时检查轮转          */
                        }
                    }
                } else {
                    ptcb->TCB_usSchedCounter--;
                }
            }
        }

#if LW_CFG_SMP_EN > 0
    }
#endif                                                                  /*  LW_CFG_SMP_EN               */
}
Exemplo n.º 3
0
/*********************************************************************************************************
** 函数名称: _SmpUpdateIpi
** 功能描述: 产生一个 IPI
** 输 入  : pcpuCur   CPU 控制块
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
VOID  _SmpUpdateIpi (PLW_CLASS_CPU  pcpu)
{
    if (!LW_CPU_IS_ACTIVE(pcpu)) {                                      /*  CPU 必须被激活              */
        return;
    }

    archMpInt(pcpu->CPU_ulCPUId);
}
Exemplo n.º 4
0
/*********************************************************************************************************
** 函数名称: API_KernelTicksContext
** 功能描述: 处理系统时钟中断. (此函数必须在中断中被调用)
** 输 入  : 
** 输 出  : 
** 全局变量: 
** 调用模块: 
** 注  意  : vprocTickHook() 可能会激活新的任务, 会在中断退出时会尝试调度. 
             所以这里允许在 QUICK 操作中打开中断.

                                           API 函数
*********************************************************************************************************/
LW_API
VOID  API_KernelTicksContext (VOID)
{
             INTREG         iregInterLevel;
    REGISTER INT            i;
             PLW_CLASS_CPU  pcpu;
             PLW_CLASS_TCB  ptcb;
             
    LW_SPIN_KERN_LOCK_QUICK(&iregInterLevel);                           /*  锁定内核并关闭中断          */
    
#if LW_CFG_RTC_EN > 0
    __kernelTODUpdate();                                                /*  更新 TOD 时间               */
#endif                                                                  /*  LW_CFG_RTC_EN > 0           */
    __kernelTickUpdate();                                               /*  更新 TICK 时间              */
    
    KN_INT_ENABLE(iregInterLevel);                                      /*  允许其他中断进入            */
    
#if LW_CFG_SMP_EN > 0
    for (i = 0; i < LW_NCPUS; i++) {                                    /*  遍历所有的核                */
#else
    i = 0;
#endif                                                                  /*  LW_CFG_SMP_EN               */

        pcpu = LW_CPU_GET(i);
        if (LW_CPU_IS_ACTIVE(pcpu)) {                                   /*  CPU 必须被激活              */
            ptcb = pcpu->CPU_ptcbTCBCur;
            ptcb->TCB_ulCPUTicks++;
            if (pcpu->CPU_iKernelCounter) {
                ptcb->TCB_ulCPUKernelTicks++;
            }
            __LW_TICK_CPUUSAGE_UPDATE(ptcb, pcpu);                      /*  更新所有 CPU 利用率         */
#if LW_CFG_MODULELOADER_EN > 0
            vprocTickHook(ptcb, pcpu);                                  /*  测算进程执行时间            */
#endif
        }
        
#if LW_CFG_SMP_EN > 0
    }
#endif                                                                  /*  LW_CFG_SMP_EN               */
    
    iregInterLevel = KN_INT_DISABLE();                                  /*  关闭中断                    */
    
    _SchedTick();                                                       /*  处理所有 CPU 线程的时间片   */
    
    LW_SPIN_KERN_UNLOCK_QUICK(iregInterLevel);                          /*  退出内核并打开中断          */
}
Exemplo n.º 5
0
/*********************************************************************************************************
** 函数名称: API_CpuIsUp
** 功能描述: 指定 CPU 是否启动.
** 输 入  : ulCPUId       CPU ID
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
BOOL  API_CpuIsUp (ULONG  ulCPUId)
{
    PLW_CLASS_CPU   pcpu;
    
    if (ulCPUId >= LW_NCPUS) {
        _ErrorHandle(EINVAL);
        return  (LW_FALSE);
    }
    
    KN_SMP_MB();
    pcpu = LW_CPU_GET(ulCPUId);
    if (LW_CPU_IS_ACTIVE(pcpu)) {
        return  (LW_TRUE);
    
    } else {
        return  (LW_FALSE);
    }
}
Exemplo n.º 6
0
/*********************************************************************************************************
** 函数名称: _SmpSendIpi
** 功能描述: 发送一个除自定义以外的核间中断给指定的 CPU 
             关中断情况下被调用, 如果需要等待, 则必须保证其他 CPU 已经运行.
** 输 入  : ulCPUId       CPU ID
**           ulIPIVec      核间中断类型 (除自定义类型中断以外)
**           iWait         是否等待处理结束 (LW_IPI_SCHED 绝不允许等待, 否则会死锁)
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
VOID  _SmpSendIpi (ULONG  ulCPUId, ULONG  ulIPIVec, INT  iWait)
{
    PLW_CLASS_CPU   pcpuDst = LW_CPU_GET(ulCPUId);
    ULONG           ulMask  = (ULONG)(1 << ulIPIVec);
    
    if (!LW_CPU_IS_ACTIVE(pcpuDst)) {                                   /*  CPU 必须被激活              */
        return;
    }
    
    LW_SPIN_LOCK_IGNIRQ(&pcpuDst->CPU_slIpi);                           /*  锁定目标 CPU                */
    LW_CPU_ADD_IPI_PEND(ulCPUId, ulMask);                               /*  添加 PEND 位                */
    LW_SPIN_UNLOCK_IGNIRQ(&pcpuDst->CPU_slIpi);                         /*  解锁目标 CPU                */
    
    archMpInt(ulCPUId);
    
    if (iWait && (ulIPIVec != LW_IPI_SCHED)) {
        while (LW_CPU_GET_IPI_PEND(ulCPUId) & ulMask) {                 /*  等待结束                    */
            LW_SPINLOCK_DELAY();
        }
    }
}
Exemplo n.º 7
0
/*********************************************************************************************************
** 函数名称: _SmpCallIpi
** 功能描述: 发送一个自定义核间中断给指定的 CPU
             关中断情况下被调用, 如果需要等待, 则必须保证其他 CPU 已经运行.
** 输 入  : ulCPUId       CPU ID
**           pipim         核间中断参数
** 输 出  : 调用返回值
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static INT  _SmpCallIpi (ULONG  ulCPUId, PLW_IPI_MSG  pipim)
{
    PLW_CLASS_CPU   pcpuDst = LW_CPU_GET(ulCPUId);
    
    if (!LW_CPU_IS_ACTIVE(pcpuDst)) {                                   /*  CPU 必须被激活              */
        return  (ERROR_NONE);
    }
    
    LW_SPIN_LOCK_IGNIRQ(&pcpuDst->CPU_slIpi);                           /*  锁定目标 CPU                */
    _List_Ring_Add_Last(&pipim->IPIM_ringManage, &pcpuDst->CPU_pringMsg);
    pcpuDst->CPU_uiMsgCnt++;
    LW_CPU_ADD_IPI_PEND(ulCPUId, LW_IPI_CALL_MSK);
    LW_SPIN_UNLOCK_IGNIRQ(&pcpuDst->CPU_slIpi);                         /*  解锁目标 CPU                */
    
    archMpInt(ulCPUId);
    
    while (pipim->IPIM_iWait) {                                         /*  等待结束                    */
        LW_SPINLOCK_DELAY();
    }
    
    return  (pipim->IPIM_iRet);
}
Exemplo n.º 8
0
/*********************************************************************************************************
** 函数名称: API_CpuUp
** 功能描述: 开启一个 CPU. (非 0 号 CPU)
** 输 入  : ulCPUId       CPU ID
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
ULONG  API_CpuUp (ULONG  ulCPUId)
{
    INTREG          iregInterLevel;
    PLW_CLASS_CPU   pcpu;

    if ((ulCPUId == 0) || (ulCPUId >= LW_NCPUS)) {
        _ErrorHandle(EINVAL);
        return  (EINVAL);
    }
    
    KN_SMP_MB();
    pcpu = LW_CPU_GET(ulCPUId);
    if (LW_CPU_IS_ACTIVE(pcpu) || 
        (LW_CPU_GET_IPI_PEND2(pcpu) & LW_IPI_DOWN_MSK)) {
        return  (ERROR_NONE);
    }
    
    iregInterLevel = KN_INT_DISABLE();
    bspCpuUp(ulCPUId);
    KN_INT_ENABLE(iregInterLevel);
    
    return  (ERROR_NONE);
}