Project

General

Profile

Misc #13486 ยป gvl_thread_error.patch

Patch with testcase. - magaudet (Matthew Gaudet), 04/19/2017 07:52 PM

View differences:

eval.c
18 18
#include "ruby/vm.h"
19 19
#include "vm_core.h"
20 20
#include "probes_helper.h"
21
#include "ruby/thread.h"
21 22

  
22 23
NORETURN(void rb_raise_jump(VALUE, VALUE));
23 24

  
......
230 231
    return sysex;
231 232
}
232 233

  
234
#define async_trace(...) if (getenv("ASYNC_COMPILATION_TRACE")) { fprintf(stderr, __VA_ARGS__); } 
235

  
236
static int compilation_thread_started = 0; 
237
void unblock_compilation_thread(void* arg) { 
238
   async_trace("Unblock called!, arg address is %p", arg);
239
   *(int*)arg  = 0; // interrupt compilation thread. 
240
}
241

  
242
void* vm_compile_thread(void *vm) { 
243
   async_trace("invoked compile thread"); 
244
   while (compilation_thread_started) {
245
         rb_thread_wait_for(rb_time_interval(DBL2NUM(0.01)));;
246
   }
247
   async_trace("compilation thread stopped. Returning NULL"); 
248
   return NULL; 
249
}
250
/**
251
 * Release the GVL then start compilation thread.
252
 */
253
VALUE releaseGVLandStartCompilationThread(rb_vm_t* vm)
254
   {
255
   async_trace( "inside %s, compilationThread address is %p\n",__FUNCTION__, &compilation_thread_started); 
256
   compilation_thread_started = 1;
257
   if (getenv("RELEASE_GVL"))
258
      rb_thread_call_without_gvl2(vm_compile_thread,             /* func */ 
259
                                 (void*)vm,                     /* func arg */   
260
                                 unblock_compilation_thread,    /* unblock func */
261
                                 &compilation_thread_started);  /* unblock arg */
262
   else 
263
      vm_compile_thread(vm); 
264

  
265
   async_trace( "inside %s, rb_thread_call_without_gvl has returned. Returning Qnil\n",__FUNCTION__); 
266
   return Qnil;
267
   }
268

  
269
void
270
kickoff_thread(rb_vm_t* vm) 
271
{
272
   typedef VALUE (*thread_function)(ANYARGS);
273
   async_trace("calling thread create");
274
   rb_thread_create((thread_function)(releaseGVLandStartCompilationThread),vm);
275
   async_trace("Thread create returned");
276

  
277
}
278

  
233 279
static int
234 280
ruby_exec_internal(void *n)
235 281
{
......
239 285

  
240 286
    if (!n) return 0;
241 287

  
288
    if (getenv("ASYNC_COMPILATION_TRACE"))
289
       kickoff_thread(GET_VM()); 
290

  
242 291
    TH_PUSH_TAG(th);
243 292
    if ((state = EXEC_TAG()) == 0) {
244 293
	SAVE_ROOT_JMPBUF(th, {
repro.sh
1
for i in `seq 1 10`; do RELEASE_GVL=1 ASYNC_COMPILATION_TRACE=1 ./miniruby test.rb -zzz=678 || exit; done; 
test.rb
1
#! /usr/local/bin/ruby -s
2
print "#{$zzz}\n"
0
-