Helixis 1.0
Task Programming API
sources/sched.c
Go to the documentation of this file.
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 */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines