perlmulticore.h - Man Page
implements the Perl Multicore Specification
Synopsis
#include "perlmulticore.h" // in your XS function: perlinterp_release (); do_the_C_thing (); perlinterp_acquire (); // optional, in BOOT section: perlmulticore_support ();
Description
This documentation is the abridged version of the full documention at <http://perlmulticore.schmorp.de/>. It's recommended to go there instead of reading this document.
This header file implements a very low overhead (both in code and runtime) mechanism for XS modules to allow re-use of the perl interpreter for other threads while doing some lengthy operation, such as cryptography, SQL queries, disk I/O and so on.
The newest version of the header file itself, can be downloaded from <http://perlmulticore.schmorp.de/perlmulticore.h>.
How Do I Use This in My Modules?
The usage is very simple - you include this header file in your XS module. Then, before you do your lengthy operation, you release the perl interpreter:
perlinterp_release ();
And when you are done with your computation, you acquire it again:
perlinterp_acquire ();
And that's it. This doesn't load any modules and consists of only a few machine instructions when no module to take advantage of it is loaded.
More documentation and examples can be found at the perl multicore site at <http://perlmulticore.schmorp.de>.
The Hard and Fast Rules
As with everything, there are a number of rules to follow.
- Never touch any perl data structures after calling perlinterp_release.
Anything perl is completely off-limits after
perlinterp_release
, until you callperlinterp_acquire
, after which you can access perl stuff again.That includes anything in the perl interpreter that you didn't prove to be safe, and didn't prove to be safe in older and future versions of perl: global variables, local perl scalars, even if you are sure nobody accesses them and you only try to "read" their value.
- Always call perlinterp_release and perlinterp_acquire in pairs.
For each
perlinterp_release
call there must be aperlinterp_acquire
call. They don't have to be in the same function, and you can have multiple calls to them, as long as everyperlinterp_release
call is followed by exactly oneperlinterp_acquire
call at runtime.- Never nest calls to perlinterp_release and perlinterp_acquire.
That simply means that after calling
perlinterp_release
, you must callperlinterp_acquire
before callingperlinterp_release
again. Likewise, afterperlinterp_acquire
, you can callperlinterp_release
but not anotherperlinterp_acquire
.- Always call perlinterp_release first.
You must not call
perlinterp_acquire
without having calledperlinterp_release
before.- Never underestimate threads.
While it's easy to add parallel execution ability to your XS module, it doesn't mean it is safe. After you release the perl interpreter, it's perfectly possible that it will call your XS function in another thread, even while your original function still executes. In other words: your C code must be thread safe, and if you use any library, that library must be thread-safe, too.
Always assume that the code between
perlinterp_release
andperlinterp_acquire
is executed in parallel on multiple CPUs at the same time.
Disabling Perl Multicore at Compile Time
You can disable the complete perl multicore API by defining the symbol PERL_MULTICORE_DISABLE
to 1
(e.g. by specifying -DPERL_MULTICORE_DISABLE as compiler argument).
This could be added to perl's CPPFLAGS
when configuring perl on platforms that do not support threading at all for example.
Advertising Multicore API Support
To help users find out whether a particular build of your module is, in fact, multicore enabled, you can invoke the perlmulticore_support
macro in your BOOT:
section, e.g.:
MODULE = My::Mod PACKAGE = My::Mod::Pkg BOOT: perlmulticore_support ();
What this does is set the $My::Mod::PERLMULTICORE_SUPPORT
variable to the major API version * 1000 + minor version, for example, version 1002
introduced this feature.
For this to work, the cv
parameter passed to BOOT:
must still be in scope. To ensure this, either invoke the macro early in your BOOT:
section, or don't declare a local variable called cv
, either of which should be easy to do.
Note that this is optional, so you don't have to do that.
Author
Marc A. Lehmann <perlmulticore@schmorp.de> http://perlmulticore.schmorp.de/
License
The perlmulticore.h header file is put into the public domain. Where this is legally not possible, or at your option, it can be licensed under creativecommons CC0 license: <https://creativecommons.org/publicdomain/zero/1.0/>.