Lisandro Dalcin wrote:
> > 1/ The simplest, but not the most optimized one: acquire/release the GIL
within __Pyx_CppExn2PyErr().
>
> Why do you say (1) is not the most optimized one? (Sorry, I'm not good
> at understanding issues with thread-based concurrency)
Because it will acquire/release the GIL, even for functions that are not called
without "with nogil".
But maybe acquiring/releasing the GIL is not costy (I haven't checked).
> > 2/ acquire/release the GIL in the catch clause only when "with nogil":
> > try {foo();} catch(...) {PyGILState_STATE state = PyGILState_Ensure();
> __Pyx_CppExn2PyErr(); PyGILState_Release(state); {__pyx_filename = __pyx_f[0];
__pyx_lineno = 6;
> __pyx_clineno = __LINE__; goto __pyx_L6;}}
> >
>
> How would this be different to (1) ?
Because it can only acquires/releases the GIL when a function is called "with
nogil" and not for the others (but more complex to implement as Cython needs to
know the "with nogil" context.
> > 3/ restore the thread in the catch clause:
> > try {foo();} catch(...) { Py_BLOCK_THREADS __Pyx_CppExn2PyErr();
{__pyx_filename =
> __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L6;}}
> > }
> > /*finally:*/ {
> > int __pyx_why;
> > Py_BLOCK_THREADS // <<<<<<<<<<<<<<<<
> > __pyx_why = 0; goto __pyx_L7;
> > __pyx_L6: __pyx_why = 4; goto __pyx_L7;
> > __pyx_L7:;
> > switch (__pyx_why) {
> > case 4: goto __pyx_L1_error;
> > }
> > }
> > }
> >
>
> And this one looks bad, I think you need: Py_BLOCK_THREADS
> __Pyx_CppExn2PyErr(); Py_UNBLOCK_THREADS .. Am I right?
>
> What about doing this (ignore the line endings, all should be
> generated in a single line)
>
> { PyThreadState *_save;
> try {
> Py_UNBLOCK_THREADS
> foo();
> Py_BLOCK_THREADS
> } catch(...) {
> Py_BLOCK_THREADS
> __Pyx_CppExn2PyErr();
> }
>
> Am I missing something? However, note that changing to this could be
> not so easy...
Because you may have several function calls within "with nogil":
def bar():
with nogil:
foo()
foo()
and the generated code contains as many try/catch around the calls but only one
thread save/restore:
{ PyThreadState *_save;
Py_UNBLOCK_THREADS
/*try:*/ {
try {foo();} catch(...) {__Pyx_CppExn2PyErr(); {__pyx_filename =
__pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L6;}}
try {foo();} catch(...) {__Pyx_CppExn2PyErr(); {__pyx_filename =
__pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L6;}}
}
/*finally:*/ {
int __pyx_why;
__pyx_why = 0; goto __pyx_L7;
__pyx_L6: __pyx_why = 4; goto __pyx_L7;
__pyx_L7:;
Py_BLOCK_THREADS
switch (__pyx_why) {
case 4: goto __pyx_L1_error;
}
}
}
Stephane
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev