1/*
2 *
3 * Copyright 2012 Samsung Electronics S.LSI Co. LTD
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * @file        Exynos_OSAL_Queue.c
20 * @brief
21 * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
22 * @version     2.0.0
23 * @history
24 *   2012.02.20 : Create
25 */
26
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31
32#include "Exynos_OSAL_Memory.h"
33#include "Exynos_OSAL_Mutex.h"
34#include "Exynos_OSAL_Queue.h"
35
36
37OMX_ERRORTYPE Exynos_OSAL_QueueCreate(EXYNOS_QUEUE *queueHandle, int maxNumElem)
38{
39    int i = 0;
40    EXYNOS_QElem *newqelem = NULL;
41    EXYNOS_QElem *currentqelem = NULL;
42    EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle;
43
44    OMX_ERRORTYPE ret = OMX_ErrorNone;
45
46    if (!queue)
47        return OMX_ErrorBadParameter;
48
49    ret = Exynos_OSAL_MutexCreate(&queue->qMutex);
50    if (ret != OMX_ErrorNone)
51        return ret;
52
53    queue->first = (EXYNOS_QElem *)Exynos_OSAL_Malloc(sizeof(EXYNOS_QElem));
54    if (queue->first == NULL)
55        return OMX_ErrorInsufficientResources;
56
57    Exynos_OSAL_Memset(queue->first, 0, sizeof(EXYNOS_QElem));
58    currentqelem = queue->last = queue->first;
59    queue->numElem = 0;
60    queue->maxNumElem = maxNumElem;
61    for (i = 0; i < (queue->maxNumElem - 2); i++) {
62        newqelem = (EXYNOS_QElem *)Exynos_OSAL_Malloc(sizeof(EXYNOS_QElem));
63        if (newqelem == NULL) {
64            while (queue->first != NULL) {
65                currentqelem = queue->first->qNext;
66                Exynos_OSAL_Free((OMX_PTR)queue->first);
67                queue->first = currentqelem;
68            }
69            return OMX_ErrorInsufficientResources;
70        } else {
71            Exynos_OSAL_Memset(newqelem, 0, sizeof(EXYNOS_QElem));
72            currentqelem->qNext = newqelem;
73            currentqelem = newqelem;
74        }
75    }
76
77    currentqelem->qNext = queue->first;
78
79    return OMX_ErrorNone;
80}
81
82OMX_ERRORTYPE Exynos_OSAL_QueueTerminate(EXYNOS_QUEUE *queueHandle)
83{
84    int i = 0;
85    EXYNOS_QElem *currentqelem = NULL;
86    EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle;
87    OMX_ERRORTYPE ret = OMX_ErrorNone;
88
89    if (!queue)
90        return OMX_ErrorBadParameter;
91
92    for ( i = 0; i < (queue->maxNumElem - 2); i++) {
93        currentqelem = queue->first->qNext;
94        Exynos_OSAL_Free(queue->first);
95        queue->first = currentqelem;
96    }
97
98    if(queue->first) {
99        Exynos_OSAL_Free(queue->first);
100        queue->first = NULL;
101    }
102
103    ret = Exynos_OSAL_MutexTerminate(queue->qMutex);
104
105    return ret;
106}
107
108int Exynos_OSAL_Queue(EXYNOS_QUEUE *queueHandle, void *data)
109{
110    EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle;
111    if (queue == NULL)
112        return -1;
113
114    Exynos_OSAL_MutexLock(queue->qMutex);
115
116    if ((queue->last->data != NULL) || (queue->numElem >= queue->maxNumElem)) {
117        Exynos_OSAL_MutexUnlock(queue->qMutex);
118        return -1;
119    }
120    queue->last->data = data;
121    queue->last = queue->last->qNext;
122    queue->numElem++;
123
124    Exynos_OSAL_MutexUnlock(queue->qMutex);
125    return 0;
126}
127
128void *Exynos_OSAL_Dequeue(EXYNOS_QUEUE *queueHandle)
129{
130    void *data = NULL;
131    EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle;
132    if (queue == NULL)
133        return NULL;
134
135    Exynos_OSAL_MutexLock(queue->qMutex);
136
137    if ((queue->first->data == NULL) || (queue->numElem <= 0)) {
138        Exynos_OSAL_MutexUnlock(queue->qMutex);
139        return NULL;
140    }
141    data = queue->first->data;
142    queue->first->data = NULL;
143    queue->first = queue->first->qNext;
144    queue->numElem--;
145
146    Exynos_OSAL_MutexUnlock(queue->qMutex);
147    return data;
148}
149
150int Exynos_OSAL_GetElemNum(EXYNOS_QUEUE *queueHandle)
151{
152    int ElemNum = 0;
153    EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle;
154    if (queue == NULL)
155        return -1;
156
157    Exynos_OSAL_MutexLock(queue->qMutex);
158    ElemNum = queue->numElem;
159    Exynos_OSAL_MutexUnlock(queue->qMutex);
160    return ElemNum;
161}
162
163int Exynos_OSAL_SetElemNum(EXYNOS_QUEUE *queueHandle, int ElemNum)
164{
165    EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle;
166    if (queue == NULL)
167        return -1;
168
169    Exynos_OSAL_MutexLock(queue->qMutex);
170    queue->numElem = ElemNum;
171    Exynos_OSAL_MutexUnlock(queue->qMutex);
172    return ElemNum;
173}
174
175int Exynos_OSAL_ResetQueue(EXYNOS_QUEUE *queueHandle)
176{
177    EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle;
178    EXYNOS_QElem *currentqelem = NULL;
179
180    if (queue == NULL)
181        return -1;
182
183    Exynos_OSAL_MutexLock(queue->qMutex);
184    queue->first->data = NULL;
185    currentqelem = queue->first->qNext;
186    while (currentqelem != queue->first) {
187        currentqelem->data = NULL;
188        currentqelem = currentqelem->qNext;
189    }
190    queue->last = queue->first;
191    queue->numElem = 0x00;
192    Exynos_OSAL_MutexUnlock(queue->qMutex);
193
194    return 0;
195}
196