[Gc] Feature request (portable use of GC_get_stack_base)

Ivan Maidanski ivmai at mail.ru
Thu Mar 5 05:12:21 PST 2009


Hi!

Consider we a have a library (that uses GC) with only 4 funcs: Init (called by user code from main threead), Attach/DetachCurrentThread, OurFunc (called by user code from non-main code between AttachCurrentThread and DetachCurrentThread calls). Let's user code knows nothing about GC.

Code for AttachCurrentThread and OurFunc:

__declspec(thread) int stack_sp_recorded = 0;

void AttachCurrentThread() {
  if (GC_get_stack_base(&sb) == GC_SUCCESS) {
    GC_register_my_thread(&sb); /* assume GC_SUCCESS */
    stack_sp_recorded = 1;
  }
  else GC_call_with_stack_base(<func>(psb){
         GC_register_my_thread(psb); /* assume GC_SUCCESS */
       });
}

void OurFunc(user_callback) {
  if (!stack_sp_recorded) {
    GC_call_with_stack_base(<func>(psb){
      GC_record_stack_sp(psb);//!!!
      stack_sp_recorded = 1;
      OurFunc(user_callback); /* safe to be inlined */
      stack_sp_recorded = 0;
    });
    return;
  }
  // our GC-sensitive code
  user_callback(); /* may call OurFunc() recursively */
  // our GC-sensitive code
}

Here I used non-existing GC_record_stack_sp(stack_base*).
Sample code for it:

void GC_record_stack_sp(stack_base *sb)
{
 LOCK();
 me = lookup_thread();
 assert me != 0;
 if (STACK_GROWS_DOWN ? me->stack_base < sp->mem_base :
     me->stack_base > sp->mem_base)
  me->stack_base = sp->mem_base;
 // same for me->backing_store_end
 UNLOCK();
}

Note: Of course, for this purpose GC_register_my_thread() functionality may be extended to have GC_record_stack_sp(sb) == { res = GC_register_my_thread(sb); assert res == GC_DUPLICATE; }

Now, consider single-threaded variant of the above library (having only Init() and OurFunc()). OurFunc() implementation is the same as for MT case.

Code for Init (in fact, this code is the same as for MT case too):

void Init() {
  GC_INIT(); /* calls GC_get_stack_base (or similar) internally */
  if (GC_get_stack_base(&sb) == GC_SUCCESS) {
    stack_sp_recorded = 1;
    // our GC-sensitive code (may also call OurFunc)
  } else {
    GC_call_with_stack_base(<func>(psb){
      GC_record_stack_sp(psb);
      stack_sp_recorded = 1;
      // our GC-sensitive code (may also call OurFunc)
      stack_sp_recorded = 0;
    });
  }
}

Any comments, objections, opinions?

Bye.


More information about the Gc mailing list