… | |
… | |
97 | # if CORO_PTHREAD |
97 | # if CORO_PTHREAD |
98 | static void *coro_thx; |
98 | static void *coro_thx; |
99 | # endif |
99 | # endif |
100 | #endif |
100 | #endif |
101 | |
101 | |
|
|
102 | /* used in state.h */ |
|
|
103 | #define VAR(name,type) VARx(name, PL_ ## name, type) |
|
|
104 | |
102 | #ifdef __linux |
105 | #ifdef __linux |
103 | # include <time.h> /* for timespec */ |
106 | # include <time.h> /* for timespec */ |
104 | # include <syscall.h> /* for SYS_* */ |
107 | # include <syscall.h> /* for SYS_* */ |
105 | # ifdef SYS_clock_gettime |
108 | # ifdef SYS_clock_gettime |
106 | # define coro_clock_gettime(id, ts) syscall (SYS_clock_gettime, (id), (ts)) |
109 | # define coro_clock_gettime(id, ts) syscall (SYS_clock_gettime, (id), (ts)) |
… | |
… | |
204 | }; |
207 | }; |
205 | |
208 | |
206 | /* the structure where most of the perl state is stored, overlaid on the cxstack */ |
209 | /* the structure where most of the perl state is stored, overlaid on the cxstack */ |
207 | typedef struct |
210 | typedef struct |
208 | { |
211 | { |
209 | SV *defsv; |
|
|
210 | AV *defav; |
|
|
211 | SV *errsv; |
|
|
212 | SV *irsgv; |
|
|
213 | HV *hinthv; |
|
|
214 | #define VAR(name,type) type name; |
212 | #define VARx(name,expr,type) type name; |
215 | # include "state.h" |
213 | # include "state.h" |
216 | #undef VAR |
214 | #undef VARx |
217 | } perl_slots; |
215 | } perl_slots; |
218 | |
216 | |
219 | // how many context stack entries do we need for perl_slots |
217 | // how many context stack entries do we need for perl_slots |
220 | #define SLOT_COUNT ((sizeof (perl_slots) + sizeof (PERL_CONTEXT) - 1) / sizeof (PERL_CONTEXT)) |
218 | #define SLOT_COUNT ((sizeof (perl_slots) + sizeof (PERL_CONTEXT) - 1) / sizeof (PERL_CONTEXT)) |
221 | |
219 | |
… | |
… | |
289 | static SV *coro_readyhook; |
287 | static SV *coro_readyhook; |
290 | static struct coro *coro_ready [CORO_PRIO_MAX - CORO_PRIO_MIN + 1][2]; /* head|tail */ |
288 | static struct coro *coro_ready [CORO_PRIO_MAX - CORO_PRIO_MIN + 1][2]; /* head|tail */ |
291 | static CV *cv_coro_run; |
289 | static CV *cv_coro_run; |
292 | static struct coro *coro_first; |
290 | static struct coro *coro_first; |
293 | #define coro_nready coroapi.nready |
291 | #define coro_nready coroapi.nready |
|
|
292 | |
|
|
293 | /** JIT *********************************************************************/ |
|
|
294 | |
|
|
295 | #if CORO_JIT |
|
|
296 | #ifndef CORO_JIT_TYPE |
|
|
297 | #if __linux && __amd64 |
|
|
298 | #define CORO_JIT_TYPE "amd64-unix" |
|
|
299 | typedef void (*load_save_perl_slots_type)(perl_slots *); |
|
|
300 | #else |
|
|
301 | #undef CORO_JIT |
|
|
302 | #endif |
|
|
303 | #endif |
|
|
304 | #endif |
|
|
305 | |
|
|
306 | #if CORO_JIT |
|
|
307 | |
|
|
308 | static load_save_perl_slots_type load_perl_slots, save_perl_slots; |
|
|
309 | |
|
|
310 | #endif |
294 | |
311 | |
295 | /** Coro::Select ************************************************************/ |
312 | /** Coro::Select ************************************************************/ |
296 | |
313 | |
297 | static OP *(*coro_old_pp_sselect) (pTHX); |
314 | static OP *(*coro_old_pp_sselect) (pTHX); |
298 | static SV *coro_select_select; |
315 | static SV *coro_select_select; |
… | |
… | |
678 | perl_slots *slot = c->slot; |
695 | perl_slots *slot = c->slot; |
679 | c->slot = 0; |
696 | c->slot = 0; |
680 | |
697 | |
681 | PL_mainstack = c->mainstack; |
698 | PL_mainstack = c->mainstack; |
682 | |
699 | |
683 | GvSV (PL_defgv) = slot->defsv; |
700 | #if CORO_JIT |
684 | GvAV (PL_defgv) = slot->defav; |
701 | load_perl_slots (slot); |
685 | GvSV (PL_errgv) = slot->errsv; |
702 | #else |
686 | GvSV (irsgv) = slot->irsgv; |
|
|
687 | GvHV (PL_hintgv) = slot->hinthv; |
|
|
688 | |
|
|
689 | #define VAR(name,type) PL_ ## name = slot->name; |
703 | #define VARx(name,expr,type) expr = slot->name; |
690 | # include "state.h" |
704 | # include "state.h" |
691 | #undef VAR |
705 | #undef VARx |
|
|
706 | #endif |
692 | |
707 | |
693 | { |
708 | { |
694 | dSP; |
709 | dSP; |
695 | |
710 | |
696 | CV *cv; |
711 | CV *cv; |
… | |
… | |
813 | c->mainstack = PL_mainstack; |
828 | c->mainstack = PL_mainstack; |
814 | |
829 | |
815 | { |
830 | { |
816 | perl_slots *slot = c->slot = (perl_slots *)(cxstack + cxstack_ix + 1); |
831 | perl_slots *slot = c->slot = (perl_slots *)(cxstack + cxstack_ix + 1); |
817 | |
832 | |
818 | slot->defav = GvAV (PL_defgv); |
833 | #if CORO_JIT |
819 | slot->defsv = DEFSV; |
834 | save_perl_slots (slot); |
820 | slot->errsv = ERRSV; |
835 | #else |
821 | slot->irsgv = GvSV (irsgv); |
|
|
822 | slot->hinthv = GvHV (PL_hintgv); |
|
|
823 | |
|
|
824 | #define VAR(name,type) slot->name = PL_ ## name; |
836 | #define VARx(name,expr,type) slot->name = expr; |
825 | # include "state.h" |
837 | # include "state.h" |
826 | #undef VAR |
838 | #undef VARx |
|
|
839 | #endif |
827 | } |
840 | } |
828 | } |
841 | } |
829 | |
842 | |
830 | /* |
843 | /* |
831 | * allocate various perl stacks. This is almost an exact copy |
844 | * allocate various perl stacks. This is almost an exact copy |
… | |
… | |
3323 | |
3336 | |
3324 | #ifndef __cplusplus |
3337 | #ifndef __cplusplus |
3325 | ecb_cold XS(boot_Coro__State); |
3338 | ecb_cold XS(boot_Coro__State); |
3326 | #endif |
3339 | #endif |
3327 | |
3340 | |
|
|
3341 | #if CORO_JIT |
|
|
3342 | |
|
|
3343 | static void ecb_noinline ecb_cold |
|
|
3344 | pushav_3uv (pTHX_ UV a, UV b, UV c) |
|
|
3345 | { |
|
|
3346 | dSP; |
|
|
3347 | AV *av = newAV (); |
|
|
3348 | |
|
|
3349 | av_store (av, 2, newSVuv (c)); |
|
|
3350 | av_store (av, 1, newSVuv (b)); |
|
|
3351 | av_store (av, 0, newSVuv (a)); |
|
|
3352 | |
|
|
3353 | XPUSHs (sv_2mortal (newRV_noinc ((SV *)av))); |
|
|
3354 | |
|
|
3355 | PUTBACK; |
|
|
3356 | } |
|
|
3357 | |
|
|
3358 | static void ecb_noinline ecb_cold |
|
|
3359 | jit_init (pTHX) |
|
|
3360 | { |
|
|
3361 | dSP; |
|
|
3362 | SV *load, *save; |
|
|
3363 | char *map_base; |
|
|
3364 | char *load_ptr, *save_ptr; |
|
|
3365 | STRLEN load_len, save_len; |
|
|
3366 | int count; |
|
|
3367 | |
|
|
3368 | PUSHMARK (SP); |
|
|
3369 | PUTBACK; |
|
|
3370 | #define VARx(name,expr,type) pushav_3uv (aTHX_ (UV)&(expr), offsetof (perl_slots, name), sizeof (type)); |
|
|
3371 | # include "state.h" |
|
|
3372 | #undef VARx |
|
|
3373 | count = call_pv ("Coro::State::_jit", G_ARRAY); |
|
|
3374 | SPAGAIN; |
|
|
3375 | |
|
|
3376 | save = POPs; save_ptr = SvPVbyte (save, save_len); |
|
|
3377 | load = POPs; load_ptr = SvPVbyte (load, load_len); |
|
|
3378 | |
|
|
3379 | map_base = mmap (0, load_len + save_len + 16, PROT_EXEC | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
|
|
3380 | |
|
|
3381 | assert (("Coro: unable mmap jit code page, cannot continue.", map_base != (char *)MAP_FAILED)); |
|
|
3382 | |
|
|
3383 | load_perl_slots = (load_save_perl_slots_type)map_base; |
|
|
3384 | memcpy (map_base, load_ptr, load_len); |
|
|
3385 | |
|
|
3386 | map_base += (load_len + 15) & ~15; |
|
|
3387 | |
|
|
3388 | save_perl_slots = (load_save_perl_slots_type)map_base; |
|
|
3389 | memcpy (map_base, save_ptr, save_len); |
|
|
3390 | } |
|
|
3391 | |
|
|
3392 | #endif |
|
|
3393 | |
3328 | MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_ |
3394 | MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_ |
3329 | |
3395 | |
3330 | PROTOTYPES: DISABLE |
3396 | PROTOTYPES: DISABLE |
3331 | |
3397 | |
3332 | BOOT: |
3398 | BOOT: |
… | |
… | |
3336 | coro_thx = PERL_GET_CONTEXT; |
3402 | coro_thx = PERL_GET_CONTEXT; |
3337 | # endif |
3403 | # endif |
3338 | #endif |
3404 | #endif |
3339 | BOOT_PAGESIZE; |
3405 | BOOT_PAGESIZE; |
3340 | |
3406 | |
|
|
3407 | /* perl defines these to check for existance first, but why it doesn't */ |
|
|
3408 | /* just create them one at init time is not clear to me, except for */ |
|
|
3409 | /* programs trying to delete them, but... */ |
|
|
3410 | /* anyway, we declare this as invalid and make sure they are initialised here */ |
|
|
3411 | DEFSV; |
|
|
3412 | ERRSV; |
|
|
3413 | |
3341 | cctx_current = cctx_new_empty (); |
3414 | cctx_current = cctx_new_empty (); |
3342 | |
3415 | |
3343 | irsgv = gv_fetchpv ("/" , GV_ADD|GV_NOTQUAL, SVt_PV); |
3416 | irsgv = gv_fetchpv ("/" , GV_ADD|GV_NOTQUAL, SVt_PV); |
3344 | stdoutgv = gv_fetchpv ("STDOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO); |
3417 | stdoutgv = gv_fetchpv ("STDOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO); |
3345 | |
3418 | |
… | |
… | |
3387 | coroapi.prepare_cede_notself = prepare_cede_notself; |
3460 | coroapi.prepare_cede_notself = prepare_cede_notself; |
3388 | |
3461 | |
3389 | time_init (aTHX); |
3462 | time_init (aTHX); |
3390 | |
3463 | |
3391 | assert (("PRIO_NORMAL must be 0", !CORO_PRIO_NORMAL)); |
3464 | assert (("PRIO_NORMAL must be 0", !CORO_PRIO_NORMAL)); |
|
|
3465 | #if CORO_JIT |
|
|
3466 | PUTBACK; |
|
|
3467 | require_pv ("Coro/jit-" CORO_JIT_TYPE ".pl"); |
|
|
3468 | jit_init (aTHX); |
|
|
3469 | perl_eval_pv ("undef &Coro::State::_jit", 1); |
|
|
3470 | SPAGAIN; |
|
|
3471 | #endif |
3392 | } |
3472 | } |
3393 | |
3473 | |
3394 | SV * |
3474 | SV * |
3395 | new (SV *klass, ...) |
3475 | new (SV *klass, ...) |
3396 | ALIAS: |
3476 | ALIAS: |