summaryrefslogtreecommitdiff
path: root/utility/rtos_compatibility_layers/posix/px_mq_arrange_msg.c
blob: f72d02457420a8b44bc8641f11edfd79ea2cde5d (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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/***************************************************************************
 * 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        */
/*                                                                        */
/*    posix_arrange_msg                                   PORTABLE C      */
/*                                                           6.2.0        */
/*  AUTHOR                                                                */
/*                                                                        */
/*    William E. Lamie, Microsoft Corporation                             */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    Return the oldest, highest priority message from the queue.         */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*    Queue                         queue descriptor                      */
/*   *pMsgPrio                      If not NULL, priority of message      */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*    OK                            Always return successful              */
/*                                                                        */
/*  CALLS                                                                 */
/*                                                                        */
/*    None                                                                */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    POSIX internal Code                                                 */
/*                                                                        */
/**************************************************************************/
ULONG posix_arrange_msg(TX_QUEUE *Queue, ULONG *pMsgPrio)
{
    ULONG*  q_read;             /* to store read ptr of the queue        */
    ULONG*  temp_q = TX_NULL;   /* temp storage for the message pointer  */
    ULONG   numMsgs;            /* no of messages queued                 */
    ULONG   msg;                /* temp variable for thr for loop        */
    ULONG   priority;           /* priority of the message               */
    ULONG   maxPrio;            /* max. priority of the messages in queue*/
    ULONG   number2;            /* messages                              */
    ULONG   minNo;              /* oldest message in the same priority   */
    ULONG   swap;               /* temp.variable for the swapping of the */
                                /* messages                              */

    /* initialize the priority to the lowest priority.  */
    maxPrio = 0;
    minNo = 0;

    /* Copy read pointer to the temporary variable.  */
    q_read = Queue -> tx_queue_read;

    /* Copy no. of messages in the queue to the temporary variable.  */
    numMsgs = Queue -> tx_queue_enqueued;

    /* If there is 0 or 1 message, no rearranging is needed.  */
    if (numMsgs < 2)
    {
        return(OK);
    }

    for (msg = 0; msg < numMsgs; msg++)
    {
        /* Advance q_read to read the priority of the message.  */
        q_read = q_read + TX_POSIX_QUEUE_PRIORITY_OFFSET;

        /* Priority of the message queued.  */
        priority = *q_read;

        /* check with maxpriority.  */
        if (priority > maxPrio)
        {
            /* copy read pointer to temporary pointer.  */
            temp_q = q_read-TX_POSIX_QUEUE_PRIORITY_OFFSET;

            /* increment read pointer to point to order.  */
            q_read++;

            /* copy FIFO order to the message  */
            minNo = *q_read;

            /* Found higher priority message.  */
            maxPrio = priority;

            q_read++;
        }

        /* if more than one message of the same priority is in the queue
           then check if this the oldest message.  */
        else if (priority == maxPrio)
        {
            /* increment read pointer to point to read FIFO order */
            q_read++;

            /* copy number to the local variable.  */
            number2 = *q_read;

            /* Go to next message.  */
            q_read++;

            /* find the oldest of the messages in this priority level.  */
            if( number2 < minNo )
            {
                /* founder older one  */
                minNo = number2;
                /* copy read pointer to temporary buffer.  */
                temp_q = q_read - (TX_POSIX_MESSAGE_SIZE);
            }
        }

        else
        {
            /* Not highest priority, go to next message.  */
            q_read = q_read + (TX_POSIX_MESSAGE_SIZE - TX_POSIX_QUEUE_PRIORITY_OFFSET);
        }

        /* Determine if we are at the end.  */
        if (q_read >= Queue -> tx_queue_end)
        {
            /* Yes, wrap around to the beginning.  */
            q_read = Queue -> tx_queue_start;
        }
    }

    /* Output priority if non-null */
    if (pMsgPrio != NULL)
    {
        /* copy message priority.  */
        *pMsgPrio = maxPrio;
    }

    /* All messages checked, temp_q holds address of oldest highest priority message
       and maxPrio holds the highest priority.  */
    /* Get the current queue read pointer */
    q_read = Queue -> tx_queue_read;

    if((temp_q != TX_NULL) && (temp_q != q_read))
    {
        /* Swap the messages.  */
        for (msg = 0; msg < TX_POSIX_MESSAGE_SIZE; msg++)
        {
            swap = *temp_q;
            *temp_q = *q_read;
            *q_read = swap;
            temp_q++;
            q_read++;
        }
    }

    return(OK);
}