1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** POSIX wrapper for THREADX */
17 /** */
18 /** */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 /* Include necessary system files. */
24
25 #include "tx_api.h" /* Threadx API */
26 #include "pthread.h" /* Posix API */
27 #include "px_int.h" /* Posix helper functions */
28
29
30 /**************************************************************************/
31 /* */
32 /* FUNCTION RELEASE */
33 /* */
34 /* posix_arrange_msg PORTABLE C */
35 /* 6.2.0 */
36 /* AUTHOR */
37 /* */
38 /* William E. Lamie, Microsoft Corporation */
39 /* */
40 /* DESCRIPTION */
41 /* */
42 /* Return the oldest, highest priority message from the queue. */
43 /* */
44 /* INPUT */
45 /* */
46 /* Queue queue descriptor */
47 /* *pMsgPrio If not NULL, priority of message */
48 /* */
49 /* OUTPUT */
50 /* */
51 /* OK Always return successful */
52 /* */
53 /* CALLS */
54 /* */
55 /* None */
56 /* */
57 /* CALLED BY */
58 /* */
59 /* POSIX internal Code */
60 /* */
61 /* RELEASE HISTORY */
62 /* */
63 /* DATE NAME DESCRIPTION */
64 /* */
65 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */
66 /* 10-31-2022 Scott Larson Modified comments, */
67 /* fixed message swap logic, */
68 /* resulting in version 6.2.0 */
69 /* */
70 /**************************************************************************/
posix_arrange_msg(TX_QUEUE * Queue,ULONG * pMsgPrio)71 ULONG posix_arrange_msg(TX_QUEUE *Queue, ULONG *pMsgPrio)
72 {
73 ULONG* q_read; /* to store read ptr of the queue */
74 ULONG* temp_q = TX_NULL; /* temp storage for the message pointer */
75 ULONG numMsgs; /* no of messages queued */
76 ULONG msg; /* temp variable for thr for loop */
77 ULONG priority; /* priority of the message */
78 ULONG maxPrio; /* max. priority of the messages in queue*/
79 ULONG number2; /* messages */
80 ULONG minNo; /* oldest message in the same priority */
81 ULONG swap; /* temp.variable for the swapping of the */
82 /* messages */
83
84 /* initialize the priority to the lowest priority. */
85 maxPrio = 0;
86 minNo = 0;
87
88 /* Copy read pointer to the temporary variable. */
89 q_read = Queue -> tx_queue_read;
90
91 /* Copy no. of messages in the queue to the temporary variable. */
92 numMsgs = Queue -> tx_queue_enqueued;
93
94 /* If there is 0 or 1 message, no rearranging is needed. */
95 if (numMsgs < 2)
96 {
97 return(OK);
98 }
99
100 for (msg = 0; msg < numMsgs; msg++)
101 {
102 /* Advance q_read to read the priority of the message. */
103 q_read = q_read + TX_POSIX_QUEUE_PRIORITY_OFFSET;
104
105 /* Priority of the message queued. */
106 priority = *q_read;
107
108 /* check with maxpriority. */
109 if (priority > maxPrio)
110 {
111 /* copy read pointer to temporary pointer. */
112 temp_q = q_read-TX_POSIX_QUEUE_PRIORITY_OFFSET;
113
114 /* increment read pointer to point to order. */
115 q_read++;
116
117 /* copy FIFO order to the message */
118 minNo = *q_read;
119
120 /* Found higher priority message. */
121 maxPrio = priority;
122
123 q_read++;
124 }
125
126 /* if more than one message of the same priority is in the queue
127 then check if this the oldest message. */
128 else if (priority == maxPrio)
129 {
130 /* increment read pointer to point to read FIFO order */
131 q_read++;
132
133 /* copy number to the local variable. */
134 number2 = *q_read;
135
136 /* Go to next message. */
137 q_read++;
138
139 /* find the oldest of the messages in this priority level. */
140 if( number2 < minNo )
141 {
142 /* founder older one */
143 minNo = number2;
144 /* copy read pointer to temporary buffer. */
145 temp_q = q_read - (TX_POSIX_MESSAGE_SIZE);
146 }
147 }
148
149 else
150 {
151 /* Not highest priority, go to next message. */
152 q_read = q_read + (TX_POSIX_MESSAGE_SIZE - TX_POSIX_QUEUE_PRIORITY_OFFSET);
153 }
154
155 /* Determine if we are at the end. */
156 if (q_read >= Queue -> tx_queue_end)
157 {
158 /* Yes, wrap around to the beginning. */
159 q_read = Queue -> tx_queue_start;
160 }
161 }
162
163 /* Output priority if non-null */
164 if (pMsgPrio != NULL)
165 {
166 /* copy message priority. */
167 *pMsgPrio = maxPrio;
168 }
169
170 /* All messages checked, temp_q holds address of oldest highest priority message
171 and maxPrio holds the highest priority. */
172 /* Get the current queue read pointer */
173 q_read = Queue -> tx_queue_read;
174
175 if((temp_q != TX_NULL) && (temp_q != q_read))
176 {
177 /* Swap the messages. */
178 for (msg = 0; msg < TX_POSIX_MESSAGE_SIZE; msg++)
179 {
180 swap = *temp_q;
181 *temp_q = *q_read;
182 *q_read = swap;
183 temp_q++;
184 q_read++;
185 }
186 }
187
188 return(OK);
189 }
190