SylixOS中的线程【13】--- 线程安全模式

概念

为防止某些关键过程操作线程被删除或重启,SylixOS提供线程安全模式相关接口。线程进入安全模式后, 任何对本线程的删除或重启操作都会推迟到线程退出安全模式时进行。

接口

/*********************************************************************************************************
** 函数名称: API_ThreadSafe
** 功能描述: 线程进入安全模式(不得在中断中调用)
** 输 入  : 
** 输 出  : 
*********************************************************************************************************/
ULONG  API_ThreadSafe (VOID)
/*********************************************************************************************************
** 函数名称: API_ThreadUnsafe
** 功能描述: 线程退出安全模式 (不得在中断中调用)
** 输 入  : 无
** 输 出  : 
*********************************************************************************************************/
ULONG  API_ThreadUnsafe (VOID)
/*********************************************************************************************************
** 函数名称: API_ThreadIsSafe
** 功能描述: 检测目标线程是否处于安全模式.
** 输 入  : ulId         线程句柄
** 输 出  : LW_TRUE 线程处于安全模式,LW_FALSE错误或非安全模式
*********************************************************************************************************/
BOOL    API_ThreadIsSafe (LW_OBJECT_HANDLE    ulId)

示例

/*********************************************************************************************************
** 函数名称: _TyWrite
** 功能描述: 向终端写入数据
** 输 入  : 
**           ptyDev             TY 设备
**           pcBuffer,          需要写入终端的数据
**           stNBytes           需要写入的数据大小
** 输 出  : 实际写入的字节数, 小于 1 表示错误
** 全局变量: 
** 调用模块: 
** 注  意  : 当任务在获取写同步信号量后获取互斥信号量前被删除, 则 tty 会丢失写同步, 所以这里提前进入安全
             模式.
*********************************************************************************************************/
ssize_t  _TyWrite (TY_DEV_ID  ptyDev, 
                   PCHAR      pcBuffer, 
                   size_t     stNBytes)
{
             INTREG     iregInterLevel;
             
    REGISTER INT        iBytesput;
    REGISTER ssize_t    sstNbStart = stNBytes;
    
    REGISTER ULONG      ulError;
    
    if (pcBuffer == LW_NULL) {
        _ErrorHandle(EINVAL);
        return  (PX_ERROR);
    }
    
    if (stNBytes == 0) {
        return  (0);
    }
    
    LW_THREAD_SAFE();                                                   /*  任务提前进入安全状态        */
    
    while (stNBytes > 0) {
        ulError = API_SemaphoreBPend(ptyDev->TYDEV_hWrtSyncSemB, ptyDev->TYDEV_ulWTimeout);
        if (ulError) {
            LW_THREAD_UNSAFE();
            _ErrorHandle(ERROR_IO_DEVICE_TIMEOUT);                      /*   超时                       */
            return  (sstNbStart - stNBytes);
        }
        
        TYDEV_LOCK(ptyDev, LW_THREAD_UNSAFE(); return (PX_ERROR));      /*  等待设备使用权              */
        
        if (ptyDev->TYDEV_iAbortFlag & OPT_WABORT) {                    /*  is abort?                   */
            ptyDev->TYDEV_iAbortFlag &= ~OPT_WABORT;                    /*  清除 abort                  */
            TYDEV_UNLOCK(ptyDev);                                       /*  释放设备使用权              */
            LW_THREAD_UNSAFE();
            _ErrorHandle(ERROR_IO_ABORT);                               /*  abort                       */
            return  (sstNbStart - stNBytes);
        }
        
        if (ptyDev->TYDEV_tydevwrstat.TYDEVWRSTAT_bCanceled) {          /*  检查是否被禁止输出了        */
            ptyDev->TYDEV_tydevwrstat.TYDEVWRSTAT_bCanceled = LW_FALSE; /*  清除 canceled               */
            TYDEV_UNLOCK(ptyDev);                                       /*  释放设备使用权              */
            LW_THREAD_UNSAFE();
            _ErrorHandle(ERROR_IO_CANCELLED);
            return  (sstNbStart - stNBytes);
        }
        
        LW_SPIN_LOCK_QUICK(&ptyDev->TYDEV_slLock, &iregInterLevel);     /*  锁定 spinlock 并关闭中断    */
        iBytesput = rngBufPut(ptyDev->TYDEV_vxringidWrBuf, 
                              pcBuffer, 
                              (INT)stNBytes);                           /*  将数据写入缓冲区            */
        LW_SPIN_UNLOCK_QUICK(&ptyDev->TYDEV_slLock, iregInterLevel);    /*  解锁 spinlock 打开中断      */
        
        _TyTxStartup(ptyDev);                                           /*  启动设备发送                */
        
        stNBytes -= (size_t)iBytesput;                                  /*  剩余需要发送的数据          */
        pcBuffer += iBytesput;                                          /*  新的缓冲区起始地址          */
    
        LW_SPIN_LOCK_QUICK(&ptyDev->TYDEV_slLock, &iregInterLevel);     /*  锁定 spinlock 并关闭中断    */
        if (rngFreeBytes(ptyDev->TYDEV_vxringidWrBuf) > 0) {
            LW_SPIN_UNLOCK_QUICK(&ptyDev->TYDEV_slLock, iregInterLevel);/*  解锁 spinlock 打开中断      */
            API_SemaphoreBPost(ptyDev->TYDEV_hWrtSyncSemB);             /*  缓冲区还有空间              */
        
        } else {
            LW_SPIN_UNLOCK_QUICK(&ptyDev->TYDEV_slLock, iregInterLevel);/*  解锁 spinlock 打开中断      */
        }
        
        TYDEV_UNLOCK(ptyDev);                                           /*  释放设备使用权              */
    }
    
    LW_THREAD_UNSAFE();                                                 /*  退出安全模式                */
    
    return  (sstNbStart);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ScilogyHunter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值