… | |
… | |
93 | |
93 | |
94 | #define IN_DESTRUCT (PL_main_cv == Nullcv) |
94 | #define IN_DESTRUCT (PL_main_cv == Nullcv) |
95 | |
95 | |
96 | #if __GNUC__ >= 3 |
96 | #if __GNUC__ >= 3 |
97 | # define attribute(x) __attribute__(x) |
97 | # define attribute(x) __attribute__(x) |
|
|
98 | # define BARRIER __asm__ __volatile__ ("" : : : "memory") |
98 | #else |
99 | #else |
99 | # define attribute(x) |
100 | # define attribute(x) |
|
|
101 | # define BARRIER |
100 | #endif |
102 | #endif |
101 | |
103 | |
102 | #define NOINLINE attribute ((noinline)) |
104 | #define NOINLINE attribute ((noinline)) |
103 | |
105 | |
104 | #include "CoroAPI.h" |
106 | #include "CoroAPI.h" |
… | |
… | |
1024 | |
1026 | |
1025 | static void |
1027 | static void |
1026 | prepare_cede (struct transfer_args *ta) |
1028 | prepare_cede (struct transfer_args *ta) |
1027 | { |
1029 | { |
1028 | api_ready (coro_current); |
1030 | api_ready (coro_current); |
1029 | |
|
|
1030 | prepare_schedule (ta); |
1031 | prepare_schedule (ta); |
|
|
1032 | } |
|
|
1033 | |
|
|
1034 | static int |
|
|
1035 | prepare_cede_notself (struct transfer_args *ta) |
|
|
1036 | { |
|
|
1037 | if (coro_nready) |
|
|
1038 | { |
|
|
1039 | SV *prev = SvRV (coro_current); |
|
|
1040 | prepare_schedule (ta); |
|
|
1041 | api_ready (prev); |
|
|
1042 | return 1; |
|
|
1043 | } |
|
|
1044 | else |
|
|
1045 | return 0; |
1031 | } |
1046 | } |
1032 | |
1047 | |
1033 | static void |
1048 | static void |
1034 | api_schedule (void) |
1049 | api_schedule (void) |
1035 | { |
1050 | { |
… | |
… | |
1037 | |
1052 | |
1038 | prepare_schedule (&ta); |
1053 | prepare_schedule (&ta); |
1039 | TRANSFER (ta); |
1054 | TRANSFER (ta); |
1040 | } |
1055 | } |
1041 | |
1056 | |
1042 | static void |
1057 | static int |
1043 | api_cede (void) |
1058 | api_cede (void) |
1044 | { |
1059 | { |
1045 | struct transfer_args ta; |
1060 | struct transfer_args ta; |
1046 | |
1061 | |
1047 | prepare_cede (&ta); |
1062 | prepare_cede (&ta); |
|
|
1063 | |
|
|
1064 | if (ta.prev != ta.next) |
|
|
1065 | { |
1048 | TRANSFER (ta); |
1066 | TRANSFER (ta); |
|
|
1067 | return 1; |
|
|
1068 | } |
|
|
1069 | else |
|
|
1070 | return 0; |
|
|
1071 | } |
|
|
1072 | |
|
|
1073 | static int |
|
|
1074 | api_cede_notself (void) |
|
|
1075 | { |
|
|
1076 | struct transfer_args ta; |
|
|
1077 | |
|
|
1078 | if (prepare_cede_notself (&ta)) |
|
|
1079 | { |
|
|
1080 | TRANSFER (ta); |
|
|
1081 | return 1; |
|
|
1082 | } |
|
|
1083 | else |
|
|
1084 | return 0; |
1049 | } |
1085 | } |
1050 | |
1086 | |
1051 | MODULE = Coro::State PACKAGE = Coro::State |
1087 | MODULE = Coro::State PACKAGE = Coro::State |
1052 | |
1088 | |
1053 | PROTOTYPES: DISABLE |
1089 | PROTOTYPES: DISABLE |
… | |
… | |
1109 | _set_stacklevel (...) |
1145 | _set_stacklevel (...) |
1110 | ALIAS: |
1146 | ALIAS: |
1111 | Coro::State::transfer = 1 |
1147 | Coro::State::transfer = 1 |
1112 | Coro::schedule = 2 |
1148 | Coro::schedule = 2 |
1113 | Coro::cede = 3 |
1149 | Coro::cede = 3 |
|
|
1150 | Coro::cede_notself = 4 |
1114 | CODE: |
1151 | CODE: |
1115 | { |
1152 | { |
1116 | struct transfer_args ta; |
1153 | struct transfer_args ta; |
1117 | |
1154 | |
1118 | switch (ix) |
1155 | switch (ix) |
… | |
… | |
1134 | break; |
1171 | break; |
1135 | |
1172 | |
1136 | case 3: |
1173 | case 3: |
1137 | prepare_cede (&ta); |
1174 | prepare_cede (&ta); |
1138 | break; |
1175 | break; |
|
|
1176 | |
|
|
1177 | case 4: |
|
|
1178 | if (!prepare_cede_notself (&ta)) |
|
|
1179 | XSRETURN_EMPTY; |
|
|
1180 | |
|
|
1181 | break; |
1139 | } |
1182 | } |
1140 | |
1183 | |
|
|
1184 | BARRIER; |
1141 | TRANSFER (ta); |
1185 | TRANSFER (ta); |
1142 | } |
1186 | } |
1143 | |
1187 | |
1144 | void |
1188 | void |
1145 | _clone_state_from (SV *dst, SV *src) |
1189 | _clone_state_from (SV *dst, SV *src) |
… | |
… | |
1196 | coro_ready[i] = newAV (); |
1240 | coro_ready[i] = newAV (); |
1197 | |
1241 | |
1198 | { |
1242 | { |
1199 | SV *sv = perl_get_sv("Coro::API", 1); |
1243 | SV *sv = perl_get_sv("Coro::API", 1); |
1200 | |
1244 | |
1201 | coroapi.schedule = api_schedule; |
1245 | coroapi.schedule = api_schedule; |
1202 | coroapi.save = api_save; |
1246 | coroapi.save = api_save; |
1203 | coroapi.cede = api_cede; |
1247 | coroapi.cede = api_cede; |
|
|
1248 | coroapi.cede_notself = api_cede_notself; |
1204 | coroapi.ready = api_ready; |
1249 | coroapi.ready = api_ready; |
1205 | coroapi.is_ready = api_is_ready; |
1250 | coroapi.is_ready = api_is_ready; |
1206 | coroapi.nready = &coro_nready; |
1251 | coroapi.nready = &coro_nready; |
1207 | coroapi.current = coro_current; |
1252 | coroapi.current = coro_current; |
1208 | |
1253 | |
1209 | GCoroAPI = &coroapi; |
1254 | GCoroAPI = &coroapi; |
1210 | sv_setiv (sv, (IV)&coroapi); |
1255 | sv_setiv (sv, (IV)&coroapi); |
1211 | SvREADONLY_on (sv); |
1256 | SvREADONLY_on (sv); |
1212 | } |
1257 | } |