You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
250 lines
6.2 KiB
250 lines
6.2 KiB
/*
|
|
* 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;
|
|
}
|