diff options
Diffstat (limited to 'halimpl/osi/osi_task.cc')
-rw-r--r-- | halimpl/osi/osi_task.cc | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/halimpl/osi/osi_task.cc b/halimpl/osi/osi_task.cc new file mode 100644 index 0000000..9174b0e --- /dev/null +++ b/halimpl/osi/osi_task.cc @@ -0,0 +1,186 @@ +/* + * 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 <signal.h> +#include <string.h> +#include "osi.h" + +/************************************************************************ +** Internal function prototype +*************************************************************************/ + +/************************************************************************ +** Public functions +*************************************************************************/ +void osi_task_entry(void* arg) { + tOSI_TASK_ENTRY task_entry = (tOSI_TASK_ENTRY)arg; + + // pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + + task_entry(); + OSI_logt("%s : exit task", __func__); + + pthread_exit(NULL); +} + +tOSI_TASK_HANDLER OSI_task_allocate(const char* task_name, + tOSI_TASK_ENTRY task_entry) { + tOSI_TASK_HANDLER free_task = NULL; + int index; + + /* Find free task */ + osi_lock(); + for (index = 0; index < OSI_MAX_TASK; index++) { + if (osi_info.task[index].state == OSI_FREE) { + if (free_task == NULL) + free_task = (tOSI_TASK_HANDLER)&osi_info.task[index]; + } else { + if (osi_info.task[index].name == NULL) continue; + + /* User can't not make same name of task */ + if (strcmp((char const*)osi_info.task[index].name, + (char const*)task_name) == 0) { + OSI_loge("%s : %s task is already allocated [%d]", __func__, task_name, + index); + free_task = NULL; + break; + } + } + } + + if (free_task == NULL) { + OSI_loge("%s : Failed to find free task(max: %d)", __func__, OSI_MAX_TASK); + } else { + free_task->state = OSI_ALLOCATED; + free_task->name = task_name; + free_task->task_entry = task_entry; + } + + osi_unlock(); + return free_task; +} +OSI_STATE OSI_task_run(tOSI_TASK_HANDLER task_handler) { + pthread_attr_t attr; + int ret = OSI_FAIL; + + osi_lock(); + if (!task_handler) { + OSI_loge("%s : task handler is not exist!!", __func__); + } else if (task_handler->state != OSI_ALLOCATED) { + OSI_loge("%s : task state is not ALLOCATED!! (%d)", __func__, + task_handler->state); + } else { + /* Thread attr configuration */ + pthread_attr_init(&attr); + if (!pthread_create(&(task_handler->task), &attr, + (void* (*)(void*))osi_task_entry, + (void*)(task_handler->task_entry))) { // + task_handler->state = OSI_RUN; + ret = OSI_OK; + } else { + OSI_loge("%s : pthread_create failed(%d), %s", __func__, ret, + task_handler->name); + } + pthread_attr_destroy(&attr); + } + + osi_unlock(); + return ret; +} + +OSI_STATE OSI_task_isRun(tOSI_TASK_HANDLER task_handler) { + OSI_STATE ret = OSI_FAIL; + osi_lock(); + if (task_handler && task_handler->state == OSI_RUN) ret = OSI_RUN; + osi_unlock(); + return ret; +} + +OSI_STATE OSI_task_stop(tOSI_TASK_HANDLER task_handler) { + OSI_STATE ret = OSI_OK; + if (!task_handler) return OSI_OK; + + osi_lock(); + if (task_handler->state == OSI_RUN) { + osi_unlock(); + // ret = pthread_cancel(task_handler->task); + ret = (OSI_STATE)pthread_join(task_handler->task, NULL); + osi_lock(); + } + + task_handler->state = OSI_ALLOCATED; + osi_unlock(); + + return ret; +} + +OSI_STATE OSI_task_free(tOSI_TASK_HANDLER task_handler) { + OSI_STATE ret = OSI_OK; + + OSI_task_stop(task_handler); + osi_lock(); + task_handler->name = NULL; + task_handler->state = OSI_FREE; + osi_unlock(); + + return ret; +} + +OSI_STATE OSI_task_kill(tOSI_TASK_HANDLER task_handler) { + OSI_STATE ret = OSI_OK; + if (!task_handler) return OSI_OK; + + osi_lock(); + if (task_handler->state == OSI_RUN) { + osi_unlock(); + // ret = pthread_cancel(task_handler->task); + ret = (OSI_STATE)pthread_join(task_handler->task, NULL); + osi_lock(); + } + + task_handler->name = NULL; + task_handler->state = OSI_FREE; + osi_unlock(); + + return ret; +} + +tOSI_TASK_HANDLER OSI_task_get_handler(char* name) { + tOSI_TASK_HANDLER task = NULL; + int index; + + if (!name) return NULL; + + osi_lock(); + for (index = 0; index < OSI_MAX_TASK; index++) { + if ((char const*)osi_info.task[index].name == NULL) continue; + + if (strcmp((char const*)osi_info.task[index].name, (char const*)name) == + 0) { + task = &osi_info.task[index]; + break; + } + } + osi_unlock(); + + return task; +} |