… | |
… | |
1097 | |
1097 | |
1098 | static coro_cctx * |
1098 | static coro_cctx * |
1099 | cctx_new () |
1099 | cctx_new () |
1100 | { |
1100 | { |
1101 | coro_cctx *cctx; |
1101 | coro_cctx *cctx; |
|
|
1102 | |
|
|
1103 | ++cctx_count; |
|
|
1104 | New (0, cctx, 1, coro_cctx); |
|
|
1105 | |
|
|
1106 | cctx->gen = cctx_gen; |
|
|
1107 | cctx->flags = 0; |
|
|
1108 | |
|
|
1109 | return cctx; |
|
|
1110 | } |
|
|
1111 | |
|
|
1112 | /* create a new cctx only suitable as source */ |
|
|
1113 | static coro_cctx * |
|
|
1114 | cctx_new_empty () |
|
|
1115 | { |
|
|
1116 | coro_cctx *cctx = cctx_new (); |
|
|
1117 | |
|
|
1118 | cctx->sptr = 0; |
|
|
1119 | cctx->idle_sp = 0; /* should never be a valid address */ |
|
|
1120 | coro_create (&cctx->cctx, 0, 0, 0, 0); |
|
|
1121 | |
|
|
1122 | return cctx; |
|
|
1123 | } |
|
|
1124 | |
|
|
1125 | /* create a new cctx suitable as destination/running a perl interpreter */ |
|
|
1126 | static coro_cctx * |
|
|
1127 | cctx_new_run () |
|
|
1128 | { |
|
|
1129 | coro_cctx *cctx = cctx_new (); |
1102 | void *stack_start; |
1130 | void *stack_start; |
1103 | size_t stack_size; |
1131 | size_t stack_size; |
1104 | |
|
|
1105 | ++cctx_count; |
|
|
1106 | Newz (0, cctx, 1, coro_cctx); |
|
|
1107 | |
|
|
1108 | cctx->gen = cctx_gen; |
|
|
1109 | |
1132 | |
1110 | #if HAVE_MMAP |
1133 | #if HAVE_MMAP |
1111 | cctx->ssize = ((cctx_stacksize * sizeof (long) + PAGESIZE - 1) / PAGESIZE + CORO_STACKGUARD) * PAGESIZE; |
1134 | cctx->ssize = ((cctx_stacksize * sizeof (long) + PAGESIZE - 1) / PAGESIZE + CORO_STACKGUARD) * PAGESIZE; |
1112 | /* mmap supposedly does allocate-on-write for us */ |
1135 | /* mmap supposedly does allocate-on-write for us */ |
1113 | cctx->sptr = mmap (0, cctx->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); |
1136 | cctx->sptr = mmap (0, cctx->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); |
… | |
… | |
1186 | return cctx; |
1209 | return cctx; |
1187 | |
1210 | |
1188 | cctx_destroy (cctx); |
1211 | cctx_destroy (cctx); |
1189 | } |
1212 | } |
1190 | |
1213 | |
1191 | return cctx_new (); |
1214 | return cctx_new_run (); |
1192 | } |
1215 | } |
1193 | |
1216 | |
1194 | static void |
1217 | static void |
1195 | cctx_put (coro_cctx *cctx) |
1218 | cctx_put (coro_cctx *cctx) |
1196 | { |
1219 | { |
… | |
… | |
1252 | coro_cctx *prev__cctx; |
1275 | coro_cctx *prev__cctx; |
1253 | |
1276 | |
1254 | if (expect_false (prev->flags & CF_NEW)) |
1277 | if (expect_false (prev->flags & CF_NEW)) |
1255 | { |
1278 | { |
1256 | /* create a new empty/source context */ |
1279 | /* create a new empty/source context */ |
1257 | ++cctx_count; |
1280 | prev->cctx = cctx_new_empty (); |
1258 | New (0, prev->cctx, 1, coro_cctx); |
|
|
1259 | prev->cctx->sptr = 0; |
|
|
1260 | coro_create (&prev->cctx->cctx, 0, 0, 0, 0); |
|
|
1261 | |
|
|
1262 | prev->flags &= ~CF_NEW; |
1281 | prev->flags &= ~CF_NEW; |
1263 | prev->flags |= CF_RUNNING; |
1282 | prev->flags |= CF_RUNNING; |
1264 | } |
1283 | } |
1265 | |
1284 | |
1266 | prev->flags &= ~CF_RUNNING; |
1285 | prev->flags &= ~CF_RUNNING; |
… | |
… | |
1654 | struct coro *coro = SvSTATE (coro_sv); |
1673 | struct coro *coro = SvSTATE (coro_sv); |
1655 | |
1674 | |
1656 | if (flags & CC_TRACE) |
1675 | if (flags & CC_TRACE) |
1657 | { |
1676 | { |
1658 | if (!coro->cctx) |
1677 | if (!coro->cctx) |
1659 | coro->cctx = cctx_new (); |
1678 | coro->cctx = cctx_new_run (); |
1660 | else if (!(coro->cctx->flags & CC_TRACE)) |
1679 | else if (!(coro->cctx->flags & CC_TRACE)) |
1661 | croak ("cannot enable tracing on coroutine with custom stack"); |
1680 | croak ("cannot enable tracing on coroutine with custom stack"); |
1662 | |
1681 | |
1663 | coro->cctx->flags |= CC_NOREUSE | (flags & (CC_TRACE | CC_TRACE_ALL)); |
1682 | coro->cctx->flags |= CC_NOREUSE | (flags & (CC_TRACE | CC_TRACE_ALL)); |
1664 | } |
1683 | } |