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 (at) 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 37 OMX_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 82 OMX_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 108 int 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 128 void *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 150 int 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 163 int 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 175 int 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