blob: 434afd7011273f2531a99d858a5d6ab91e742d4e [file] [log] [blame]
/*
* 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 <pthread.h>
#include <sched.h>
#include <string.h>
#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;
}