/* * Copyright (C) 2013 SAMSUNG S.LSI * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * */ /************************************************************************ ** OS interface for task handling *************************************************************************/ #include #include #include #include "osi.h" /************************************************************************ ** Internal function prototype *************************************************************************/ /************************************************************************ ** Public functions *************************************************************************/ tOSI_MEM_HANDLER OSI_mem_get(size_t size) { tOSI_MEM_HANDLER free_mem = NULL; int index, err_cnt = 3; if (size > OSI_MEM_POOL_SIZE) { OSI_loge("%s : memory getting failed. Max size=%d, Requested size=%d", __func__, OSI_MEM_POOL_SIZE, (int)size); return NULL; } /* Try 3 times to get memory */ retry_getting: osi_lock(); for (index = 0; index < osi_info.mem_max_cnt; index++) { #ifdef OSI_USE_DYNAMIC_BUF if (osi_info.mem[index]->state == OSI_FREE) free_mem = (tOSI_MEM_HANDLER)osi_info.mem[index]; #else if (osi_info.mem[index].state == OSI_FREE) free_mem = (tOSI_MEM_HANDLER)&osi_info.mem[index]; #endif } if (free_mem == NULL) { /* Not found free memory handler */ OSI_loge("%s : Failed to find free memory pool(max: %d)", __func__, osi_info.mem_max_cnt); #ifdef OSI_USE_DYNAMIC_BUF /* get a new buffer */ free_mem = osi_info.mem[index] = (tOSI_MEM_HANDLER)malloc(OSI_MEM_POOL_SIZE); if (osi_info.mem[index] != NULL) { osi_info.mem[index]->state = OSI_FREE; osi_info.mem_max_cnt++; OSI_loge("%s : get a new buffer (max: %d)", __func__, osi_info.mem_max_cnt); } else #endif if (--err_cnt > 0) { OSI_loge("%s : try %d time(s) more!", __func__, err_cnt + 1); osi_unlock(); sched_yield(); OSI_delay(20); goto retry_getting; } } else { free_mem->state = OSI_ALLOCATED; memset(free_mem->buffer, 0, OSI_MEM_POOL_SIZE); } osi_unlock(); return free_mem; } void OSI_mem_free(tOSI_MEM_HANDLER target) { if (!target) return; osi_lock(); target->state = OSI_FREE; osi_unlock(); } tOSI_QUEUE_HANDLER OSI_queue_allocate(const char* que_name) { tOSI_QUEUE_HANDLER free_que = NULL; int index; osi_lock(); for (index = 0; index < osi_info.queue_max_cnt; index++) { if (osi_info.queue[index].state == OSI_FREE) { if (free_que == NULL) free_que = (tOSI_QUEUE_HANDLER)&osi_info.queue[index]; } else { if (osi_info.queue[index].name == NULL) continue; if (strcmp((char const*)osi_info.queue[index].name, (char const*)que_name) == 0) { OSI_loge("%s : %s queue is already allocated [%d]", __func__, que_name, index); free_que = NULL; break; } } } if (free_que == NULL) { OSI_loge("%s : Failed to find free queue(max: %d)", __func__, OSI_MAX_QUEUE); } else { memset(free_que->queue, 0, OSI_QUEUE_SIZE); free_que->name = que_name; free_que->state = OSI_ALLOCATED; free_que->head = 0; free_que->tail = OSI_QUEUE_SIZE; } osi_unlock(); return free_que; } int OSI_queue_put(tOSI_QUEUE_HANDLER queue, void* p_data) { int ret; osi_lock(); if (!queue || queue->state != OSI_ALLOCATED) { OSI_loge("%s : queue is not allocated", __func__); return -1; } if (queue->head == queue->tail) { OSI_loge("%s : queue is overflower (max: %d)", __func__, OSI_QUEUE_SIZE); } else { queue->queue[queue->head++] = p_data; if (queue->head >= OSI_QUEUE_SIZE) queue->head = 0; // pthread_cond_broadcast(&queue->cond); pthread_cond_signal(&queue->cond); } ret = (queue->head) - (queue->tail); osi_unlock(); if (ret < 0) ret += OSI_QUEUE_SIZE; return ret; } void* queue_get(tOSI_QUEUE_HANDLER queue) { void* data = NULL; if (!queue || queue->state != OSI_ALLOCATED) { OSI_loge("%s : queue is not allocated", __func__); return NULL; } if (queue->tail + 1 >= OSI_QUEUE_SIZE) { if (queue->head == 0) { // empty // OSI_loge("%s : queue is empty", __func__); return NULL; } } else { if (queue->tail + 1 == queue->head) { // empty // OSI_loge("%s : queue is empty", __func__); return NULL; } } queue->tail++; if (queue->tail >= OSI_QUEUE_SIZE) queue->tail = 0; data = queue->queue[queue->tail]; return data; } void* OSI_queue_get(tOSI_QUEUE_HANDLER queue) { void* data = NULL; osi_lock(); data = queue_get(queue); osi_unlock(); return data; } void* OSI_queue_get_wait(tOSI_QUEUE_HANDLER queue) { void* ret; osi_lock(); if (!queue || queue->state != OSI_ALLOCATED) { OSI_loge("%s : queue is not allocated", __func__); return NULL; } ret = queue_get(queue); if (ret == NULL) { pthread_cond_wait(&queue->cond, &osi_info.mutex); ret = queue_get(queue); } osi_unlock(); return ret; } void OSI_queue_free(tOSI_QUEUE_HANDLER target) { if (target) { target->name = NULL; target->state = OSI_FREE; } } tOSI_QUEUE_HANDLER OSI_queue_get_handler(const char* name) { tOSI_QUEUE_HANDLER queue = NULL; int index; if (name == NULL) return NULL; osi_lock(); for (index = 0; index < OSI_MAX_QUEUE; index++) { if (osi_info.queue[index].name == NULL) continue; if (strcmp((char const*)osi_info.queue[index].name, (char const*)name) == 0) { queue = (tOSI_QUEUE_HANDLER)&osi_info.queue[index]; break; } } osi_unlock(); return queue; }