00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef CUFLOW_EXEQ_H
00019 #define CUFLOW_EXEQ_H
00020
00021 #include <cuflow/fwd.h>
00022 #include <cuflow/tstate.h>
00023 #include <cuflow/cdisj.h>
00024 #include <cu/clos.h>
00025 #include <cu/thread.h>
00026 #include <atomic_ops.h>
00027
00028 CU_BEGIN_DECLARATIONS
00029
00030 void cuflowP_sched_call(cuflow_exeq_t exeq, cu_clop0(f, void), AO_t *cdisj);
00031 void cuflowP_sched_call_sub1(cuflow_exeq_t exeq, cu_clop0(f, void),
00032 AO_t *cdisj);
00033
00034 #if CUFLOW_PROFILE_SCHED
00035 extern AO_t cuflowP_profile_sched_count;
00036 extern AO_t cuflowP_profile_nonsched_count;
00037 #endif
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 CU_SINLINE cuflow_exeqpri_t
00052 cuflow_sched_priority(void)
00053 {
00054 return cuflow_tstate()->exeqpri;
00055 }
00056
00057
00058
00059 CU_SINLINE cuflow_exeqpri_t
00060 cuflow_sched_change_priority(cuflow_exeqpri_t priority)
00061 {
00062 cuflow_tstate_t tstate = cuflow_tstate();
00063 cuflow_exeqpri_t old_priority = tstate->exeqpri;
00064 tstate->exeqpri = priority;
00065 return old_priority;
00066 }
00067
00068
00069 CU_SINLINE cuflow_exeq_t
00070 cuflow_sched_exeq(void)
00071 {
00072 cuflow_tstate_t tstate = cuflow_tstate();
00073 return &tstate->exeq[tstate->exeqpri];
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 CU_SINLINE void
00086 cuflow_sched_call_on(cu_clop0(f, void), AO_t *cdisj, cuflow_exeq_t exeq)
00087 {
00088 #if CUFLOW_CALLS_BETWEEN_SCHED > 1
00089 if (cu_expect(!--exeq->calls_till_sched, 0)) {
00090 exeq->calls_till_sched = CUFLOW_CALLS_BETWEEN_SCHED;
00091 #endif
00092 if (cu_expect_false(exeq->head != AO_load(&exeq->tail))) {
00093 cuflowP_sched_call(exeq, f, cdisj);
00094 return;
00095 }
00096 #if CUFLOW_CALLS_BETWEEN_SCHED > 1
00097 }
00098 #endif
00099 #if CUFLOW_PROFILE_SCHED
00100 AO_fetch_and_add1(&cuflowP_profile_nonsched_count);
00101 #endif
00102 cu_call0(f);
00103 }
00104
00105
00106
00107 void cuflow_sched_call_at(cu_clop0(f, void), AO_t *cdisj,
00108 cuflow_exeqpri_t pri);
00109
00110
00111
00112 CU_SINLINE void
00113 cuflow_sched_call(cu_clop0(f, void), AO_t *cdisj)
00114 {
00115 cuflow_sched_call_on(f, cdisj, cuflow_tstate_exeq(cuflow_tstate()));
00116 }
00117
00118
00119
00120
00121 CU_SINLINE void
00122 cuflow_sched_call_sub1_on(cu_clop0(f, void), AO_t *cdisj, cuflow_exeq_t exeq)
00123 {
00124 #if CUFLOW_CALLS_BETWEEN_SCHED > 1
00125 if (cu_expect(!--exeq->calls_till_sched, 0)) {
00126 exeq->calls_till_sched = CUFLOW_CALLS_BETWEEN_SCHED;
00127 #endif
00128 if (cu_expect_false(exeq->head != AO_load(&exeq->tail))) {
00129 cuflowP_sched_call_sub1(exeq, f, cdisj);
00130 return;
00131 }
00132 #if CUFLOW_CALLS_BETWEEN_SCHED > 1
00133 }
00134 #endif
00135 #if CUFLOW_PROFILE_SCHED
00136 AO_fetch_and_add1(&cuflowP_profile_nonsched_count);
00137 #endif
00138 cu_call0(f);
00139 cuflow_cdisj_sub1_release_write(cdisj);
00140 }
00141
00142
00143
00144 void cuflow_sched_call_sub1_at(cu_clop0(f, void), AO_t *cdisj,
00145 cuflow_exeqpri_t pri);
00146
00147
00148
00149 CU_SINLINE void
00150 cuflow_sched_call_sub1(cu_clop0(f, void), AO_t *cdisj)
00151 {
00152 cuflow_sched_call_sub1_on(f, cdisj, cuflow_tstate_exeq(cuflow_tstate()));
00153 }
00154
00155
00156 CU_END_DECLARATIONS
00157
00158 #endif