summaryrefslogtreecommitdiff
path: root/utility/rtos_compatibility_layers/posix/px_cond_broadcast.c
blob: f9c8f1510efa9c1b1e31ee8ec494416c6b623bc6 (plain)
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);
}