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 <signal.h>
24 #include <string.h>
25 #include "osi.h"
26 
27 /************************************************************************
28 ** Internal function prototype
29 *************************************************************************/
30 
31 /************************************************************************
32 ** Public functions
33 *************************************************************************/
osi_task_entry(void * arg)34 void osi_task_entry(void* arg) {
35   tOSI_TASK_ENTRY task_entry = (tOSI_TASK_ENTRY)arg;
36 
37   // pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
38 
39   task_entry();
40   OSI_logt("%s : exit task", __func__);
41 
42   pthread_exit(NULL);
43 }
44 
OSI_task_allocate(const char * task_name,tOSI_TASK_ENTRY task_entry)45 tOSI_TASK_HANDLER OSI_task_allocate(const char* task_name,
46                                     tOSI_TASK_ENTRY task_entry) {
47   tOSI_TASK_HANDLER free_task = NULL;
48   int index;
49 
50   /* Find free task */
51   osi_lock();
52   for (index = 0; index < OSI_MAX_TASK; index++) {
53     if (osi_info.task[index].state == OSI_FREE) {
54       if (free_task == NULL)
55         free_task = (tOSI_TASK_HANDLER)&osi_info.task[index];
56     } else {
57       if (osi_info.task[index].name == NULL) continue;
58 
59       /* User can't not make same name of task */
60       if (strcmp((char const*)osi_info.task[index].name,
61                  (char const*)task_name) == 0) {
62         OSI_loge("%s : %s task is already allocated [%d]", __func__, task_name,
63                  index);
64         free_task = NULL;
65         break;
66       }
67     }
68   }
69 
70   if (free_task == NULL) {
71     OSI_loge("%s : Failed to find free task(max: %d)", __func__, OSI_MAX_TASK);
72   } else {
73     free_task->state = OSI_ALLOCATED;
74     free_task->name = task_name;
75     free_task->task_entry = task_entry;
76   }
77 
78   osi_unlock();
79   return free_task;
80 }
OSI_task_run(tOSI_TASK_HANDLER task_handler)81 OSI_STATE OSI_task_run(tOSI_TASK_HANDLER task_handler) {
82   pthread_attr_t attr;
83   int ret = OSI_FAIL;
84 
85   osi_lock();
86   if (!task_handler) {
87     OSI_loge("%s : task handler is not exist!!", __func__);
88   } else if (task_handler->state != OSI_ALLOCATED) {
89     OSI_loge("%s : task state is not ALLOCATED!! (%d)", __func__,
90              task_handler->state);
91   } else {
92     /* Thread attr configuration */
93     pthread_attr_init(&attr);
94     if (!pthread_create(&(task_handler->task), &attr,
95                         (void* (*)(void*))osi_task_entry,
96                         (void*)(task_handler->task_entry))) {  //
97       task_handler->state = OSI_RUN;
98       ret = OSI_OK;
99     } else {
100       OSI_loge("%s : pthread_create failed(%d), %s", __func__, ret,
101                task_handler->name);
102     }
103     pthread_attr_destroy(&attr);
104   }
105 
106   osi_unlock();
107   return ret;
108 }
109 
OSI_task_isRun(tOSI_TASK_HANDLER task_handler)110 OSI_STATE OSI_task_isRun(tOSI_TASK_HANDLER task_handler) {
111   OSI_STATE ret = OSI_FAIL;
112   osi_lock();
113   if (task_handler && task_handler->state == OSI_RUN) ret = OSI_RUN;
114   osi_unlock();
115   return ret;
116 }
117 
OSI_task_stop(tOSI_TASK_HANDLER task_handler)118 OSI_STATE OSI_task_stop(tOSI_TASK_HANDLER task_handler) {
119   OSI_STATE ret = OSI_OK;
120   if (!task_handler) return OSI_OK;
121 
122   osi_lock();
123   if (task_handler->state == OSI_RUN) {
124     osi_unlock();
125     // ret = pthread_cancel(task_handler->task);
126     ret = (OSI_STATE)pthread_join(task_handler->task, NULL);
127     osi_lock();
128   }
129 
130   task_handler->state = OSI_ALLOCATED;
131   osi_unlock();
132 
133   return ret;
134 }
135 
OSI_task_free(tOSI_TASK_HANDLER task_handler)136 OSI_STATE OSI_task_free(tOSI_TASK_HANDLER task_handler) {
137   OSI_STATE ret = OSI_OK;
138 
139   OSI_task_stop(task_handler);
140   osi_lock();
141   task_handler->name = NULL;
142   task_handler->state = OSI_FREE;
143   osi_unlock();
144 
145   return ret;
146 }
147 
OSI_task_kill(tOSI_TASK_HANDLER task_handler)148 OSI_STATE OSI_task_kill(tOSI_TASK_HANDLER task_handler) {
149   OSI_STATE ret = OSI_OK;
150   if (!task_handler) return OSI_OK;
151 
152   osi_lock();
153   if (task_handler->state == OSI_RUN) {
154     osi_unlock();
155     // ret = pthread_cancel(task_handler->task);
156     ret = (OSI_STATE)pthread_join(task_handler->task, NULL);
157     osi_lock();
158   }
159 
160   task_handler->name = NULL;
161   task_handler->state = OSI_FREE;
162   osi_unlock();
163 
164   return ret;
165 }
166 
OSI_task_get_handler(char * name)167 tOSI_TASK_HANDLER OSI_task_get_handler(char* name) {
168   tOSI_TASK_HANDLER task = NULL;
169   int index;
170 
171   if (!name) return NULL;
172 
173   osi_lock();
174   for (index = 0; index < OSI_MAX_TASK; index++) {
175     if ((char const*)osi_info.task[index].name == NULL) continue;
176 
177     if (strcmp((char const*)osi_info.task[index].name, (char const*)name) ==
178         0) {
179       task = &osi_info.task[index];
180       break;
181     }
182   }
183   osi_unlock();
184 
185   return task;
186 }
187