Coro

 view release on metacpan or  search on metacpan

Coro/State.xs  view on Meta::CPAN


  U32 gen;
#if CORO_USE_VALGRIND
  int valgrind_id;
#endif
  unsigned char flags;
} coro_cctx;

static coro_cctx *cctx_current; /* the currently running cctx */

/*****************************************************************************/

static MGVTBL coro_state_vtbl;

enum
{
  CF_RUNNING   = 0x0001, /* coroutine is running */
  CF_READY     = 0x0002, /* coroutine is ready */
  CF_NEW       = 0x0004, /* has never been switched to */
  CF_ZOMBIE    = 0x0008, /* coroutine data has been freed */
  CF_SUSPENDED = 0x0010, /* coroutine can't be scheduled */
  CF_NOCANCEL  = 0x0020, /* cannot cancel, set slf_frame.data to 1 (hackish) */
};

/* the structure where most of the perl state is stored, overlaid on the cxstack */
typedef struct
{
  #define VARx(name,expr,type) type name;
  #include "state.h"
} perl_slots;

/* how many context stack entries do we need for perl_slots */
#define SLOT_COUNT ((sizeof (perl_slots) + sizeof (PERL_CONTEXT) - 1) / sizeof (PERL_CONTEXT))

/* this is a structure representing a perl-level coroutine */
struct coro
{
  /* the C coroutine allocated to this perl coroutine, if any */
  coro_cctx *cctx;

  /* ready queue */
  struct coro *next_ready;

  /* state data */
  struct CoroSLF slf_frame; /* saved slf frame */
  AV *mainstack;
  perl_slots *slot; /* basically the saved sp */

  CV *startcv;  /* the CV to execute */
  AV *args;     /* data associated with this coroutine (initial args) */
  int flags;    /* CF_ flags */
  HV *hv;       /* the perl hash associated with this coro, if any */

  /* statistics */
  int usecount; /* number of transfers to this coro */

  /* coro process data */
  int prio;
  SV *except;   /* exception to be thrown */
  SV *rouse_cb; /* last rouse callback */
  AV *on_destroy; /* callbacks or coros to notify on destroy */
  AV *status;   /* the exit status list */

  /* async_pool */
  SV *saved_deffh;
  SV *invoke_cb;
  AV *invoke_av;

  /* on_enter/on_leave */
  AV *on_enter; AV *on_enter_xs;
  AV *on_leave; AV *on_leave_xs;

  /* swap_sv */
  AV *swap_sv;

  /* times */
  coro_ts t_cpu, t_real;

  /* linked list */
  struct coro *next, *prev;
};

typedef struct coro *Coro__State;
typedef struct coro *Coro__State_or_hashref;

/* the following variables are effectively part of the perl context */
/* and get copied between struct coro and these variables */
/* the main reason we don't support windows process emulation */
static struct CoroSLF slf_frame; /* the current slf frame */

/** Coro ********************************************************************/

#define CORO_PRIO_MAX     3
#define CORO_PRIO_HIGH    1
#define CORO_PRIO_NORMAL  0
#define CORO_PRIO_LOW    -1
#define CORO_PRIO_IDLE   -3
#define CORO_PRIO_MIN    -4

/* for Coro.pm */
static SV *coro_current;
static SV *coro_readyhook;
static struct coro *coro_ready [CORO_PRIO_MAX - CORO_PRIO_MIN + 1][2]; /* head|tail */
static CV *cv_coro_run;
static struct coro *coro_first;
#define coro_nready coroapi.nready

/** JIT *********************************************************************/

#if CORO_JIT
  /* APPLE doesn't have mmap though */
  #define CORO_JIT_UNIXY (__linux || __FreeBSD__ || __OpenBSD__ || __NetBSD__ || __solaris || __APPLE__)
  #ifndef CORO_JIT_TYPE
    #if ECB_AMD64 && CORO_JIT_UNIXY
      #define CORO_JIT_TYPE "amd64-unix"
    #elif __i386 && CORO_JIT_UNIXY
      #define CORO_JIT_TYPE "x86-unix"
    #endif
  #endif
#endif



( run in 2.479 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )