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
|
/***************************************************************************
* 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_timedwait PORTABLE C */
/* 6.1.7 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function shall block on a condition variable. They shall be */
/* called with mutex locked by the calling thread or undefined behavior*/
/* results.These functions atomically release the mutex and cause the */
/* calling thread to block on the condition variable cond; atomically */
/* here means ��atomically with respect to access by another */
/* thread to the mutex and then the request for semaphore. */
/* */
/* Upon successful return, the mutex shall have been locked and shall */
/* be owned by the calling thread. */
/* */
/* Upon successful return, the mutex shall have been locked and shall */
/* be owned by the calling thread. */
/* When using condition variables there is always a Boolean predicate */
/* involving shared variables associated with each condition wait that */
/* is true if the thread should proceed. Spurious wakeups from the */
/* pthread_cond_timedwait or pthread_cond_wait functions may occur. */
/* Since the return from pthread_cond_timedwait or pthread_cond_wait */
/* does not imply anything about the value of this predicate, the */
/* predicate should be re-evaluated upon such return. The effect of */
/* using more than one mutex for concurrent pthread_cond_timedwait or */
/* pthread_cond_wait operations on the same condition variable is */
/* undefined; that is, a condition variable becomes bound to a unique */
/* mutex when a thread waits on the condition variable, and this */
/* (dynamic) binding shall end when the wait returns. */
/* */
/* INPUT */
/* */
/* cond condition variable */
/* mutex mutex to be associated with condition */
/* variable */
/* abstime time interval for wait */
/* */
/* OUTPUT */
/* */
/* OK if succesfull */
/* ERROR in case of any error */
/* */
/* CALLS */
/* */
/* pthread_mutex_unlock unlocks the mutex held by the caller */
/* tx_semaphore_get try to get sempaphore internal to cond */
/* tx_semaphore_prioritize prioritize all suspended pthreads */
/* pthread_mutex_lock lock the mutex */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/**************************************************************************/
INT pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex,
struct timespec *abstime)
{
TX_SEMAPHORE *semaphore_ptr;
ULONG wait_option;
UINT status;
UINT old_threshold,dummy;
TX_THREAD *thread;
/* Find the current thread. */
thread = tx_thread_identify();
/* Raise its preemption threshold so it does not get descheduled. */
tx_thread_preemption_change(thread,0,&old_threshold);
pthread_mutex_unlock(mutex);
semaphore_ptr = (&( cond->cond_semaphore ));
wait_option = posix_abs_time_to_rel_ticks(abstime);
status = tx_semaphore_get(semaphore_ptr, wait_option);
/* Restore original preemption threshold */
tx_thread_preemption_change(thread, old_threshold, &dummy);
if( status == TX_NO_INSTANCE)
{
posix_errno = ETIMEDOUT;
posix_set_pthread_errno(ETIMEDOUT);
return(ETIMEDOUT);
}
else if ( status != TX_SUCCESS)
{
posix_errno = EINVAL;
posix_set_pthread_errno(EINVAL);
return(EINVAL);
}
status = tx_semaphore_prioritize(semaphore_ptr);
if (status != TX_SUCCESS)
{
posix_errno = EINVAL;
posix_set_pthread_errno(EINVAL);
return(EINVAL);
}
pthread_mutex_lock(mutex);
return(OK);
}
|