1 /*
2 * Copyright (C) 2013 SAMSUNG S.LSI
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 *
17 */
18
19 /************************************************************************
20 ** OS interface for task handling
21 *************************************************************************/
22 #include <pthread.h>
23 #include <sched.h>
24 #include <string.h>
25 #include "osi.h"
26
27 /************************************************************************
28 ** Internal function prototype
29 *************************************************************************/
30
31 /************************************************************************
32 ** Public functions
33 *************************************************************************/
OSI_mem_get(size_t size)34 tOSI_MEM_HANDLER OSI_mem_get(size_t size) {
35 tOSI_MEM_HANDLER free_mem = NULL;
36 int index, err_cnt = 3;
37
38 if (size > OSI_MEM_POOL_SIZE) {
39 OSI_loge("%s : memory getting failed. Max size=%d, Requested size=%d",
40 __func__, OSI_MEM_POOL_SIZE, (int)size);
41 return NULL;
42 }
43
44 /* Try 3 times to get memory */
45 retry_getting:
46
47 osi_lock();
48 for (index = 0; index < osi_info.mem_max_cnt; index++) {
49 #ifdef OSI_USE_DYNAMIC_BUF
50 if (osi_info.mem[index]->state == OSI_FREE)
51 free_mem = (tOSI_MEM_HANDLER)osi_info.mem[index];
52 #else
53 if (osi_info.mem[index].state == OSI_FREE)
54 free_mem = (tOSI_MEM_HANDLER)&osi_info.mem[index];
55 #endif
56 }
57
58 if (free_mem == NULL) {
59 /* Not found free memory handler */
60 OSI_loge("%s : Failed to find free memory pool(max: %d)", __func__,
61 osi_info.mem_max_cnt);
62 #ifdef OSI_USE_DYNAMIC_BUF
63 /* get a new buffer */
64 free_mem = osi_info.mem[index] =
65 (tOSI_MEM_HANDLER)malloc(OSI_MEM_POOL_SIZE);
66 if (osi_info.mem[index] != NULL) {
67 osi_info.mem[index]->state = OSI_FREE;
68 osi_info.mem_max_cnt++;
69 OSI_loge("%s : get a new buffer (max: %d)", __func__,
70 osi_info.mem_max_cnt);
71 } else
72 #endif
73 if (--err_cnt > 0) {
74 OSI_loge("%s : try %d time(s) more!", __func__, err_cnt + 1);
75 osi_unlock();
76 sched_yield();
77 OSI_delay(20);
78 goto retry_getting;
79 }
80 } else {
81 free_mem->state = OSI_ALLOCATED;
82 memset(free_mem->buffer, 0, OSI_MEM_POOL_SIZE);
83 }
84 osi_unlock();
85
86 return free_mem;
87 }
88
OSI_mem_free(tOSI_MEM_HANDLER target)89 void OSI_mem_free(tOSI_MEM_HANDLER target) {
90 if (!target) return;
91
92 osi_lock();
93 target->state = OSI_FREE;
94 osi_unlock();
95 }
96
OSI_queue_allocate(const char * que_name)97 tOSI_QUEUE_HANDLER OSI_queue_allocate(const char* que_name) {
98 tOSI_QUEUE_HANDLER free_que = NULL;
99 int index;
100
101 osi_lock();
102 for (index = 0; index < osi_info.queue_max_cnt; index++) {
103 if (osi_info.queue[index].state == OSI_FREE) {
104 if (free_que == NULL)
105 free_que = (tOSI_QUEUE_HANDLER)&osi_info.queue[index];
106 } else {
107 if (osi_info.queue[index].name == NULL) continue;
108
109 if (strcmp((char const*)osi_info.queue[index].name,
110 (char const*)que_name) == 0) {
111 OSI_loge("%s : %s queue is already allocated [%d]", __func__, que_name,
112 index);
113 free_que = NULL;
114 break;
115 }
116 }
117 }
118
119 if (free_que == NULL) {
120 OSI_loge("%s : Failed to find free queue(max: %d)", __func__,
121 OSI_MAX_QUEUE);
122 } else {
123 memset(free_que->queue, 0, OSI_QUEUE_SIZE);
124 free_que->name = que_name;
125 free_que->state = OSI_ALLOCATED;
126 free_que->head = 0;
127 free_que->tail = OSI_QUEUE_SIZE;
128 }
129 osi_unlock();
130
131 return free_que;
132 }
133
OSI_queue_put(tOSI_QUEUE_HANDLER queue,void * p_data)134 int OSI_queue_put(tOSI_QUEUE_HANDLER queue, void* p_data) {
135 int ret;
136
137 osi_lock();
138
139 if (!queue || queue->state != OSI_ALLOCATED) {
140 OSI_loge("%s : queue is not allocated", __func__);
141 return -1;
142 }
143
144 if (queue->head == queue->tail) {
145 OSI_loge("%s : queue is overflower (max: %d)", __func__, OSI_QUEUE_SIZE);
146 } else {
147 queue->queue[queue->head++] = p_data;
148 if (queue->head >= OSI_QUEUE_SIZE) queue->head = 0;
149
150 // pthread_cond_broadcast(&queue->cond);
151 pthread_cond_signal(&queue->cond);
152 }
153
154 ret = (queue->head) - (queue->tail);
155
156 osi_unlock();
157
158 if (ret < 0) ret += OSI_QUEUE_SIZE;
159
160 return ret;
161 }
162
queue_get(tOSI_QUEUE_HANDLER queue)163 void* queue_get(tOSI_QUEUE_HANDLER queue) {
164 void* data = NULL;
165
166 if (!queue || queue->state != OSI_ALLOCATED) {
167 OSI_loge("%s : queue is not allocated", __func__);
168 return NULL;
169 }
170
171 if (queue->tail + 1 >= OSI_QUEUE_SIZE) {
172 if (queue->head == 0) {
173 // empty
174 // OSI_loge("%s : queue is empty", __func__);
175 return NULL;
176 }
177 } else {
178 if (queue->tail + 1 == queue->head) {
179 // empty
180 // OSI_loge("%s : queue is empty", __func__);
181 return NULL;
182 }
183 }
184
185 queue->tail++;
186 if (queue->tail >= OSI_QUEUE_SIZE) queue->tail = 0;
187 data = queue->queue[queue->tail];
188
189 return data;
190 }
191
OSI_queue_get(tOSI_QUEUE_HANDLER queue)192 void* OSI_queue_get(tOSI_QUEUE_HANDLER queue) {
193 void* data = NULL;
194
195 osi_lock();
196 data = queue_get(queue);
197 osi_unlock();
198
199 return data;
200 }
201
OSI_queue_get_wait(tOSI_QUEUE_HANDLER queue)202 void* OSI_queue_get_wait(tOSI_QUEUE_HANDLER queue) {
203 void* ret;
204
205 osi_lock();
206
207 if (!queue || queue->state != OSI_ALLOCATED) {
208 OSI_loge("%s : queue is not allocated", __func__);
209 return NULL;
210 }
211
212 ret = queue_get(queue);
213 if (ret == NULL) {
214 pthread_cond_wait(&queue->cond, &osi_info.mutex);
215 ret = queue_get(queue);
216 }
217
218 osi_unlock();
219
220 return ret;
221 }
222
OSI_queue_free(tOSI_QUEUE_HANDLER target)223 void OSI_queue_free(tOSI_QUEUE_HANDLER target) {
224 if (target) {
225 target->name = NULL;
226 target->state = OSI_FREE;
227 }
228 }
229
OSI_queue_get_handler(const char * name)230 tOSI_QUEUE_HANDLER OSI_queue_get_handler(const char* name) {
231 tOSI_QUEUE_HANDLER queue = NULL;
232 int index;
233
234 if (name == NULL) return NULL;
235
236 osi_lock();
237 for (index = 0; index < OSI_MAX_QUEUE; index++) {
238 if (osi_info.queue[index].name == NULL) continue;
239
240 if (strcmp((char const*)osi_info.queue[index].name, (char const*)name) ==
241 0) {
242 queue = (tOSI_QUEUE_HANDLER)&osi_info.queue[index];
243 break;
244 }
245 }
246 osi_unlock();
247
248 return queue;
249 }
250