更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
pthread_cond.c 文件参考

浏览源代码.

函数

STATIC INLINE INT32 CondInitCheck (const pthread_cond_t *cond)
 
int pthread_condattr_getpshared (const pthread_condattr_t *attr, int *shared)
 获取条件变量的范围,目前只支持获取PTHREAD_PROCESS_PRIVATE条件变量属性
更多...
 
int pthread_condattr_setpshared (pthread_condattr_t *attr, int shared)
 设置条件变量的范围
更多...
 
int pthread_condattr_destroy (pthread_condattr_t *attr)
 销毁条件变量属性对象 更多...
 
int pthread_condattr_init (pthread_condattr_t *attr)
 初始化条件变量属性对象 更多...
 
int pthread_cond_destroy (pthread_cond_t *cond)
 销毁条件变量 更多...
 
int pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t *attr)
 pthread_cond_init 初始化条件变量 更多...
 
STATIC VOID PthreadCondValueModify (pthread_cond_t *cond)
 
int pthread_cond_broadcast (pthread_cond_t *cond)
 解除若干已被等待条件阻塞的线程 更多...
 
int pthread_cond_signal (pthread_cond_t *cond)
 解除被阻塞的线程/发送满足条件信号量 更多...
 
STATIC INT32 PthreadCondWaitSub (pthread_cond_t *cond, INT32 value, UINT32 ticks)
 
STATIC VOID PthreadCountSub (pthread_cond_t *cond)
 
STATIC INT32 ProcessReturnVal (pthread_cond_t *cond, INT32 val)
 
int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *absTime)
 pthread_cond_timedwait
等待条件 在指定的时间之前阻塞,函数会一直阻塞,直到该条件获得信号,或者最后一个参数所指定的时间已过为止。 更多...
 
int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
 阻塞方式获取条件变量,阻塞的线程可以通过 pthread_cond_signal()pthread_cond_broadcast() 唤醒 更多...
 

详细描述

条件变量属性

使用条件变量可以以原子方式阻塞线程,直到某个特定条件为真为止。条件变量始终与互斥锁一起使用。
使用条件变量,线程可以以原子方式阻塞,直到满足某个条件为止。对条件的测试是在互斥锁(互斥)的保护下进行的。
如果条件为假,线程通常会基于条件变量阻塞,并以原子方式释放等待条件变化的互斥锁。如果另一个线程更改了条件,
该线程可能会向相关的条件变量发出信号,从而使一个或多个等待的线程执行以下操作:
    唤醒
    再次获取互斥锁
    重新评估条件
在以下情况下,条件变量可用于在进程之间同步线程:
    线程是在可以写入的内存中分配的
    内存由协作进程共享
调度策略可确定唤醒阻塞线程的方式。对于缺省值 SCHED_OTHER,将按优先级顺序唤醒线程。

https://docs.oracle.com/cd/E19253-01/819-7051/sync-13528/index.html
https://docs.oracle.com/cd/E19253-01/819-7051/6n919hpai/index.html#sync-59145
 * 

在文件 pthread_cond.c 中定义.

函数说明

◆ CondInitCheck()

STATIC INLINE INT32 CondInitCheck ( const pthread_cond_t *  cond)

在文件 pthread_cond.c67 行定义.

68{
69 if ((cond->event.stEventList.pstPrev == NULL) &&
70 (cond->event.stEventList.pstNext == NULL)) {
71 return 1;
72 }
73 return 0;
74}
这是这个函数的调用关系图:

◆ ProcessReturnVal()

STATIC INT32 ProcessReturnVal ( pthread_cond_t *  cond,
INT32  val 
)

在文件 pthread_cond.c259 行定义.

260{
261 INT32 ret;
262 switch (val) {
263 /* 0: event does not occur */
264 case 0:
265 case BROADCAST_EVENT:
266 ret = ENOERR;
267 break;
268 case LOS_ERRNO_EVENT_READ_TIMEOUT:
269 PthreadCountSub(cond);
270 ret = ETIMEDOUT;
271 break;
272 default:
273 PthreadCountSub(cond);
274 ret = EINVAL;
275 break;
276 }
277 return ret;
278}
signed int INT32
Definition: los_typedef.h:60
STATIC VOID PthreadCountSub(pthread_cond_t *cond)
Definition: pthread_cond.c:250
函数调用图:
这是这个函数的调用关系图:

◆ pthread_cond_broadcast()

int pthread_cond_broadcast ( pthread_cond_t *  cond)

解除若干已被等待条件阻塞的线程

在文件 pthread_cond.c189 行定义.

190{
191 int ret = ENOERR;
192
193 if (cond == NULL) {
194 return EINVAL;
195 }
196
197 (VOID)pthread_mutex_lock(cond->mutex);
198 if (cond->count > 0) {
199 cond->count = 0;
200 (VOID)pthread_mutex_unlock(cond->mutex);
201
203
204 (VOID)LOS_EventWrite(&(cond->event), BROADCAST_EVENT);//写事件
205 return ret;
206 }
207 (VOID)pthread_mutex_unlock(cond->mutex);
208
209 return ret;
210}
LITE_OS_SEC_TEXT UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events)
写指定的事件类型
Definition: los_event.c:318
STATIC VOID PthreadCondValueModify(pthread_cond_t *cond)
Definition: pthread_cond.c:175
int pthread_mutex_lock(pthread_mutex_t *mutex)
互斥锁加锁操作
int pthread_mutex_unlock(pthread_mutex_t *mutex)
解锁互斥锁
函数调用图:

◆ pthread_cond_destroy()

int pthread_cond_destroy ( pthread_cond_t *  cond)

销毁条件变量

在文件 pthread_cond.c119 行定义.

120{
121 if (cond == NULL) {
122 return EINVAL;
123 }
124
125 if (CondInitCheck(cond)) {
126 return ENOERR;
127 }
128
129 if (LOS_EventDestroy(&cond->event) != LOS_OK) {
130 return EBUSY;
131 }
132 if (pthread_mutex_destroy(cond->mutex) != ENOERR) {
133 PRINT_ERR("%s mutex destroy fail!\n", __FUNCTION__);
134 return EINVAL;
135 }
136 free(cond->mutex);
137 cond->mutex = NULL;
138 return ENOERR;
139}
LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB)
销毁指定的事件控制块
Definition: los_event.c:334
void free(void *ptr)
释放ptr所指向的内存空间
Definition: malloc.c:66
STATIC INLINE INT32 CondInitCheck(const pthread_cond_t *cond)
Definition: pthread_cond.c:67
int pthread_mutex_destroy(pthread_mutex_t *mutex)
销毁互斥锁
函数调用图:

◆ pthread_cond_init()

int pthread_cond_init ( pthread_cond_t *  cond,
const pthread_condattr_t *  attr 
)

pthread_cond_init 初始化条件变量

参数
attr指向条件变量属性的指针,若为 NULL 则使用默认属性值
cond条件变量句柄,不能为 NULL
返回
参见

在文件 pthread_cond.c150 行定义.

151{
152 int ret = ENOERR;
153
154 if (cond == NULL) {
155 return EINVAL;
156 }
157 (VOID)attr;
158 (VOID)LOS_EventInit(&(cond->event));
159
160 cond->mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
161 if (cond->mutex == NULL) {
162 return ENOMEM;
163 }
164
165 (VOID)pthread_mutex_init(cond->mutex, NULL);
166
167 cond->value = 0;
168 (VOID)pthread_mutex_lock(cond->mutex);
169 cond->count = 0;
170 (VOID)pthread_mutex_unlock(cond->mutex);
171
172 return ret;
173}
LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB)
初始化一个事件控制块
Definition: los_event.c:95
void * malloc(size_t size)
动态分配内存块大小
Definition: malloc.c:81
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexAttr)
初始化互斥锁。 如果 mutexAttr 为 NULL,则使用默认属性。
函数调用图:
这是这个函数的调用关系图:

◆ pthread_cond_signal()

int pthread_cond_signal ( pthread_cond_t *  cond)

解除被阻塞的线程/发送满足条件信号量

在文件 pthread_cond.c212 行定义.

213{
214 int ret = ENOERR;
215
216 if (cond == NULL) {
217 return EINVAL;
218 }
219
220 (VOID)pthread_mutex_lock(cond->mutex);
221 if (cond->count > 0) {
222 cond->count--;
223 (VOID)pthread_mutex_unlock(cond->mutex);
225 (VOID)OsEventWriteOnce(&(cond->event), 0x01);//只写一次,也就是解除一个线程的阻塞
226
227 return ret;
228 }
229 (VOID)pthread_mutex_unlock(cond->mutex);
230
231 return ret;
232}
UINT32 OsEventWriteOnce(PEVENT_CB_S eventCB, UINT32 events)
只写一次事件
Definition: los_event.c:329
函数调用图:

◆ pthread_cond_timedwait()

int pthread_cond_timedwait ( pthread_cond_t *  cond,
pthread_mutex_t *  mutex,
const struct timespec *  absTime 
)

pthread_cond_timedwait
等待条件 在指定的时间之前阻塞,函数会一直阻塞,直到该条件获得信号,或者最后一个参数所指定的时间已过为止。

参数
absTime指定的等待时间,单位是操作系统时钟节拍(OS Tick)
cond条件变量句柄,不能为 NULL
mutex指向互斥锁控制块的指针,不能为 NULL
返回
此函数和 pthread_cond_wait() 函数唯一的差别在于,如果条件变量不可用,线程将被阻塞 abstime 时长, 超时后函数将直接返回 ETIMEDOUT 错误码,线程将会被唤醒进入就绪态。
参见

在文件 pthread_cond.c291 行定义.

293{
294 UINT32 absTicks;
295 INT32 ret;
296 INT32 oldValue;
297
299 if ((cond == NULL) || (mutex == NULL) || (absTime == NULL)) {
300 return EINVAL;
301 }
302
303 if (CondInitCheck(cond)) {
304 ret = pthread_cond_init(cond, NULL);
305 if (ret != ENOERR) {
306 return ret;
307 }
308 }
309 oldValue = cond->value;
310
311 (VOID)pthread_mutex_lock(cond->mutex);
312 cond->count++;
313 (VOID)pthread_mutex_unlock(cond->mutex);
314
315 if ((absTime->tv_sec == 0) && (absTime->tv_nsec == 0)) {
316 return ETIMEDOUT;
317 }
318
319 if (!ValidTimeSpec(absTime)) {
320 return EINVAL;
321 }
322
323 absTicks = OsTimeSpec2Tick(absTime);
324 if (pthread_mutex_unlock(mutex) != ENOERR) {
325 PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
326 }
327
328#ifndef LOSCFG_ARCH_CORTEX_M7
329 ret = PthreadCondWaitSub(cond, oldValue, absTicks);
330#else
331 ret = (INT32)LOS_EventRead(&(cond->event), 0x0f, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, absTicks);
332#endif
333 if (pthread_mutex_lock(mutex) != ENOERR) {
334 PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
335 }
336
337 ret = ProcessReturnVal(cond, ret);
339 return ret;
340}
LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout)
读取指定事件类型,超时时间为相对时间:单位为Tick
Definition: los_event.c:313
unsigned int UINT32
Definition: los_typedef.h:57
void pthread_testcancel(void)
Definition: pthread.c:750
STATIC INT32 PthreadCondWaitSub(pthread_cond_t *cond, INT32 value, UINT32 ticks)
Definition: pthread_cond.c:234
STATIC INT32 ProcessReturnVal(pthread_cond_t *cond, INT32 val)
Definition: pthread_cond.c:259
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
pthread_cond_init 初始化条件变量
Definition: pthread_cond.c:150
STATIC INLINE BOOL ValidTimeSpec(const struct timespec *tp)
Definition: time_posix.h:53
STATIC INLINE UINT32 OsTimeSpec2Tick(const struct timespec *tp)
Definition: time_posix.h:68
函数调用图:

◆ pthread_cond_wait()

int pthread_cond_wait ( pthread_cond_t *  cond,
pthread_mutex_t *  mutex 
)

阻塞方式获取条件变量,阻塞的线程可以通过 pthread_cond_signal()pthread_cond_broadcast() 唤醒

在文件 pthread_cond.c342 行定义.

343{
344 int ret;
345 int oldValue;
346
347 if ((cond == NULL) || (mutex == NULL)) {
348 return EINVAL;
349 }
350
351 if (CondInitCheck(cond)) {
352 ret = pthread_cond_init(cond, NULL);
353 if (ret != ENOERR) {
354 return ret;
355 }
356 }
357 oldValue = cond->value;
358
359 (VOID)pthread_mutex_lock(cond->mutex);
360 cond->count++;
361 (VOID)pthread_mutex_unlock(cond->mutex);
362
363 if (pthread_mutex_unlock(mutex) != ENOERR) {
364 PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
365 }
366
367#ifndef LOSCFG_ARCH_CORTEX_M7
368 ret = PthreadCondWaitSub(cond, oldValue, LOS_WAIT_FOREVER);
369#else
370 ret = (INT32)LOS_EventRead(&(cond->event), 0x0f, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);
371#endif
372 if (pthread_mutex_lock(mutex) != ENOERR) {
373 PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
374 }
375
376 switch (ret) {
377 /* 0: event does not occur */
378 case 0:
379 case BROADCAST_EVENT:
380 ret = ENOERR;
381 break;
382 default:
383 PthreadCountSub(cond);
384 ret = EINVAL;
385 break;
386 }
387
388 return ret;
389}
函数调用图:

◆ pthread_condattr_destroy()

int pthread_condattr_destroy ( pthread_condattr_t *  attr)

销毁条件变量属性对象

在文件 pthread_cond.c101 行定义.

102{
103 if (attr == NULL) {
104 return EINVAL;
105 }
106
107 return 0;
108}

◆ pthread_condattr_getpshared()

int pthread_condattr_getpshared ( const pthread_condattr_t *  attr,
int shared 
)

获取条件变量的范围,目前只支持获取PTHREAD_PROCESS_PRIVATE条件变量属性

在文件 pthread_cond.c76 行定义.

77{
78 if ((attr == NULL) || (shared == NULL)) {
79 return EINVAL;
80 }
81
82 *shared = PTHREAD_PROCESS_PRIVATE;// PTHREAD_PROCESS_PRIVATE,则仅有那些由同一个进程创建的线程才能够处理该互斥锁。
83
84 return 0;
85}

◆ pthread_condattr_init()

int pthread_condattr_init ( pthread_condattr_t *  attr)

初始化条件变量属性对象

在文件 pthread_cond.c110 行定义.

111{
112 if (attr == NULL) {
113 return EINVAL;
114 }
115
116 return 0;
117}

◆ pthread_condattr_setpshared()

int pthread_condattr_setpshared ( pthread_condattr_t *  attr,
int  shared 
)

设置条件变量的范围

如果 pshared 属性在共享内存中设置为 PTHREAD_PROCESS_SHARED,则其所创建的条件变量可以在多个进程中的线程之间共享。

在文件 pthread_cond.c87 行定义.

88{
89 (VOID)attr;
90 if ((shared != PTHREAD_PROCESS_PRIVATE) && (shared != PTHREAD_PROCESS_SHARED)) {
91 return EINVAL;
92 }
93///如果 pshared 属性在共享内存中设置为 PTHREAD_PROCESS_SHARED,则其所创建的条件变量可以在多个进程中的线程之间共享。
94 if (shared != PTHREAD_PROCESS_PRIVATE) {
95 return ENOSYS;
96 }
97
98 return 0;
99}

◆ PthreadCondValueModify()

STATIC VOID PthreadCondValueModify ( pthread_cond_t *  cond)

在文件 pthread_cond.c175 行定义.

176{
177 UINT32 flags = ((UINT32)cond->value & COND_FLAGS_MASK);
178 INT32 oldVal, newVal;
179
180 while (true) {
181 oldVal = cond->value;
182 newVal = (INT32)(((UINT32)(oldVal - COND_COUNTER_STEP) & COND_COUNTER_MASK) | flags);
183 if (LOS_AtomicCmpXchg32bits(&cond->value, newVal, oldVal) == 0) {
184 break;
185 }
186 }
187}
STATIC INLINE BOOL LOS_AtomicCmpXchg32bits(Atomic *v, INT32 val, INT32 oldVal)
Atomic exchange for 32-bit variable with compare. | 比较并交换32位原子数据,返回比较结果
Definition: los_atomic.h:890
函数调用图:
这是这个函数的调用关系图:

◆ PthreadCondWaitSub()

STATIC INT32 PthreadCondWaitSub ( pthread_cond_t *  cond,
INT32  value,
UINT32  ticks 
)

在文件 pthread_cond.c234 行定义.

235{
236 EventCond eventCond = { &cond->value, value, ~0x01U };
237 /*
238 * When the scheduling lock is held:
239 * (1) value is not equal to cond->value, clear the event message and
240 * do not block the current thread, because other threads is calling pthread_cond_broadcast or
241 * pthread_cond_signal to modify cond->value and wake up the current thread,
242 * and others threads will block on the scheduling lock until the current thread releases
243 * the scheduling lock.
244 * (2) value is equal to cond->value, block the current thread
245 * and wait to be awakened by other threads.
246 */
247 return (int)OsEventReadWithCond(&eventCond, &(cond->event), 0x0fU,
248 LOS_WAITMODE_OR | LOS_WAITMODE_CLR, ticks);
249}
UINT32 OsEventReadWithCond(const EventCond *cond, PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout)
有条件式读事件
Definition: los_event.c:371
INT32 value
Definition: los_event_pri.h:46
函数调用图:
这是这个函数的调用关系图:

◆ PthreadCountSub()

STATIC VOID PthreadCountSub ( pthread_cond_t *  cond)

在文件 pthread_cond.c250 行定义.

251{
252 (VOID)pthread_mutex_lock(cond->mutex);
253 if (cond->count > 0) {
254 cond->count--;
255 }
256 (VOID)pthread_mutex_unlock(cond->mutex);
257}
函数调用图:
这是这个函数的调用关系图: