Ejemplo n.º 1
0
/* survives in the child.					*/
void GC_remove_all_threads_but_me(void)
{
    pthread_t self = pthread_self();
    int hv;
    GC_thread p, next, me;

    for (hv = 0; hv < THREAD_TABLE_SZ; ++hv) {
      me = 0;
      for (p = GC_threads[hv]; 0 != p; p = next) {
	next = p -> next;
	if (THREAD_EQUAL(p -> id, self)) {
	  me = p;
	  p -> next = 0;
	} else {
#	  ifdef THREAD_LOCAL_ALLOC
	    if (!(p -> flags & FINISHED)) {
	      GC_destroy_thread_local(&(p->tlfs));
	    }
#	  endif /* THREAD_LOCAL_ALLOC */
	  if (p != &first_thread) GC_INTERNAL_FREE(p);
	}
      }
      GC_threads[hv] = me;
    }
}
Ejemplo n.º 2
0
/* thread being deleted.					*/
void GC_delete_thread(DWORD id)
{
  if (GC_win32_dll_threads) {
    GC_thread t = GC_lookup_thread_inner(id);

    if (0 == t) {
      WARN("Removing nonexistent thread %ld\n", (GC_word)id);
    } else {
      GC_delete_gc_thread(t);
    }
  } else {
    word hv = ((word)id) % THREAD_TABLE_SZ;
    register GC_thread p = GC_threads[hv];
    register GC_thread prev = 0;
    
    GC_ASSERT(I_HOLD_LOCK());
    while (p -> id != id) {
        prev = p;
        p = p -> next;
    }
    CloseHandle(p->handle);
    if (prev == 0) {
        GC_threads[hv] = p -> next;
    } else {
        prev -> next = p -> next;
    }
    GC_INTERNAL_FREE(p);
  }
}
Ejemplo n.º 3
0
  static GC_bool ensure_toggleref_capacity(int capacity_inc)
  {
    GC_ASSERT(capacity_inc >= 0);
    if (NULL == GC_toggleref_arr) {
      GC_toggleref_array_capacity = 32; /* initial capacity */
      GC_toggleref_arr = GC_INTERNAL_MALLOC_IGNORE_OFF_PAGE(
                        GC_toggleref_array_capacity * sizeof(GCToggleRef),
                        NORMAL);
      if (NULL == GC_toggleref_arr)
        return FALSE;
    }
    if ((unsigned)GC_toggleref_array_size + (unsigned)capacity_inc
        >= (unsigned)GC_toggleref_array_capacity) {
      GCToggleRef *new_array;
      while ((unsigned)GC_toggleref_array_capacity
              < (unsigned)GC_toggleref_array_size + (unsigned)capacity_inc) {
        GC_toggleref_array_capacity *= 2;
        if (GC_toggleref_array_capacity < 0) /* overflow */
          return FALSE;
      }

      new_array = GC_INTERNAL_MALLOC_IGNORE_OFF_PAGE(
                        GC_toggleref_array_capacity * sizeof(GCToggleRef),
                        NORMAL);
      if (NULL == new_array)
        return FALSE;
      BCOPY(GC_toggleref_arr, new_array,
            GC_toggleref_array_size * sizeof(GCToggleRef));
      GC_INTERNAL_FREE(GC_toggleref_arr);
      GC_toggleref_arr = new_array;
    }
    return TRUE;
  }
Ejemplo n.º 4
0
/* (The code intentionally traps if it wasn't.)			*/
void GC_delete_thread(pthread_t id)
{
    int hv = NUMERIC_THREAD_ID(id) % THREAD_TABLE_SZ;
    register GC_thread p = GC_threads[hv];
    register GC_thread prev = 0;
    
    GC_ASSERT(I_HOLD_LOCK());
    while (!THREAD_EQUAL(p -> id, id)) {
        prev = p;
        p = p -> next;
    }
    if (prev == 0) {
        GC_threads[hv] = p -> next;
    } else {
        prev -> next = p -> next;
    }
#   ifdef GC_DARWIN_THREADS
	mach_port_deallocate(mach_task_self(), p->stop_info.mach_thread);
#   endif
    GC_INTERNAL_FREE(p);
}
Ejemplo n.º 5
0
/* thread being deleted.					*/
void GC_delete_gc_thread(GC_vthread gc_id)
{
  CloseHandle(gc_id->handle);
  if (GC_win32_dll_threads) {
    /* This is intended to be lock-free.				*/
    /* It is either called synchronously from the thread being deleted,	*/
    /* or by the joining thread.					*/
    /* In this branch asynchronosu changes to *gc_id are possible.	*/
    gc_id -> stack_base = 0;
    gc_id -> id = 0;
#   ifdef CYGWIN32
      gc_id -> pthread_id = 0;
#   endif /* CYGWIN32 */
#   ifdef GC_WIN32_PTHREADS
      gc_id -> pthread_id.p = NULL;
#   endif /* GC_WIN32_PTHREADS */
    AO_store_release(&(gc_id->in_use), FALSE);
  } else {
    /* Cast away volatile qualifier, since we have lock. */
    GC_thread gc_nvid = (GC_thread)gc_id;
    DWORD id = gc_nvid -> id;
    word hv = ((word)id) % THREAD_TABLE_SZ;
    register GC_thread p = GC_threads[hv];
    register GC_thread prev = 0;

    GC_ASSERT(I_HOLD_LOCK());
    while (p != gc_nvid) {
        prev = p;
        p = p -> next;
    }
    if (prev == 0) {
        GC_threads[hv] = p -> next;
    } else {
        prev -> next = p -> next;
    }
    GC_INTERNAL_FREE(p);
  }
}