in reply to Re: Significance of #define PERL_GET_NO_CONTEXT in XS
in thread Significance of #define PERL_NO_GET_CONTEXT in XS

I take it there's no point in defining PERL_GET_NO_CONTEXT if MULTIPLICITY is not defined, and one could therefore do:
#ifdef MULTIPLICITY #define PERL_GET_NO_CONTEXT 1 #endif
Would that ensure that PERL_GET_NO_CONTEXT gets defined whenever (and only whenever) it's relevant ?

Update: Heh ... for one thing, MULTIPLICITY is not defined prior to the inclusion of the standard XS headers, so we can't use that.
I guess we can have the Makefile pass another symbol (iff $Config{usemultiplicity} is 'define').
Or just define PERL_GET_NO_CONTEXT, and not concern ourselves with whether perl was even built with "usemultiplicity".

Cheers,
Rob

Replies are listed 'Best First'.
Re^3: Significance of #define PERL_GET_NO_CONTEXT in XS
by dave_the_m (Monsignor) on Mar 14, 2014 at 12:34 UTC
    Or just define PERL_GET_NO_CONTEXT, and not concern ourselves with whether perl was even built with "usemultiplicity"
    That's the thing to do. On unthreaded builds etc, the macros will all just Do The Right Thing (which is usually to do nothing).

    To further elaborate, consider the following snippet of XS code:

    #define PERL_NO_GET_CONTEXT sv_foo(a, b, c);
    On a threaded/MULTIPLICITY build, it would macro-expand to:
    Perl_sv_foo(my_perl, a, b, c);
    Remove the PERL_NO_GET_CONTEXT and, depending on platform (this is Linux), it might expand to something like:
    Perl_sv_foo(((PerlInterpreter *)pthread_getspecific(PL_thr_key)), a, b, c);

    On a non-threaded build, it would expand to the following, regardless of whether PERL_NO_GET_CONTEXT is present:

    Perl_sv_foo(a, b, c);

    The dTHX macro basically expands to

    PerlInterpreter * my_perl = (PerlInterpreter *)pthread_getspecific(PL_thr_key);
    So it's more efficient to just calculate my_perl once per function rather than for every function call, but it's even better to get your caller to pass it to you. So declare your functions as say Foo(pTHX_ int a, int b) and call them as Foo(aTHX_ 1, 2);

    Dave.

      Ok ... I'll just make it a blanket "#define PERL_NO_GET_CONTEXT" ... no ifs and buts ;-)

      I mainly use Inline::C to autogenerate my XS files.
      The appealing aspect of using dTHX is that Inline::C already accommodates that approach. That is, this simple Inline::C demo works fine:
      use strict; use warnings; use Inline C => Config => BUILD_NOISY => 1, PRE_HEAD => "#define PERL_NO_GET_CONTEXT", ; use Inline C => <<'EOC'; SV * dubble(SV * in) { dTHX; return newSViv(SvIV(in) * 2); } EOC my $x = dubble(23); print $x; # 46
      But handling pTHX_ and aTHX_ is way beyond Inline's current capabilities, and the XS file therefore needs to be written by hand.

      I'm not even sure what the XS file should look like when we use pTHX_ and aTHX_. The following seems to work:
      #define PERL_NO_GET_CONTEXT #include "EXTERN.h" #include "perl.h" #include "XSUB.h" SV * dubble(pTHX_ SV * in) { return newSViv(SvIV(in) * 2); } MODULE = FOO PACKAGE = FOO SV * dubble (in) SV * in CODE: RETVAL = dubble(aTHX_ in); OUTPUT: RETVAL
      But I wouldn't like to guarantee that it's not doing something wrong and/or unnecessary.
      The example in the docs to which you linked, invokes a wrapper function called my_xsub - but I've written it so that dubble() wraps itself.
      Is that a valid technique ? Is there something better ?

      Thanks Dave. Good question halfcountplus.

      Cheers,
      Rob