00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef CUFLOW_CONTINUATION_H
00019 #define CUFLOW_CONTINUATION_H
00020
00021 #include <stdlib.h>
00022 #include <setjmp.h>
00023 #include <cu/clos.h>
00024 #include <cuflow/fwd.h>
00025
00026 CU_BEGIN_DECLARATIONS
00027
00028
00029
00030
00031 typedef long cuflowP_stack_item_t;
00032
00033 typedef enum {
00034 cuflowP_cntn_kind_frame,
00035 cuflowP_cntn_kind_continuation,
00036 cuflowP_cntn_kind_catch
00037 } cuflowP_cntn_kind_t;
00038
00039 #define cuflowP_cntn_flag_invalid 1
00040 struct cuflow_continuation
00041 {
00042 unsigned int kind : 8;
00043 unsigned int flags : 8;
00044 cuflow_continuation_t up;
00045 cuflow_continuation_t down;
00046 jmp_buf door;
00047 int level;
00048 cuflowP_stack_item_t *ptr_stack_item;
00049 size_t stack_size;
00050 char * stack_data;
00051 cu_clop0(on_entry, void);
00052 cu_clop0(on_exit, void);
00053 cu_clop(on_xc, void, void *);
00054 };
00055
00056 #define cuflow_continuation_invalidate(cont) \
00057 (CU_MARG(cuflow_continuation_t, (cont))->flags |= cuflowP_cntn_flag_invalid)
00058 #define cuflow_continuation_is_valid(cont) \
00059 (!(CU_MARG(cuflow_continuation_t, (cont))->flags & cuflowP_cntn_flag_invalid))
00060
00061 #define cuflow_continuation_result_ptr(cont) \
00062 ((void*)(CU_MARG(cuflow_continuation_t, (cont)) + 1))
00063 #define CUFLOW_CONTINUATION_RESULT(cont, T) \
00064 (*(T*)(CU_MARG(cuflow_continuation_t, (cont)) + 1))
00065 #define CUFLOW_CONTINUATION_APPLY(cont, T, x) \
00066 (CUFLOW_CONTINUATION_RESULT((cont), T) = x, cuflow_continuation_call(cont))
00067 void cuflow_continuation_call(cuflow_continuation_t cont) CU_ATTR_NORETURN;
00068
00069 void cuflow_continuation_print_stats();
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 typedef enum {
00082 cuflow_mode_det,
00083 cuflow_mode_semidet,
00084 cuflow_mode_multi,
00085 cuflow_mode_nondet,
00086
00087 } cuflow_mode_t;
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 int cuflow_mode_allows_split_0(cuflow_mode_t);
00121 #define cuflow_mode_allows_split_0(flow) ((flow) & 1)
00122 int cuflow_mode_allows_split_gt_1(cuflow_mode_t);
00123 #define cuflow_mode_allows_split_gt_1(flow) ((flow) & 2)
00124
00125 cuflow_mode_t cuflow_mode_which_allows_split_0(cuflow_mode_t);
00126 #define cuflow_mode_which_allows_split_0(flow) ((cuflow_mode_t)((flow) | 1))
00127 cuflow_mode_t cuflow_mode_which_forbids_split_0(cuflow_mode_t);
00128 #define cuflow_mode_which_forbids_split_0(flow) ((cuflow_mode_t)((flow) & ~1))
00129
00130 cuflow_mode_t cuflow_mode_which_allows_split_gt_1(cuflow_mode_t);
00131 #define cuflow_mode_which_allows_split_gt_1(flow) ((cuflow_mode_t)((flow | 2)))
00132 cuflow_mode_t cuflow_mode_which_forbids_split_gt_1(cuflow_mode_t);
00133 #define cuflow_mode_which_forbids_split_gt_1(flow) ((cuflow_mode_t)((flow & ~2)))
00134
00135 char const *cuflow_mode_name(cuflow_mode_t);
00136
00137
00138 cuflow_mode_t cuflow_current_mode(void);
00139 #define cuflow_current_mode() ((cuflow_mode_t const)(cuflow_tstate())->flow)
00140
00141
00142
00143 void cuflow_set_current_mode(cuflow_mode_t newflow);
00144 #define cuflow_set_current_mode(newflow) ((void)(cuflow_tstate()->flow = (newflow)))
00145
00146
00147
00148
00149 void cuflow_set_save_current_flow(cuflow_mode_t newflow, cuflow_mode_t *oldflow);
00150 #ifndef CUCONF_ENABLE_THREADS
00151 #define cuflow_set_save_current_flow(newflow, oldflow) \
00152 (*(oldflow) = cuflow_current_mode(), cuflow_set_current_mode(newflow))
00153 #endif
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 void cuflow_call_in_root(cu_clop0(trunk, void), cuflow_mode_t trunk_flow);
00164
00165
00166
00167
00168 #define cu_call_in_frame(trunk, flow) \
00169 cuflow_dynamic_wind(cu_clop_null, (trunk), cu_clop_null, (flow))
00170
00171
00172 void cuflow_dynamic_wind(cu_clop0(on_entry, void),
00173 cu_clop0(trunk, void),
00174 cu_clop0(on_exit, void),
00175 cuflow_mode_t trunk_flow);
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 int
00189 cuflow_call_with_cc(
00190 cu_clop(trunk, int, cu_clop(cc, void, void *arg), void *res),
00191 void *result_ptr, size_t result_size);
00192
00193
00194
00195
00196
00197
00198
00199 int cuflow_set_cc(cu_clop(*cc_out, void, void *),
00200 void *result_ptr, size_t result_size);
00201
00202
00203
00204
00205
00206 void cuflow_catch(cu_clop0(trunk, void),
00207 cu_clop(on_xc, void, cu_ptr_t xc));
00208 void cuflow_throw(cu_ptr_t xc) CU_ATTR_NORETURN;
00209 void cuflow_uncaught(cu_clop(on_xc, void, void *));
00210
00211
00212
00213
00214
00215
00216 #define cuflow_for_catchers_next -1
00217 int cuflow_for_catchers(cu_clop(proc, int, cu_clop(, void, cu_ptr_t)));
00218
00219
00220
00221
00222
00223
00224 int cuflow_split(int n);
00225
00226
00227
00228
00229 #define cuflow_absorb() ((void)cuflow_split(0))
00230
00231
00232
00233 #define cuflow_mode_count() (cuflow_tstate()->flow_count)
00234
00235
00236
00237
00238
00239
00240 struct cuflow_tstate
00241 {
00242
00243 cuflow_continuation_t onstack_cont;
00244 cuflow_continuation_t split_cont;
00245 int flow_count;
00246 void *exception;
00247 cu_clop(uncaught_backtrace, void, void *);
00248 int opt_uncaught_backtrace;
00249 cuflow_mode_t flow;
00250 };
00251
00252 #ifdef CUCONF_ENABLE_THREADS
00253 cuflow_tstate_t cuflow_tstate();
00254 #else
00255 extern struct cuflow_tstate _ccf_the_state;
00256 #define cuflow_tstate() (&_ccf_the_state)
00257 #endif
00258
00259 #define cuflow_tstate_current_flow(st) (CU_MARG(cuflow_tstate_t, (st))->flow)
00260 #define cuflow_tstate_set_current_flow(st, newflow) \
00261 ((void)(CU_MARG(cuflow_tstate_t, (st))->flow = (newflow)))
00262 void cuflow_tstate_save_current_flow(cuflow_tstate_t st, cuflow_mode_t newflow,
00263 cuflow_mode_t *oldflow);
00264
00265 CU_END_DECLARATIONS
00266
00267 #endif