Skip to content
Snippets Groups Projects
Commit 49ed1e71 authored by Lars Kanis's avatar Lars Kanis
Browse files

Release GVL for all implementations of loadPixels and savePixels.

parent c2098287
No related branches found
No related tags found
No related merge requests found
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include "FXRbCommon.h" #include "FXRbCommon.h"
__thread int g_fxrb_thread_has_gvl = 1;
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_WRAPPER_STRUCT ); FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_WRAPPER_STRUCT );
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_SKELETON ); FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_SKELETON );
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB ); FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB );
...@@ -17,164 +17,130 @@ ...@@ -17,164 +17,130 @@
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
extern "C" void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1, extern "C" void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
rb_unblock_function_t *ubf, void *data2); rb_unblock_function_t *ubf, void *data2);
#endif #endif
#define DEFINE_PARAM_LIST1(type, name) \ #define DEFINE_PARAM_LIST1(type, name) \
name, , name
#define DEFINE_PARAM_LIST2(type, name) \ #define DEFINE_PARAM_LIST2(type, name) \
p->params.name, , p->params.name
#define DEFINE_PARAM_LIST3(type, name) \ #define DEFINE_PARAM_LIST3(type, name) \
type name, , type name
#define DEFINE_PARAM_DECL(type, name) \ #define DEFINE_PARAM_DECL(type, name) \
type name; type name;
#define DEFINE_GVL_WRAPPER_STRUCT(name, when_non_void, rettype, lastparamtype, lastparamname) \ #define DEFINE_GVL_WRAPPER_STRUCT(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \
struct gvl_wrapper_##name##_params { \ struct gvl_wrapper_##klass##_##name##_params { \
struct { \ struct { \
FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_DECL) \ firstparamtype firstparamname; \
lastparamtype lastparamname; \ FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_DECL) \
} params; \ } params; \
when_non_void( rettype retval; ) \ when_non_void( rettype retval; ) \
}; };
#define DEFINE_GVL_SKELETON(name, when_non_void, rettype, lastparamtype, lastparamname) \ extern __thread int g_fxrb_thread_has_gvl;
static void * gvl_##name##_skeleton( void *data ){ \
struct gvl_wrapper_##name##_params *p = (struct gvl_wrapper_##name##_params*)data; \ #define DEFINE_GVL_SKELETON(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \
when_non_void( p->retval = ) \ static void * gvl_##klass##_##name##_skeleton( void *data ){ \
name##_gvl( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST2) p->params.lastparamname ); \ struct gvl_wrapper_##klass##_##name##_params *p = (struct gvl_wrapper_##klass##_##name##_params*)data; \
return NULL; \ g_fxrb_thread_has_gvl = 0; \
} when_non_void( p->retval = ) \
klass##_##name##_gvl( p->params.firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST2) ); \
g_fxrb_thread_has_gvl = 1; \
return NULL; \
}
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
#define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \ #define DEFINE_GVL_STUB(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \
rettype name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \ rettype klass##_##name(firstparamtype firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST3)){ \
struct gvl_wrapper_##name##_params params = { \ struct gvl_wrapper_##klass##_##name##_params params = { \
{FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \ {firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST1)}, when_non_void((rettype)0) \
}; \ }; \
rb_thread_call_without_gvl(gvl_##name##_skeleton, &params, RUBY_UBF_IO, 0); \ rb_thread_call_without_gvl(gvl_##klass##_##name##_skeleton, &params, RUBY_UBF_IO, 0); \
when_non_void( return params.retval; ) \ when_non_void( return params.retval; ) \
} }
#else #else
#define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \ #define DEFINE_GVL_STUB(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \
rettype name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \ rettype klass##_##name(firstparamtype firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST3)){ \
return name##_gvl( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \ return klass##_##name##_gvl(firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST1)); \
} }
#endif #endif
#define DEFINE_GVL_STUB_DECL(name, when_non_void, rettype, lastparamtype, lastparamname) \ #define DEFINE_GVL_STUB_DECL(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \
rettype name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname); rettype klass##_##name( firstparamtype firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST3));
#define DEFINE_GVL_TARGET_DECL(name, when_non_void, rettype, lastparamtype, lastparamname) \
rettype name##_gvl(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname);
#define GVL_TYPE_VOID(string) #define GVL_TYPE_VOID(string)
#define GVL_TYPE_NONVOID(string) string #define GVL_TYPE_NONVOID(string) string
/* /*
* Definitions of blocking functions and their parameters * Definitions of blocking functions and their parameters
*/ */
#define FOR_EACH_PARAM_OF_FXImage_loadPixels(param) \ #define FOR_EACH_PARAM_OF_FXImage_loadPixels(param) \
param(FXImage *, self) param(FXStream&, store)
#define FOR_EACH_PARAM_OF_FXImage_savePixels(param) \ #define FOR_EACH_PARAM_OF_FXImage_savePixels(param) \
param(const FXImage *, self) param(FXStream&, store)
#define FOR_EACH_PARAM_OF_FXBMPImage_loadPixels(param) \ /* function( name, void_or_nonvoid, returntype, firstparamtype, firstparamname ) */
param(FXBMPImage *, self)
#define FOR_EACH_PARAM_OF_FXBMPImage_savePixels(param) \
param(const FXBMPImage *, self)
#define FOR_EACH_PARAM_OF_FXJPGImage_loadPixels(param) \
param(FXJPGImage *, self)
#define FOR_EACH_PARAM_OF_FXJPGImage_savePixels(param) \
param(const FXJPGImage *, self)
#define FOR_EACH_PARAM_OF_FXGIFImage_loadPixels(param) \
param(FXGIFImage *, self)
#define FOR_EACH_PARAM_OF_FXGIFImage_savePixels(param) \
param(const FXGIFImage *, self)
#define FOR_EACH_PARAM_OF_FXICOImage_loadPixels(param) \
param(FXICOImage *, self)
#define FOR_EACH_PARAM_OF_FXICOImage_savePixels(param) \
param(const FXICOImage *, self)
#define FOR_EACH_PARAM_OF_FXPNGImage_loadPixels(param) \
param(FXPNGImage *, self)
#define FOR_EACH_PARAM_OF_FXPNGImage_savePixels(param) \
param(const FXPNGImage *, self)
#define FOR_EACH_PARAM_OF_FXPPMImage_loadPixels(param) \
param(FXPPMImage *, self)
#define FOR_EACH_PARAM_OF_FXPPMImage_savePixels(param) \
param(const FXPPMImage *, self)
#define FOR_EACH_PARAM_OF_FXPCXImage_loadPixels(param) \
param(FXPCXImage *, self)
#define FOR_EACH_PARAM_OF_FXPCXImage_savePixels(param) \
param(const FXPCXImage *, self)
#define FOR_EACH_PARAM_OF_FXRGBImage_loadPixels(param) \
param(FXRGBImage *, self)
#define FOR_EACH_PARAM_OF_FXRGBImage_savePixels(param) \
param(const FXRGBImage *, self)
#define FOR_EACH_PARAM_OF_FXTGAImage_loadPixels(param) \
param(FXTGAImage *, self)
#define FOR_EACH_PARAM_OF_FXTGAImage_savePixels(param) \
param(const FXTGAImage *, self)
#define FOR_EACH_PARAM_OF_FXTIFImage_loadPixels(param) \
param(FXTIFImage *, self)
#define FOR_EACH_PARAM_OF_FXTIFImage_savePixels(param) \
param(const FXTIFImage *, self)
#define FOR_EACH_PARAM_OF_FXXBMImage_loadPixels(param) \
param(FXXBMImage *, self)
#define FOR_EACH_PARAM_OF_FXXBMImage_savePixels(param) \
param(const FXXBMImage *, self)
#define FOR_EACH_PARAM_OF_FXXPMImage_loadPixels(param) \
param(FXXPMImage *, self)
#define FOR_EACH_PARAM_OF_FXXPMImage_savePixels(param) \
param(const FXXPMImage *, self)
/* function( name, void_or_nonvoid, returntype, lastparamtype, lastparamname ) */
#define FOR_EACH_BLOCKING_FUNCTION(function) \ #define FOR_EACH_BLOCKING_FUNCTION(function) \
function(FXImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXImage *, self) \
function(FXImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXImage *, self) \
function(FXBMPImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXBMPImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXBMPImage *, self) \
function(FXBMPImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXBMPImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXBMPImage *, self) \
function(FXJPGImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXJPGImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXJPGImage *, self) \
function(FXJPGImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXJPGImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXJPGImage *, self) \
function(FXGIFImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXGIFImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXGIFImage *, self) \
function(FXGIFImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXGIFImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXGIFImage *, self) \
function(FXICOImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXICOImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXICOImage *, self) \
function(FXICOImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXICOImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXICOImage *, self) \
function(FXPNGImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXPNGImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPNGImage *, self) \
function(FXPNGImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXPNGImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPNGImage *, self) \
function(FXPPMImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXPPMImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPPMImage *, self) \
function(FXPPMImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXPPMImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPPMImage *, self) \
function(FXPCXImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXPCXImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPCXImage *, self) \
function(FXPCXImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXPCXImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPCXImage *, self) \
function(FXRGBImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXRGBImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXRGBImage *, self) \
function(FXRGBImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXRGBImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXRGBImage *, self) \
function(FXTGAImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXTGAImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXTGAImage *, self) \
function(FXTGAImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXTGAImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXTGAImage *, self) \
function(FXTIFImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXTIFImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXTIFImage *, self) \
function(FXTIFImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXTIFImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXTIFImage *, self) \
function(FXXBMImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXXBMImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXXBMImage *, self) \
function(FXXBMImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXXBMImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXXBMImage *, self) \
function(FXXPMImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ function(FXXPMImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXXPMImage *, self) \
function(FXXPMImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) function(FXXPMImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXXPMImage *, self) \
function(FXIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXIcon *, self) \
function(FXIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXIcon *, self) \
function(FXBMPIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXBMPIcon *, self) \
function(FXBMPIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXBMPIcon *, self) \
function(FXJPGIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXJPGIcon *, self) \
function(FXJPGIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXJPGIcon *, self) \
function(FXGIFIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXGIFIcon *, self) \
function(FXGIFIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXGIFIcon *, self) \
function(FXICOIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXICOIcon *, self) \
function(FXICOIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXICOIcon *, self) \
function(FXPNGIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPNGIcon *, self) \
function(FXPNGIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPNGIcon *, self) \
function(FXPPMIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPPMIcon *, self) \
function(FXPPMIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPPMIcon *, self) \
function(FXPCXIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPCXIcon *, self) \
function(FXPCXIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPCXIcon *, self) \
function(FXRGBIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXRGBIcon *, self) \
function(FXRGBIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXRGBIcon *, self) \
function(FXTGAIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXTGAIcon *, self) \
function(FXTGAIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXTGAIcon *, self) \
function(FXTIFIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXTIFIcon *, self) \
function(FXTIFIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXTIFIcon *, self) \
function(FXXBMIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXXBMIcon *, self) \
function(FXXBMIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXXBMIcon *, self) \
function(FXXPMIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXXPMIcon *, self) \
function(FXXPMIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXXPMIcon *, self)
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL ) FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL )
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_TARGET_DECL )
#endif /* end __gvl_wrappers_h */ #endif /* end __gvl_wrappers_h */
...@@ -17,7 +17,7 @@ class TC_FXJPGImage < Fox::TestCase ...@@ -17,7 +17,7 @@ class TC_FXJPGImage < Fox::TestCase
count = 0 count = 0
th = Thread.new do th = Thread.new do
loop do loop do
sleep 0.01 sleep 0.001
count += 1 count += 1
end end
end end
...@@ -26,13 +26,23 @@ class TC_FXJPGImage < Fox::TestCase ...@@ -26,13 +26,23 @@ class TC_FXJPGImage < Fox::TestCase
img.setPixels( img_data, 0, w, h ) img.setPixels( img_data, 0, w, h )
jpeg_data = FXMemoryStream.open(FXStreamSave, nil) do |outfile| jpeg_data = FXMemoryStream.open(FXStreamSave, nil) do |outfile|
img.savePixels(outfile) img.savePixels(outfile)
outfile.takeBuffer outfile.takeBuffer
end end
assert_operator(count, :>=, 10)
assert_operator(jpeg_data.bytesize, :>=, 1000)
count = 0
img = FXJPGImage.new(app)
FXMemoryStream.open(FXStreamLoad, jpeg_data) do |infile|
img.loadPixels(infile)
end
th.kill th.kill
assert_equal 4000, img.width
assert_equal 3000, img.height
assert_operator(count, :>=, 10) assert_operator(count, :>=, 10)
assert_operator(jpeg_data.bytesize, :>=, 1000)
end end
end end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment