source: svn/trunk/zas_dstar/hal/os/src/os_queue.c @ 2

Last change on this file since 2 was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
File size: 14.0 KB
Line 
1/****************************************************************************
2 * Copyright (c) 2006 DST Technologies Inc.  All Rights Reserved.   
3 *
4 * Module:      OS_QUEUE
5 *
6 * Description: Unified APIs for interfacing with different operating systems
7 *              (WinCE)
8 *
9 * Notes:       This module implement APIs to interface with the following
10 *              operating system's objects:
11 *              - Queues
12 *
13 *              This implementation provide fixed-length-message queues. The
14 *              message can be of any size, selected by the caller who creates
15 *              the queue. However, these queues can not be shared between
16 *              multiple processes and can not be used from an ISR.
17 *
18 ***************************************************************************/
19
20/*==========================
21 * Includes
22 *=========================*/
23#include "dsthallocal.h"
24#include "os.h"
25#include "os_prive.h"
26#include <string.h>
27
28#ifdef DMALLOC
29#include <dmalloc.h>
30#endif
31
32#define DEBUG                   0
33
34
35//yzyeo
36#define MSGQ_SIZE
37
38#ifdef MSGQ_SIZE
39typedef struct
40{
41        DS_U32 msg_size;
42        DS_U8 msg[0];
43} MSG_DATA,*pMSG_DATA;
44#endif
45/*=========================
46 * Defines
47 *========================*/
48typedef struct
49{
50    DS_U32  Name;
51    DS_U32  ByteSize;                   /* Size of the queue in bytes   */
52    DS_U32  MsgSize;                    /* Message size in bytes        */
53    DS_U32  Head;                       /* Head offset from queue start */
54    DS_U32  Tail;                       /* Tail offset from queue start */
55    CORE_MUTEX_ID QMutex;               /* Queue mutex                  */
56    CORE_EVENT_ID QEvent;               /* Queue event                  */
57    DS_U8  *StartPtr;                  /* Pointer to queue start       */
58    DS_U32      curCount;
59    DS_U32      maxCount;
60    DS_U32      Limit;
61}MSG_QUEUE;
62
63/*=========================
64 * Local variables
65 *========================*/
66
67/*^^***************************************************************************
68 * CORE_QUEUE_ID DstCore_QueueCreate (DS_U32 QueueName, DS_U32 MaxMsgCount,
69 *                                   DS_U32 MsgDwordLen)
70 *
71 * Description: Create a fixed length message queue.
72 *
73 * Entry :  QueueName   = Unique number identifying the Queue. Must be set
74 *                        to NULL since this implementation does not support
75 *                        process-shared queues.
76 *          MaxMagCount = Max number of messages the queue can hold.
77 *          MsgDwordLen = Message length in DWORDs. (e.g, if the max message
78 *                        length is 16 bytes, this parameter must be set to 4)
79 *                     
80 *
81 *
82 * Return:  Queue ID or
83 *          NULL if any error
84 *
85 * Notes :  The queue will be created empty with priority order pending.
86 *          The entry QueueName is currently not used since queues can not be
87 *          shared between multiple processes.
88 **************************************************************************^^*/
89CORE_QUEUE_ID DstCore_QueueCreate (DS_U32 QueueName, DS_U32 MaxMsgCount,
90                                   DS_U32 MsgDwordLen)
91{
92    CORE_MUTEX_ID Qmutex;
93    CORE_EVENT_ID Qevent;
94    MSG_QUEUE   *Qptr;
95    DS_U32      MsgLen;         /* Message byte length */
96
97    MaxMsgCount++;              /* Queue is full if only one entry free */
98//yzyeo
99#ifndef MSGQ_SIZE
100        MsgLen = MsgDwordLen * 4;
101#else
102        MsgLen = sizeof(MSG_DATA) + (MsgDwordLen);
103#endif 
104
105    /*================================================
106     * Create memory, mutex and event for the queue
107     *===============================================*/
108    Qptr = (MSG_QUEUE *) malloc ( 
109                        sizeof (MSG_QUEUE) + (MaxMsgCount * MsgLen));
110#if 0
111    if ( Qptr == (MSG_QUEUE *)0x10132008 ) {
112        if ( QueueName ) {
113                char *ptr = (char *)QueueName;
114                printf("Q Name = %s\n", ptr);
115                }
116            Qptr = (MSG_QUEUE *) malloc ( sizeof (MSG_QUEUE) + (MaxMsgCount * MsgLen) );
117        }
118#endif
119    if (Qptr == NULL)
120    {
121        return (0);
122    }
123
124    Qmutex = DstCore_MutexCreate (0);
125    if (Qmutex == 0)
126    {
127        free (Qptr);
128        return (0);
129    }
130
131    Qevent = DstCore_EventCreate (0, _FALSE_);
132    if (Qevent == 0)
133    {
134        DstCore_MutexDelete (Qmutex);
135        free (Qptr);
136        return (0);
137    }
138       
139    /*==========================================
140     * Initialize the queue
141     *=========================================*/
142    DstCore_MutexLock (Qmutex, OS_WAIT_FOREVER);
143
144    Qptr->Name      = QueueName;
145    Qptr->ByteSize  = MaxMsgCount * MsgLen;
146    Qptr->MsgSize   = MsgLen;
147    Qptr->Head      = 0;
148    Qptr->Tail      = 0;
149    Qptr->QMutex    = Qmutex;
150    Qptr->QEvent    = Qevent;
151    Qptr->StartPtr  = (DS_U8 *) (((DS_U32)Qptr) + sizeof (MSG_QUEUE));
152        Qptr->curCount  = 0;
153        Qptr->maxCount  = MaxMsgCount;
154        Qptr->Limit     = ((DS_U32)Qptr) + sizeof (MSG_QUEUE) + (MaxMsgCount * MsgLen); 
155
156#if DEBUG
157        printf("QId=0x%08lX, StartPtr=0x%08lX, Limit=0x%08lX,", (DS_U32)Qptr, (DS_U32)Qptr->StartPtr, (DS_U32)Qptr->Limit);
158        printf("ByteSize=0x%08lX, MsgSize=0x%08lX, MaxMsgCount=0x%08lX\n", Qptr->ByteSize, Qptr->MsgSize, MaxMsgCount);
159#endif
160    DstCore_MutexUnlock (Qmutex);
161
162    return ((CORE_QUEUE_ID)Qptr);
163}
164
165/*^^***************************************************************************
166 * DS_U32 DstCore_QueuePost (CORE_QUEUE_ID QueueId, DS_U32 Message)
167 *
168 * Description: Post a message to a fixed-length message queue.
169 *
170 * Entry :  QueueId = Returned by QueueCreate
171 *          Message = Pointer to the message to put at end of queue. Message
172 *                    size must be equal to the queue message size
173 *
174 * Return:  OS_OK
175 *          OS_FAIL
176 *
177 * Notes :
178 **************************************************************************^^*/
179DS_U32 DstCore_QueuePost (CORE_QUEUE_ID QueueId, DS_U32 *Message
180#ifdef MSGQ_SIZE
181                         , DS_U32  msg_size
182#endif
183    )
184{
185    CORE_MUTEX_ID Qmutex;
186    MSG_QUEUE   *Qptr;
187    DS_U32      RetVal = OS_FAIL;
188    DS_U32      Head, Tail, Avail;
189
190    /*==========================================
191     * Get queue mutex
192     *=========================================*/
193    if (QueueId == 0)
194    {
195        return (OS_FAIL);
196    }
197    Qptr = (MSG_QUEUE *) QueueId;
198    Qmutex = Qptr->QMutex;
199
200    DstCore_MutexLock (Qmutex, OS_WAIT_FOREVER);
201
202    /*==========================================
203     * Get available space in the queue
204     *=========================================*/
205    Head = Qptr->Head;
206    Tail = Qptr->Tail;
207    if (Head  > Tail)
208    {
209        Avail = Head - Tail;
210    }
211    else
212    {
213        Avail = Qptr->ByteSize - (Tail - Head);
214    }
215
216    /*====================================
217     * If there's space for two messages
218     *===================================*/
219    if (Avail >= (Qptr->MsgSize * 2))
220    {
221#ifdef MSGQ_SIZE
222                pMSG_DATA pData;
223                pData = (pMSG_DATA)((DS_U8*)Qptr->StartPtr + Tail);
224
225                if(msg_size > Qptr->MsgSize){
226                        printf("ERROR: message queue sending data size is overflow(%ld > %ld) \n",msg_size,Qptr->MsgSize);
227                        msg_size = Qptr->MsgSize; 
228                }
229                pData->msg_size  = msg_size; 
230                //Tail += sizeof(MSG_DATA);
231               
232                if ( ((DS_U32)(pData->msg) + msg_size) > Qptr->Limit ) {
233                        printf("|%s| ERROR: LINE=%d\n", __FUNCTION__, __LINE__);
234                }
235
236#if DEBUG
237                printf("|%s| Current Ptr = 0x%08lX\n", __FUNCTION__, (DS_U32)pData->msg);
238#endif
239                memcpy(pData->msg, Message, msg_size); 
240#else
241        memcpy (Qptr->StartPtr + Tail, Message, Qptr->MsgSize); 
242#endif   
243        Tail+= Qptr->MsgSize;
244        if (Tail >= Qptr->ByteSize)
245        {
246            Tail = 0;
247        }
248        Qptr->Tail = Tail;
249        RetVal = OS_OK;
250        DstCore_EventSet (Qptr->QEvent);            /* Set the queue event  */
251        Qptr->curCount++;
252        if ( Qptr->curCount >= Qptr->maxCount ) {
253                printf("|%s:%d| ERROR: Queue Count is over than maxCount! Qptr->curCount=%d, Qptr->maxCount=%d\n", __FUNCTION__, __LINE__, (int)Qptr->curCount, (int)Qptr->maxCount );
254        }
255    }
256    DstCore_MutexUnlock (Qmutex);
257    return (RetVal);
258}
259
260/*^^***************************************************************************
261 * DS_U32 DstCore_QueueWait (CORE_QUEUE_ID QueueId, DS_U32 *Msg, DS_U32 Timeout)
262 *
263 * Description: Wait for a message in a queue.
264 *
265 * Entry :  QueueId = Returned by QueueCreate
266 *          Msg     = Pointer to buffer to receive message of queue msg length
267 *          Timeout = In 1/100 of a second increments. This is ONLY accurate
268 *                    if the OS provides a way of getting system ticks/second.
269 *                    = 0 to return immidiately if the resource not available
270 *                    = OS_WAIT_FOREVER to wait forever on the resource
271 *
272 * Return:  OS_OK
273 *          OS_TIMEOUT
274 *          OS_FAIL
275 *
276 * Notes :
277 **************************************************************************^^*/
278DS_U32 DstCore_QueueWait (CORE_QUEUE_ID QueueId, DS_U32 *Msg, DS_U32 Timeout
279#ifdef MSGQ_SIZE
280                         , DS_U32 * MsgSize
281#endif
282    )
283{
284    CORE_MUTEX_ID Qmutex;
285    MSG_QUEUE   *Qptr;
286    DS_U32      RetVal = OS_OK;
287    DS_U32      Head = 0, Tail;
288
289    /*==========================================
290     * Get queue mutex
291     *=========================================*/
292    if (QueueId == 0)
293    {
294        return (OS_FAIL);
295    }
296    Qptr = (MSG_QUEUE *) QueueId;
297    Qmutex = Qptr->QMutex;
298#ifdef ONE_RX_THR
299        Head = Qptr->Head;
300        Tail = Qptr->Tail;
301#else
302    Tail = Head + 1;                                /* Make head != tail */
303#endif
304
305    /*=============================================
306     * Wait until there's messages in the queue
307     *============================================*/
308    while (_TRUE_)
309    {
310        if (Head == Tail)
311        {
312            RetVal = DstCore_EventWait (Qptr->QEvent, _TRUE_, Timeout);
313        }
314#ifndef ONE_RX_THR
315        DstCore_MutexLock (Qmutex, OS_WAIT_FOREVER);
316        Head = Qptr->Head;
317#endif
318        Tail = Qptr->Tail;
319        if ((Head != Tail) || (RetVal != OS_OK))
320        {
321            break;
322        }
323        /*=========================================
324         * Got event but no messages in the queue
325         *========================================*/
326
327#ifndef ONE_RX_THR
328                DstCore_MutexUnlock (Qmutex);
329#endif
330    }
331
332    /*=============================================
333     * If there's messages in the queue
334     *============================================*/
335    if (RetVal == OS_OK)
336    {
337        /*=============================================
338         * If we have a message
339         *============================================*/
340        if (Head != Tail)
341        {
342#ifdef MSGQ_SIZE
343                        pMSG_DATA       pData;
344                        unsigned int msg_size;
345                        pData =  (pMSG_DATA)((DS_U8*)Qptr->StartPtr + Head);
346                        msg_size = pData->msg_size;
347                        //Head += sizeof(MSG_DATA);
348                       
349                        if(msg_size > Qptr->MsgSize){
350                                printf("ERROR: message queue sending data size is overflow(%ld > %ld) \n",(long)msg_size,Qptr->MsgSize);
351                                msg_size = Qptr->MsgSize; 
352                        }
353
354#if DEBUG
355                        printf("|%s| Current Ptr = 0x%08lX\n", __FUNCTION__, (DS_U32)pData->msg);
356#endif
357                        memcpy(Msg, pData->msg, msg_size);
358                        *MsgSize = msg_size;
359#else
360                        memcpy(Msg, Qptr->StartPtr + Head, Qptr->MsgSize);
361#endif
362            Head+= Qptr->MsgSize;
363            if (Head >= Qptr->ByteSize)
364            {
365                Head = 0;
366            }
367            Qptr->Head = Head;
368            DstCore_EventReset (Qptr->QEvent);
369            if ( Qptr->curCount == 0 ) {
370                printf("|%s:%d| ERROR: Queue Count is now -1.\n", __FUNCTION__, __LINE__);
371            }
372            Qptr->curCount--;
373        }
374        else
375        {
376            RetVal = OS_FAIL;
377        }
378    }
379
380#ifndef ONE_RX_THR
381        DstCore_MutexUnlock (Qmutex);
382#endif
383    return (RetVal);
384}
385
386/*^^***************************************************************************
387 * DS_U32 DstCore_QueueReset (CORE_QUEUE_ID QueueId)
388 *
389 * Description: Removes all messages from fixed-length message queue.
390 *
391 * Entry :  QueueId = Returned by QueueCreate
392 *
393 * Return:  OS_OK
394 *          OS_FAIL
395 *
396 * Notes :  The queue will be empty after this call.
397 **************************************************************************^^*/
398DS_U32 DstCore_QueueReset (CORE_QUEUE_ID QueueId)
399{
400    CORE_MUTEX_ID Qmutex;
401    MSG_QUEUE   *Qptr;
402
403    /*==========================================
404     * Get queue mutex
405     *=========================================*/
406    if (QueueId == 0)
407    {
408        return (OS_FAIL);
409    }
410    Qptr = (MSG_QUEUE *) QueueId;
411    Qmutex = Qptr->QMutex;
412
413    /*=============================================
414     * Reset queue head and tail
415     *============================================*/
416    DstCore_MutexLock (Qmutex, OS_WAIT_FOREVER);
417
418    Qptr->Head = 0;
419    Qptr->Tail = 0;
420    Qptr->curCount = 0;
421    DstCore_EventReset (Qptr->QEvent);
422
423    DstCore_MutexUnlock (Qmutex);
424    return (OS_OK);
425}
426
427/*^^***************************************************************************
428 * DS_U32 DstCore_QueueDelete (CORE_QUEUE_ID QueueId)
429 *
430 * Description: Delete a fixed-length message queue.
431 *
432 * Entry :  QueueId   = Returned by QueueCreate
433 *
434 * Return:  OS_OK
435 *          OS_FAIL
436 *
437 * Notes :
438 **************************************************************************^^*/
439DS_U32 DstCore_QueueDelete (CORE_QUEUE_ID QueueId)
440{
441    CORE_MUTEX_ID Qmutex;
442    MSG_QUEUE   *Qptr;
443
444    /*==========================================
445     * Get queue mutex
446     *=========================================*/
447    if (QueueId == 0)
448    {
449        return (OS_FAIL);
450    }
451    Qptr = (MSG_QUEUE *) QueueId;
452    Qmutex = Qptr->QMutex;
453
454    /*=============================================
455     * Delete queue event, mutex and memory
456     *============================================*/
457    DstCore_MutexLock (Qmutex, OS_WAIT_FOREVER);
458    DstCore_EventDelete (Qptr->QEvent);
459    free (Qptr);
460    DstCore_MutexUnlock (Qmutex);
461    DstCore_MutexDelete (Qmutex);
462
463    return (OS_OK);
464}
465
466/*^^***************************************************************************
467 * DS_BOOL Os_QueueInit (DS_BOOL Init)
468 *
469 * Description: Queues local data initialization
470 *
471 * Entry :  Init    = _TRUE_ to init
472 *                    _FALSE_ to free
473 *
474 * Return:  _TRUE_ if success
475 *
476 * Notes : 
477 *
478 **************************************************************************^^*/
479DS_BOOL Os_QueueInit (DS_BOOL Init)
480{
481    return (_TRUE_);
482}
Note: See TracBrowser for help on using the repository browser.