Example #1
0
/*********************************************************************************************************
** 函数名称: archSpinInit
** 功能描述: 初始化一个 spinlock
** 输 入  : psl        spinlock 指针
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
VOID  archSpinInit (spinlock_t  *psl)
{
    psl->SL_sltData   = 0;                                              /*  0: 未锁定状态  1: 锁定状态  */
    psl->SL_pcpuOwner = LW_NULL;
    psl->SL_ulCounter = 0ul;                                            /*  重入锁计数                  */
    KN_SMP_WMB();
}
Example #2
0
/*********************************************************************************************************
** 函数名称: __smpProcCallfunc
** 功能描述: 处理核间中断调用函数
** 输 入  : pcpuCur       当前 CPU
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static VOID  __smpProcCallfunc (PLW_CLASS_CPU  pcpuCur)
{
#define LW_KERNEL_OWN_CPU()     (PLW_CLASS_CPU)(_K_klKernel.KERN_pvCpuOwner)

    UINT            i, uiCnt;
    PLW_IPI_MSG     pipim;
    PLW_LIST_RING   pringTemp;
    PLW_LIST_RING   pringDelete;
    VOIDFUNCPTR     pfuncAsync;
    PVOID           pvAsync;
    
    LW_SPIN_LOCK_IGNIRQ(&pcpuCur->CPU_slIpi);                           /*  锁定 CPU                    */
    
    pringTemp = pcpuCur->CPU_pringMsg;
    uiCnt     = pcpuCur->CPU_uiMsgCnt;
    
    for (i = 0; i < uiCnt; i++) {
        _BugHandle((!pcpuCur->CPU_pringMsg), LW_TRUE, "ipi call func error!\r\n");
        
        pipim = _LIST_ENTRY(pringTemp, LW_IPI_MSG, IPIM_ringManage);
        if ((LW_KERNEL_OWN_CPU() == pcpuCur) &&
            (pipim->IPIM_iOption & IPIM_OPT_NOKERN)) {                  /*  此函数不能再内核锁定状态执行*/
            pringTemp = _list_ring_get_next(pringTemp);
            continue;
        }
        
        pringDelete = pringTemp;
        pringTemp   = _list_ring_get_next(pringTemp);
        _List_Ring_Del(pringDelete, &pcpuCur->CPU_pringMsg);            /*  删除一个节点                */
        pcpuCur->CPU_uiMsgCnt--;
        
        if (pipim->IPIM_pfuncCall) {
            pipim->IPIM_iRet = pipim->IPIM_pfuncCall(pipim->IPIM_pvArg);/*  执行同步调用                */
        }
        
        pfuncAsync = pipim->IPIM_pfuncAsyncCall;
        pvAsync    = pipim->IPIM_pvAsyncArg;
        
        KN_SMP_MB();
        pipim->IPIM_iWait = 0;                                          /*  调用结束                    */
        KN_SMP_WMB();
        LW_SPINLOCK_NOTIFY();
        
        if (pfuncAsync) {
            pfuncAsync(pvAsync);                                        /*  执行异步调用                */
        }
    }
    
    KN_SMP_MB();
    if (pcpuCur->CPU_pringMsg == LW_NULL) {
        LW_CPU_CLR_IPI_PEND2(pcpuCur, LW_IPI_CALL_MSK);                 /*  清除                        */
    }
    
    LW_SPIN_UNLOCK_IGNIRQ(&pcpuCur->CPU_slIpi);                         /*  解锁 CPU                    */
    
    LW_SPINLOCK_NOTIFY();
}
Example #3
0
/*********************************************************************************************************
** 函数名称: _SmpCallIpiAllOther
** 功能描述: 发送一个自定义核间中断给其他所有 CPU 
             关中断情况下被调用, 如果需要等待, 则必须保证其他 CPU 已经运行.
** 输 入  : pipim         核间中断参数
** 输 出  : NONE (无法确定返回值)
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static VOID  _SmpCallIpiAllOther (PLW_IPI_MSG  pipim)
{
    ULONG   i;
    ULONG   ulCPUId;
    INT     iWaitSave = pipim->IPIM_iWait;
    
    ulCPUId = LW_CPU_GET_CUR_ID();
    
    KN_SMP_WMB();
    for (i = 0; i < LW_NCPUS; i++) {
        if (ulCPUId != i) {
            _SmpCallIpi(i, pipim);
            
            KN_SMP_MB();
            pipim->IPIM_iWait = iWaitSave;
            KN_SMP_WMB();
        }
    }
}
Example #4
0
/*********************************************************************************************************
** 函数名称: _SmpSendIpiAllOther
** 功能描述: 发送一个除自定义以外的核间中断给所有其他 CPU 
             关中断情况下被调用, 如果需要等待, 则必须保证其他 CPU 已经运行.
** 输 入  : ulIPIVec      核间中断类型 (除自定义类型中断以外)
**           iWait         是否等待处理结束 (LW_IPI_SCHED 绝不允许等待, 否则会死锁)
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
VOID  _SmpSendIpiAllOther (ULONG  ulIPIVec, INT  iWait)
{
    ULONG   i;
    ULONG   ulCPUId;
    
    ulCPUId = LW_CPU_GET_CUR_ID();
    
    KN_SMP_WMB();
    for (i = 0; i < LW_NCPUS; i++) {
        if (ulCPUId != i) {
            _SmpSendIpi(i, ulIPIVec, iWait);
        }
    }
}
Example #5
0
/*********************************************************************************************************
** 函数名称: archSpinUnlock
** 功能描述: spinlock 解锁
** 输 入  : psl        spinlock 指针
** 输 出  : 0: 没有获取
**           1: 正常解锁
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
INT  archSpinUnlock (spinlock_t  *psl)
{
    if (psl->SL_pcpuOwner != LW_CPU_GET_CUR()) {
        return  (0);                                                    /*  没有权利释放                */
    }
    
    if (psl->SL_ulCounter) {
        psl->SL_ulCounter--;                                            /*  减少重复调用次数            */
        return  (1);
    }

    psl->SL_pcpuOwner = LW_NULL;                                        /*  没有 CPU 获取               */
    KN_SMP_WMB();
    
    armSpinUnlock(&psl->SL_sltData);                                    /*  解锁                        */
    
    return  (1);
}
Example #6
0
/*********************************************************************************************************
** 函数名称: API_InterEnter
** 功能描述: 内核中断入口函数 (在关中断的情况下被调用)
** 输 入  : 
** 输 出  : 中断层数
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API
ULONG    API_InterEnter (VOID)
{
    PLW_CLASS_CPU  pcpu;
    
    pcpu = LW_CPU_GET_CUR();
    if (pcpu->CPU_ulInterNesting != LW_CFG_MAX_INTER_SRC) {
        pcpu->CPU_ulInterNesting++;
    }
    
    KN_SMP_WMB();                                                       /*  等待以上操作完成            */

#if LW_CFG_CPU_FPU_EN > 0
    if (LW_KERN_FPU_EN_GET()) {                                         /*  中断状态允许使用浮点运算    */
        __fpuInterEnter(pcpu);
    }
#endif                                                                  /*  LW_CFG_CPU_FPU_EN > 0       */

    return  (pcpu->CPU_ulInterNesting);
}
Example #7
0
/*********************************************************************************************************
** 函数名称: API_InterExit
** 功能描述: 内核中断出口函数 (在关中断的情况下被调用)
** 输 入  : NONE
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API
VOID    API_InterExit (VOID)
{
    PLW_CLASS_CPU  pcpu;
    
    pcpu = LW_CPU_GET_CUR();
    
#if LW_CFG_INTER_INFO > 0
    if (pcpu->CPU_ulInterNestingMax < pcpu->CPU_ulInterNesting) {
        pcpu->CPU_ulInterNestingMax = pcpu->CPU_ulInterNesting;
    }
#endif                                                                  /*  LW_CFG_INTER_INFO > 0       */

    if (pcpu->CPU_ulInterNesting) {                                     /*  系统中断嵌套层数--          */
        pcpu->CPU_ulInterNesting--;
    }
    
    KN_SMP_WMB();                                                       /*  等待以上操作完成            */
    
    if (pcpu->CPU_ulInterNesting) {                                     /*  查看系统是否在中断嵌套中    */
#if LW_CFG_CPU_FPU_EN > 0                                               /*  恢复上一等级中断 FPU CTX    */
        if (LW_KERN_FPU_EN_GET()) {
            __fpuInterExit(pcpu);
        }
#endif                                                                  /*  LW_CFG_CPU_FPU_EN > 0       */
        return;
    }
    
    __KERNEL_SCHED_INT(pcpu);                                           /*  中断中的调度                */
    
#if LW_CFG_CPU_FPU_EN > 0
    if (LW_KERN_FPU_EN_GET()) {
        __fpuInterExit(pcpu);
    }
#endif                                                                  /*  LW_CFG_CPU_FPU_EN > 0       */
}
Example #8
0
/*********************************************************************************************************
** 函数名称: _SmpSpinInit
** 功能描述: 自旋锁初始化
** 输 入  : psl           自旋锁
** 输 出  : NONE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
VOID  _SmpSpinInit (spinlock_t *psl)
{
    __ARCH_SPIN_INIT(psl);
    KN_SMP_WMB();
}