Coro-Multicore
view release on metacpan or search on metacpan
Makefile.PL view on Meta::CPAN
The environment variable CORO_MULTICORE_CHECK can be used to set a
default for this answer.
EOF
my $extra = prompt ("Enable extra checks?", $ENV{CORO_MULTICORE_CHECK} ? "y" : "n") =~ /[Yy]/;
my $define = sprintf "-DRECURSION_CHECK=%d", $extra;
WriteMakefile(Coro::MakeMaker::coro_args(
dist => {
PREOP => 'pod2text Multicore.pm | tee README >$(DISTVNAME)/README; chmod -R u=rwX,go=rX . ;',
COMPRESS => 'gzip -9v',
SUFFIX => '.gz',
},
NAME => "Coro::Multicore",
VERSION_FROM => "Multicore.pm",
CONFIGURE_REQUIRES => { "ExtUtils::MakeMaker" => 6.52, "Canary::Stability" => 0, "Coro" => 6.44 },
TEST_REQUIRES => { "Coro" => 6.44 },
DEFINE => $define,
Multicore.pm view on Meta::CPAN
=head1 NAME
Coro::Multicore - make coro threads on multiple cores with specially supported modules
=head1 SYNOPSIS
# when you DO control the main event loop, e.g. in the main program
use Coro::Multicore; # enable by default
Coro::Multicore::scoped_disable;
AE::cv->recv; # or EV::run, AnyEvent::Loop::run, Event::loop, ...
Multicore.pm view on Meta::CPAN
...
};
=head1 DESCRIPTION
While L<Coro> threads (unlike ithreads) provide real threads similar to
pthreads, python threads and so on, they do not run in parallel to each
other even on machines with multiple CPUs or multiple CPU cores.
This module lifts this restriction under two very specific but useful
conditions: firstly, the coro thread executes in XS code and does not
touch any perl data structures, and secondly, the XS code is specially
prepared to allow this.
This means that, when you call an XS function of a module prepared for it,
this XS function can execute in parallel to any other Coro threads. This
is useful for both CPU bound tasks (such as cryptography) as well as I/O
bound tasks (such as loading an image from disk). It can also be used
to do stuff in parallel via APIs that were not meant for this, such as
database accesses via DBI.
Multicore.pm view on Meta::CPAN
C<Coro::Multicore::scoped_enable>.
Note that this setting nonly affects the I<global default> - it will not
reflect whether multicore functionality is enabled for the current thread.
The function returns the previous value of the enable flag.
=item Coro::Multicore::scoped_enable
This function instructs Coro::Multicore to handle all requests executed
in the current coro thread, from the call to the end of the current scope.
Calls to C<scoped_enable> and C<scoped_disable> don't nest very well at
the moment, so don't nest them.
=item Coro::Multicore::scoped_disable
The opposite of C<Coro::Multicore::scope_disable>: instructs Coro::Multicore to
I<not> handle the next multicore-enabled request.
=back
Multicore.xs view on Meta::CPAN
static s_epipe ep;
static void *perl_thx;
static sigset_t cursigset, fullsigset;
static int global_enable = 0;
static int thread_enable; /* 0 undefined, 1 disabled, 2 enabled */
/* assigned to a thread for each release/acquire */
struct tctx
{
void *coro;
int wait_f;
xcond_t acquire_c;
int jeret;
};
static struct tctx *tctx_free;
static struct tctx *
tctx_get (void)
{
struct tctx *ctx;
if (!tctx_free)
{
ctx = malloc (sizeof (*tctx_free));
X_COND_CREATE (ctx->acquire_c);
}
else
{
ctx = tctx_free;
tctx_free = tctx_free->coro;
}
return ctx;
}
static void
tctx_put (struct tctx *ctx)
{
ctx->coro = tctx_free;
tctx_free = ctx;
}
/* a stack of tctxs */
struct tctxs
{
struct tctx **ctxs;
int cur, max;
};
Multicore.xs view on Meta::CPAN
--idle;
X_UNLOCK (release_m);
if (!ctx) /* timed out? */
break;
pthread_sigmask (SIG_SETMASK, &cursigset, 0);
JMPENV_PUSH (ctx->jeret);
if (!ctx->jeret)
while (ctx->coro)
CORO_SCHEDULE;
JMPENV_POP;
pthread_sigmask (SIG_SETMASK, &fullsigset, &cursigset);
X_LOCK (acquire_m);
ctx->wait_f = 1;
X_COND_SIGNAL (ctx->acquire_c);
X_UNLOCK (acquire_m);
Multicore.xs view on Meta::CPAN
}
#if RECURSION_CHECK
if (X_TLS_GET (check_key))
fatal ("FATAL: perlinterp_release () called without valid perl context");
X_TLS_SET (check_key, &check_key);
#endif
struct tctx *ctx = tctx_get ();
ctx->coro = SvREFCNT_inc_simple_NN (CORO_CURRENT);
ctx->wait_f = 0;
X_TLS_SET (current_key, ctx);
pthread_sigmask (SIG_SETMASK, &fullsigset, &cursigset);
X_LOCK (release_m);
if (idle <= min_idle)
start_thread ();
Multicore.xs view on Meta::CPAN
RETVAL
void
poll (...)
CODE:
s_epipe_drain (&ep);
X_LOCK (acquire_m);
while (acquirers.cur)
{
struct tctx *ctx = tctxs_get (&acquirers);
CORO_READY ((SV *)ctx->coro);
SvREFCNT_dec_simple_void_NN ((SV *)ctx->coro);
ctx->coro = 0;
}
X_UNLOCK (acquire_m);
void
sleep (NV seconds)
CODE:
perlinterp_release ();
{
int nsec = seconds;
if (nsec) sleep (nsec);
NAME
Coro::Multicore - make coro threads on multiple cores with specially
supported modules
SYNOPSIS
# when you DO control the main event loop, e.g. in the main program
use Coro::Multicore; # enable by default
Coro::Multicore::scoped_disable;
AE::cv->recv; # or EV::run, AnyEvent::Loop::run, Event::loop, ...
# blocking is safe in your own threads
...
};
DESCRIPTION
While Coro threads (unlike ithreads) provide real threads similar to
pthreads, python threads and so on, they do not run in parallel to each
other even on machines with multiple CPUs or multiple CPU cores.
This module lifts this restriction under two very specific but useful
conditions: firstly, the coro thread executes in XS code and does not
touch any perl data structures, and secondly, the XS code is specially
prepared to allow this.
This means that, when you call an XS function of a module prepared for
it, this XS function can execute in parallel to any other Coro threads.
This is useful for both CPU bound tasks (such as cryptography) as well
as I/O bound tasks (such as loading an image from disk). It can also be
used to do stuff in parallel via APIs that were not meant for this, such
as database accesses via DBI.
calling "Coro::Multicore::scoped_enable".
Note that this setting nonly affects the *global default* - it will
not reflect whether multicore functionality is enabled for the
current thread.
The function returns the previous value of the enable flag.
Coro::Multicore::scoped_enable
This function instructs Coro::Multicore to handle all requests
executed in the current coro thread, from the call to the end of the
current scope.
Calls to "scoped_enable" and "scoped_disable" don't nest very well
at the moment, so don't nest them.
Coro::Multicore::scoped_disable
The opposite of "Coro::Multicore::scope_disable": instructs
Coro::Multicore to *not* handle the next multicore-enabled request.
THREAD SAFETY OF SUPPORTING XS MODULES
( run in 0.317 second using v1.01-cache-2.11-cpan-3cd7ad12f66 )