![]() |
Helixis 1.0
Task Programming API
|
00001 /* 00002 ** Copyright 2009-2011, helixis.org 00003 ** All rights reserved. 00004 ** 00005 ** Redistribution and use in source and binary forms, with or without modification, are permitted provided 00006 ** that the following conditions are met: 00007 ** 00008 ** Redistributions of source code must retain the above copyright notice, this list of conditions and the 00009 ** following disclaimer. 00010 ** 00011 ** Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 00012 ** the following disclaimer in the documentation and/or other materials provided with the distribution. 00013 ** 00014 ** Neither the name of the helixis.org nor the names of its contributors may be used to endorse or promote 00015 ** products derived from this software without specific prior written permission. 00016 ** 00017 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 00018 ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00019 ** PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00020 ** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00021 ** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00022 ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00023 ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00024 ** POSSIBILITY OF SUCH DAMAGE. 00025 */ 00026 00027 /* 00028 ** INCLUDES 00029 */ 00030 00031 #include "hlx/core.h" 00032 #include "helixis_internal.h" 00033 00034 #ifdef __cplusplus 00035 extern "C" { 00036 #endif 00037 00038 /* 00039 ** EXTERNALS 00040 */ 00041 00042 extern hlx_api gl_api; 00043 extern hlx_scheduler gl_scheduler; 00044 00045 /* 00046 ** FUNCTIONS 00047 */ 00048 00049 void hlx_scheduler_construct(void) 00050 { 00051 unsigned int i; 00052 hlx_group* group; 00053 00054 gl_scheduler.loop = 0; 00055 #if defined(HLX_BUILD_WITH_PARALLEL_THREADING) 00056 gl_scheduler.launched = 0; 00057 #endif 00058 if (gl_api.get_cpu_count_entry != 0) 00059 { 00060 gl_scheduler.cpu_count = gl_api.get_cpu_count_entry(); 00061 if (gl_scheduler.cpu_count < 1) 00062 gl_scheduler.cpu_count = 1; 00063 } 00064 else 00065 gl_scheduler.cpu_count = 1; 00066 hlx_list_construct(&gl_scheduler.groups); 00067 gl_scheduler.default_groups_id = gl_api.malloc_entry(gl_scheduler.cpu_count * sizeof(*(gl_scheduler.default_groups_id))); 00068 if (!gl_scheduler.default_groups_id) 00069 return; 00070 for (i = 0; i < gl_scheduler.cpu_count; ++i) 00071 { 00072 group = gl_api.malloc_entry(sizeof(*group)); 00073 hlx_group_construct(group); 00074 hlx_list_push_back(&gl_scheduler.groups, group); 00075 gl_scheduler.default_groups_id[i] = (hlx_group_id)group; 00076 } 00077 } 00078 00079 void hlx_scheduler_destruct(void) 00080 { 00081 hlx_list_node* it; 00082 00083 for (it = gl_scheduler.groups.first; it != 0; it = it->next) 00084 { 00085 hlx_group_destruct(it->data); 00086 gl_api.free_entry(it->data); 00087 } 00088 hlx_list_clear(&gl_scheduler.groups); 00089 gl_api.free_entry(gl_scheduler.default_groups_id); 00090 hlx_event_manager_destroy(hlx_event_get_default_manager()); 00091 } 00092 00093 hlx_group_id hlx_core_create_group(void) 00094 { 00095 hlx_group* g; 00096 00097 if ((g = gl_api.malloc_entry(sizeof(*g))) == 0) 00098 return ((hlx_group_id)-1); 00099 hlx_group_construct(g); 00100 hlx_list_push_back(&gl_scheduler.groups, g); 00101 return (g->id); 00102 } 00103 00104 hlx_group* hlx_sheduler_find_lighter_group(void) 00105 { 00106 unsigned int i; 00107 unsigned int best_size; 00108 unsigned int group_size; 00109 hlx_group* best; 00110 hlx_group* group; 00111 00112 best_size = 0; 00113 group_size = 0; 00114 best = 0; 00115 group = 0; 00116 for (i = 0; i < gl_scheduler.cpu_count; ++i) 00117 { 00118 group = (hlx_group*)(gl_scheduler.default_groups_id[i]); 00119 group_size = hlx_group_get_size(group); 00120 if (best == 0 || best_size > group_size) 00121 { 00122 best = group; 00123 best_size = group_size; 00124 } 00125 } 00126 return (group); 00127 } 00128 00129 void hlx_core_add_task_in_group(hlx_task_func task_func, void* data, hlx_group_id group_id) 00130 { 00131 hlx_core_add_task_in_group_callback(task_func, data, group_id, 0, 0); 00132 } 00133 00134 void hlx_core_add_task(hlx_task_func task_func, void* data) 00135 { 00136 hlx_core_add_task_in_group_callback(task_func, data, hlx_sheduler_find_lighter_group()->id, 0, 0); 00137 } 00138 00139 hlx_task* hlx_scheduler_init_task(hlx_task_func task_func, void* data, hlx_group* group, hlx_task_callback callback) 00140 { 00141 hlx_task* task; 00142 00143 task = gl_api.malloc_entry(sizeof (*task)); 00144 if (!task) 00145 return (0); 00146 task->status = HLX_TASK_STATUS_RUN; 00147 task->task_func = task_func; 00148 task->data = data; 00149 task->stack = 0; 00150 task->group_id = group->id; 00151 task->callback = callback; 00152 task->ctx = 0; 00153 return (task); 00154 } 00155 00156 int hlx_scheduler_schedule_group(hlx_group* group) 00157 { 00158 hlx_list_node* it; 00159 hlx_list_node* tmp; 00160 hlx_task* task; 00161 int loop; 00162 int ret; 00163 00164 loop = 0; 00165 it = group->tasks.first; 00166 while (it) 00167 { 00168 task = it->data; 00169 if (task->status != HLX_TASK_STATUS_RUN) 00170 { 00171 it = it->next; 00172 continue; 00173 } 00174 if (!task->task_func) 00175 ret = HLX_EXITED; 00176 else 00177 ret = task->task_func(&(task->ctx), task->group_id, &(task->stack), task->data); 00178 if (ret == HLX_ENDED || ret == HLX_EXITED || ret == HLX_MEMORY_EXHAUSTED) 00179 { 00180 if (task->callback != 0) 00181 task->callback(task->data, task->group_id, ret); 00182 if (task->stack != 0) 00183 gl_api.free_entry(task->stack); 00184 gl_api.free_entry(task); 00185 tmp = it->next; 00186 hlx_list_erase(&group->tasks, it); 00187 it = tmp; 00188 } 00189 else 00190 { 00191 loop = 1; 00192 it = it->next; 00193 } 00194 } 00195 return (loop); 00196 } 00197 00198 #ifdef __cplusplus 00199 } 00200 #endif 00201 00202 /* 00203 ** END OF FILE 00204 */