[Cython] incorrect codegen for nogil functions calling nogil except+ functions

Gerald Dalley gerald.dalley at gmail.com
Fri Nov 16 17:54:51 CET 2012

When a nogil function calls a nogil except+ function, Cython generates C
code that requires the Py_BEGIN_ALLOW_THREADS macro to be evaluated, but it
doesn't inject the code to evaluate the Py_BEING_ALLOW_THREADS macro.

Consider the following C header file (nogil_except.h)

    inline int foo() { return 1; }

and a corresponding Cython source file (nogil_except.pyx)

    cdef extern from "nogil_except.h":
        cdef int foo() nogil except+
    cdef int bar() nogil:
        return foo()
    print bar()

Cython's ExprNodes.py generates code that calls the Py_BLOCKS_THREADS
macro, but it doesn't ensure that Py_BEGIN_ALLOW_THREADS has been injected
into an enclosing scope.  The latter macro defines a variable, "_save"
that's needed by the Py_BLOCKS_THREADS macro:

    $ cython nogil_except.pyx && /usr/bin/g++ ... -c nogil_except.cpp

    nogil_except.c: In function ‘int __pyx_f_12nogil_except_bar()’:
    nogil_except.c:537: error: ‘_save’ was not declared in this scope

Here's the applicable block of generated code:

    $ awk -F, '{if (($2=="") && (NR >= 531) && (NR < 540))
                printf "%-4d %s\n", NR,$0}' nogil_except.c

    531    /* "nogil_except.pyx":4
    532   *     cdef int foo() nogil except+
    533   * cdef int bar() nogil:
    534   *     return foo()             # <<<<<<<<<<<<<<
    535   * print bar()
    536   */
    537    try {__pyx_t_1 = foo();} catch(...) {
           Py_BLOCK_THREADS; __Pyx_CppExn2PyErr(); Py_UNBLOCK_THREADS;
           {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4;
            __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
    538    __pyx_r = __pyx_t_1;
    539    goto __pyx_L0;

It seems like either ExprNodes.py should avoid injecting Py_BLOCK_THREADS
and Py_UNBLOCK_THREADS when operating outside an OpenMP context and/or
something should guarantee that Py_BEGIN_ALLOW_THREADS and
Py_END_ALLOW_THREADS get injected as needed into the code stream.

I've tested Cython 0.17b2 and 0.17b3 and both exhibit this problem.

--Gerald Dalley
  dalleyg at ieee.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cython-devel/attachments/20121116/f5eef764/attachment.html>

More information about the cython-devel mailing list