Helixis 1.0
Task Programming API
includes/hlx/task.h
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 **    #############################################################################
00029 **    # This implementation is based on the protothreads library by Adam Dunkels. #
00030 **    # For more information : http://www.sics.se/~adam/pt/                       #
00031 **    #                                                                           #
00032 **    # Thanks Adam to share your work with the community. We love you so much :) #
00033 **    #############################################################################
00034 */
00035 
00036 /*
00037  * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
00038  * All rights reserved.
00039  *
00040  * Redistribution and use in source and binary forms, with or without
00041  * modification, are permitted provided that the following conditions
00042  * are met:
00043  * 1. Redistributions of source code must retain the above copyright
00044  *    notice, this list of conditions and the following disclaimer.
00045  * 2. Redistributions in binary form must reproduce the above copyright
00046  *    notice, this list of conditions and the following disclaimer in the
00047  *    documentation and/or other materials provided with the distribution.
00048  * 3. Neither the name of the Institute nor the names of its contributors
00049  *    may be used to endorse or promote products derived from this software
00050  *    without specific prior written permission.
00051  *
00052  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00053  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00054  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00055  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00056  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00057  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00058  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00059  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00060  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00061  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00062  * SUCH DAMAGE.
00063  *
00064  * Author: Adam Dunkels <adam@sics.se>
00065  */
00066 
00067 #ifndef __HLX_TASK_H__
00068 # define __HLX_TASK_H__
00069 
00070 #ifdef __cplusplus
00071 extern "C"      {
00072 #endif
00073 
00074 /*
00075 ** TYPES
00076 */
00077 
00078 typedef unsigned short hlx_ctx; /* 16 bits task context */
00079 
00080 typedef int  (*hlx_task_func)(hlx_ctx*, hlx_group_id, void**, void *);
00081 
00082 typedef void (*hlx_task_callback)(void *, hlx_group_id, int);
00083 
00084 /* TASK STACK TRICKS */
00085 struct __empty_stack
00086 {
00087         unsigned short __size;
00088 };
00089 
00090 /*
00091 ** MACROS
00092 */
00093 
00094 /* TASK STATE */
00095 # define HLX_WAITING                    (0)
00096 # define HLX_YIELDED                    (1)
00097 # define HLX_EXITED                             (2)
00098 # define HLX_ENDED                              (3)
00099 # define HLX_MEMORY_EXHAUSTED   (4) /* Only occurs if the someone use the emulated stack */
00100 
00101 /*
00102 ** Lc switch implementation by Adam Dunkels with Helixis Microsoft compiler bug patch :
00103 ** http://support.microsoft.com/default.aspx?scid=kb;en-us;199057
00104 */
00105 #if defined(COMPILER_MSC)
00106 # define HLX_SET(s) s = __COUNTER__ + 1; case __COUNTER__:
00107 #else
00108 # define HLX_SET(s) s = __LINE__; case __LINE__:
00109 #endif
00110 
00111 /* TASK INIT */
00112 # define HLX_TASK_INIT()                                        *ctx = 0;
00113 
00114 /* TASK SCOPE */
00115 #define HLX_TASK_BEGIN() { char HLX_YIELD_FLAG = 1; switch(*ctx) { case 0:
00116 #define HLX_TASK_END() } HLX_YIELD_FLAG = 0; HLX_TASK_INIT(); return HLX_ENDED; }
00117 
00118 /* TASK EXIT */
00119 #define HLX_TASK_EXIT()                         \
00120   do {                                          \
00121     HLX_TASK_INIT();                            \
00122     return HLX_EXITED;                  \
00123   } while(0)
00124 
00125 /* TASK RESTART */
00126 #define HLX_TASK_RESTART()                                      \
00127   do {                                          \
00128     HLX_TASK_INIT();                            \
00129     return HLX_WAITING;                 \
00130   } while(0)
00131 
00132 /* TASK WAIT UNTIL */
00133 #define HLX_TASK_WAIT_UNTIL(condition)          \
00134   do {                                          \
00135     HLX_SET(*ctx);                              \
00136     if(!(condition)) {                          \
00137       return HLX_WAITING;                       \
00138     }                                           \
00139   } while(0)
00140 
00141 /* HLX TASK YIELD */
00142 #define HLX_TASK_YIELD()                                \
00143   do {                                          \
00144     HLX_YIELD_FLAG = 0;                         \
00145     HLX_SET(*ctx);                              \
00146     if(HLX_YIELD_FLAG == 0) {                   \
00147       return HLX_YIELDED;                       \
00148     }                                           \
00149   } while(0)
00150 
00151 /* TASK YIELD UNTIL */
00152 #define HLX_TASK_YIELD_UNTIL(cond)              \
00153   do {                                          \
00154     HLX_YIELD_FLAG = 0;                         \
00155     HLX_SET(*ctx);                              \
00156     if((HLX_YIELD_FLAG == 0) || !(cond)) {      \
00157       return HLX_YIELDED;                       \
00158     }                                           \
00159   } while(0)
00160 
00161 /* TASK WAIT WHILE */
00162 #define HLX_TASK_WAIT_WHILE(cond) HLX_TASK_WAIT_UNTIL(!(cond))
00163 
00164 /* TASK STACK */
00165 # define HLX_STACK(VARS)        struct __local { VARS unsigned short __size; };\
00166                                                 if (*__stack == 0 && sizeof(struct __local) > sizeof(struct __empty_stack)) \
00167                                                 { \
00168                                                         *__stack = hlx_api_entries()->malloc_entry(sizeof(struct __local)); \
00169                                                         if (!*__stack) return (-1); \
00170                                                         HLX_L(__size) = sizeof(struct __local); \
00171                                                 }
00172 # define HLX_L(VAR)             (((struct __local* )*__stack)->VAR)
00173 
00174 /* TASK PROTOTYPES */
00175 # define HLX_TASK(TASKNAME, PARAMETER)  int TASKNAME(hlx_ctx* ctx, hlx_group_id self_group_id, void* *__stack, PARAMETER)
00176 # define HLX_SIMPLE_TASK(TASKNAME)              HLX_TASK(TASKNAME, void* __unused_var__)
00177 
00178 /* ADD TASK */
00179 # define HLX_TASK_ADD(TASK, DATA)                                                                       hlx_core_add_task_callback(TASK, DATA, self_group_id, 0)
00180 # define HLX_TASK_ADD_IN_GROUP(TASK, DATA, GROUP)                                       hlx_core_add_task_in_group_callback(TASK, DATA, GROUP, self_group_id, 0)
00181 # define HLX_TASK_ADD_CALLBACK(TASK, DATA, CALLBACK)                                    hlx_core_add_task_callback(TASK, DATA, self_group_id, CALLBACK)
00182 # define HLX_TASK_ADD_IN_GROUP_CALLBACK(TASK, DATA, GROUP, CALLBACK)    hlx_core_add_task_in_group_callback(TASK, DATA, GROUP, self_group_id, CALLBACK)
00183 
00184 #ifdef __cplusplus
00185 }
00186 #endif
00187 
00188 #endif /* !__HLX_TASK_H__ */
00189 
00190 /*
00191 ** END OF FILE
00192 */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines