4 rt-thread posix 条件变量源码分析

posix 条件变量源码分析

初始化条件变量

int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
{
    zs_err_t result;
    char cond_name[ZS_NAME_MAX];
    static zs_uint16_t cond_num = 0;
    /* parameter check */
    if (cond == ZS_NULL)
        return EINVAL;
    if ((attr != ZS_NULL) && (*attr != PTHREAD_PROCESS_PRIVATE))            ///> (1)
        return EINVAL;
    snprintf(cond_name, sizeof(cond_name), "cond%02d", cond_num++);
    if (attr == ZS_NULL)        /* use default value */
        cond->attr = PTHREAD_PROCESS_PRIVATE;                               ///> (2)
    else 
        cond->attr = *attr;
    result = zs_sem_init(&cond->sem, cond_name, 0, ZS_IPC_FLAG_FIFO);       ///> (3)
    if (result != ZS_EOK)
        return EINVAL;
    /* detach the object from system object container */
    zs_object_detach(&(cond->sem.parent.parent));                           ///> (4)
    cond->sem.parent.parent.type = ZS_Object_Class_Semaphore;               ///> (5)
    return 0;
}

代码段(1):判断属性为空;不是同一个进程创建的线程,不能处理该互斥锁。
代码段(2):设置默认的属性值。
代码段(3):设置指定的属性值。
代码段(4):将此条件变量在object类链表上分离。
代码段(5):添加此条件变量 在object 信号类的链表中。

销毁条件变量

int pthread_cond_destroy(pthread_cond_t *cond)
{
    zs_err_t result;
    if (cond == ZS_NULL)                                            ///>(1) 
        return EINVAL;                                       
    if (cond->attr == -1)                                           ///>(2)
        return 0; /* which is not initialized */
    result = zs_sem_trytake(&(cond->sem));                          ///>(3)
    if (result != ZS_EOK)
        return EBUSY;
    /* clean condition */   
    memset(cond, 0, sizeof(pthread_cond_t));                        ///>(4)
    cond->attr = -1;                                                ///>(5)
    return 0;
}

代码段(1):没有条件变量对象,返回。
代码段(2):条件变量属性没有初始化,返回。
代码段(3):非阻塞的方式获取信号量,result 不等于 0,忙。等于 0,空闲。
代码段(4):将条件变量对象的信息清0。
代码段(5):设置条件变量的属性为未初始化的状态。

阻塞方式获取条件变量

zs_err_t _pthread_cond_timedwait(pthread_cond_t  *cond, pthread_mutex_t *mutex, zs_int32_t timeout)
{
    zs_err_t result;
    if (!cond || !mutex)                                                            ///> (2)
        return -ZS_ERROR;
    /* check whether initialized */
    if (cond->attr == -1)                                                           ///> (3)
        pthread_cond_init(cond, ZS_NULL);
    /* The mutex was not owned by the current thread at the time of the call. */
    if (mutex->lock.owner != zs_thread_self())                                      ///> (4)
        return -ZS_ERROR;
    /* unlock a mutex failed */
    if (pthread_mutex_unlock(mutex) != 0)                                           ///> (5)
        return -ZS_ERROR;
    result = zs_sem_take(&(cond->sem), timeout);                                    ///> (6)
    /* lock mutex again */
    pthread_mutex_lock(mutex);                                                      ///> (7)
    return result;
}

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
    zs_err_t result;
    result = _pthread_cond_timedwait(cond, mutex, ZS_WAITING_FOREVER);              ///> (1)
    if (result == ZS_EOK)
        return 0;
    return EINVAL;
}

代码段(1):阻塞方式等待条件变量。
代码段(2):条件对象为空;互斥锁为空。退出。
代码段(3):条件对象没有初始化。退出。
代码段(4):调用时互斥锁不属于当前线程。
代码段(5):互斥锁解锁。失败,退出。
代码段(6):阻塞方式调用互斥锁。
代码段(7):互斥锁上锁。

指定阻塞时间获取时间获取条件变量

int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
{
    int timeout;
    zs_err_t result;
    timeout = clock_time_to_tick(abstime);                                 ///> (1)
    result = _pthread_cond_timedwait(cond, mutex, timeout);                ///> (2)
    if (result == ZS_EOK)                                                  ///> (3)
        return 0;
    if (result == -ZS_ETIMEOUT)                                            ///> (4)
        return ETIMEDOUT;
    return EINVAL;
}

代码段(1):将用户设置的时间转换为rtc时间。
代码段(2):非阻塞方式创建定时时间。
代码段(3):条件变量已释放。
代码段(4):指定时间内条件变量未释放。

发送满足条件信号量

int pthread_cond_signal(pthread_cond_t *cond)
{
    zs_err_t result;
    if (cond == ZS_NULL)
        return EINVAL;
    if (cond->attr == -1)                                       
        pthread_cond_init(cond, ZS_NULL);                       ///> (1)
    result = zs_sem_release(&(cond->sem));                      ///> (2)
    if (result == ZS_EOK)
        return 0;
    return 0;
}

代码段(1):条件变量对象属性未设置时,初始化条件变量对象。
代码段(2):释放信号量。

广播

int pthread_cond_broadcast(pthread_cond_t *cond)
{
    zs_err_t result;
    if (cond == ZS_NULL)
        return EINVAL;
    if (cond->attr == -1)
        pthread_cond_init(cond, ZS_NULL);
    zs_enter_critical();
    while (1)
    {
        /* try to take condition semaphore */
        result = zs_sem_trytake(&(cond->sem));                     ///> (1)
        if (result == -ZS_ETIMEOUT)                                
        {
            /* it's timeout, release this semaphore */
            zs_sem_release(&(cond->sem));                          ///> (2)
        }
        else if (result == ZS_EOK)
        {
            /* has taken this semaphore, release it */
            zs_sem_release(&(cond->sem));                          ///> (3)
            break;
        }
        else
        {
            zs_exit_critical();                                    ///> (4)
            return EINVAL;
        }
    }
    zs_exit_critical();
    return 0;
}

代码段(1):非阻塞方式获取条件变量。
代码段(2):时间溢出,释放信号量。
代码段(3):获取到条件变量,释放信号量。继续获取条件变量。
代码段(4):时间没有溢出,没有获取到信号,退出临界区。退出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值