1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
* Copyright (c) 2026-present Eclipse ThreadX contributors
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: MIT
**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** POSIX wrapper for THREADX */
/** */
/** */
/** */
/**************************************************************************/
/**************************************************************************/
/* Include necessary system files. */
#include "tx_api.h" /* Threadx API */
#include "pthread.h" /* Posix API */
#include "px_int.h" /* Posix helper functions */
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* pthread_cond_broadcast PORTABLE C */
/* 6.1.7 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* These functions shall unblock all threads currently blocked on a */
/* specified condition variable cond. */
/* If more than one thread is blocked on a condition variable, */
/* the scheduling policy shall determine the order in which threads are*/
/* unblocked. When each thread unblocked as a result of this function */
/* call returns from its call to pthread_cond_wait or */
/* pthread_cond_timedwait, the thread shall own the mutex with which it*/
/* called pthread_cond_wait or pthread_cond_timedwait. The thread(s) */
/* that are unblocked shall contend for the mutex according to the */
/* scheduling policy (if applicable), and as if each had called */
/* pthread_mutex_lock.The pthread_cond_broadcast function may be called*/
/* by a thread whether or not it currently owns the mutex that threads */
/* calling pthread_cond_wait or pthread_cond_timedwait have associated */
/* with the condition variable during their waits; however, */
/* if predictable scheduling behavior is required, then that mutex */
/* shall be locked by the thread calling pthread_cond_broadcast. */
/* The pthread_cond_broadcast function shall have no effect if there */
/* are no threads currently blocked on cond. */
/* */
/* INPUT */
/* */
/* cond condition variable */
/* */
/* OUTPUT */
/* */
/* Ok if successful */
/* Error in case of any errors */
/* */
/* CALLS */
/* */
/* tx_semaphore_prioritize line up pthreads waiting at semaphore*/
/* tx_thread_identify to check which pthread? */
/* tx_thread_preemption_change to disable thread preemption */
/* tx_semaphore_put ThreadX semaphore put service */
/* tx_thread_preemption_change to enable thread preemption */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/**************************************************************************/
INT pthread_cond_broadcast(pthread_cond_t *cond)
{
TX_SEMAPHORE *semaphore_ptr;
TX_THREAD *thread;
UINT status;
ULONG sem_count;
UINT old_threshold,dummy;
/* Get the condition variable's internal semaphore. */
/* Simply convert the condition variable control block into a semaphore a cast */
semaphore_ptr = (&( cond->cond_semaphore ));
sem_count = semaphore_ptr->tx_semaphore_suspended_count;
if (!sem_count)
return(OK);
status = tx_semaphore_prioritize(semaphore_ptr);
if ( status != TX_SUCCESS)
{
posix_errno = EINVAL;
posix_set_pthread_errno(EINVAL);
return(EINVAL);
}
/* get to know about current thread */
thread = tx_thread_identify();
/* Got the current thread , now raise its preemption threshold */
/* that way the current thread does not get descheduled when */
/* threads with higher priority are activated */
tx_thread_preemption_change(thread,0,&old_threshold);
while( sem_count)
{
status = tx_semaphore_put(semaphore_ptr);
if ( status != TX_SUCCESS)
{
/* restore changed preemption threshold */
tx_thread_preemption_change(thread,old_threshold,&dummy);
posix_errno = EINVAL;
posix_set_pthread_errno(EINVAL);
return(EINVAL);
}
sem_count--;
}
/* restore changed preemption threshold */
tx_thread_preemption_change(thread,old_threshold,&dummy);
return(OK);
}
|