Example #1
0
void GC_suspend_handler(int sig)
{
    int dummy;
    GC_thread me;
    sigset_t all_sigs;
    sigset_t old_sigs;
    int i;

    if (sig != SIG_SUSPEND) ABORT("Bad signal in suspend_handler");
    me = GC_lookup_thread(pthread_self());
    /* The lookup here is safe, since I'm doing this on behalf  */
    /* of a thread which holds the allocation lock in order	*/
    /* to stop the world.  Thus concurrent modification of the	*/
    /* data structure is impossible.				*/
    if (PLEASE_STOP != me -> stop) {
	/* Misdirected signal.	*/
	pthread_mutex_unlock(&GC_suspend_lock);
	return;
    }
    pthread_mutex_lock(&GC_suspend_lock);
    me -> stack_hot = (ptr_t)(&dummy);
    me -> stop = STOPPED;
    pthread_cond_signal(&GC_suspend_ack_cv);
    pthread_cond_wait(&GC_continue_cv, &GC_suspend_lock);
    pthread_mutex_unlock(&GC_suspend_lock);
    /* GC_printf1("Continuing 0x%x\n", pthread_self()); */
}
Example #2
0
GC_API int GC_register_my_thread(struct GC_stack_base *sb) {
  DWORD t = GetCurrentThreadId();

  if (0 == GC_lookup_thread(t)) {
    /* We lock here, since we want to wait for an ongoing GC.	*/
    LOCK();
    GC_register_my_thread_inner(sb, t);
    UNLOCK();
    return GC_SUCCESS;
  } else {
    return GC_DUPLICATE;
  }
}
Example #3
0
int GC_pthread_detach(pthread_t thread)
{
	GC_thread t;

	LOCK();
	t=GC_lookup_thread(thread);	
	UNLOCK();
	if (t) {
		LOCK();
		t->flags |= DETACHED;
		UNLOCK();
		return 0;
	}
	else
		return pthread_detach(thread);
}
Example #4
0
GC_PTR GC_local_malloc(size_t bytes)
{
    if (EXPECT(!SMALL_ENOUGH(bytes),0)) {
        return(GC_malloc(bytes));
    } else {
	int index = INDEX_FROM_BYTES(bytes);
	ptr_t * my_fl;
	ptr_t my_entry;
#	if defined(REDIRECT_MALLOC) && !defined(USE_PTHREAD_SPECIFIC)
	GC_key_t k = GC_thread_key;
#	endif
	void * tsd;

#	if defined(REDIRECT_MALLOC) && !defined(USE_PTHREAD_SPECIFIC)
	    if (EXPECT(0 == k, 0)) {
		/* This can happen if we get called when the world is	*/
		/* being initialized.  Whether we can actually complete	*/
		/* the initialization then is unclear.			*/
		GC_init_parallel();
		k = GC_thread_key;
	    }
#	endif
	tsd = GC_getspecific(GC_thread_key);
#	ifdef GC_ASSERTIONS
	  LOCK();
	  GC_ASSERT(tsd == (void *)GC_lookup_thread(pthread_self()));
	  UNLOCK();
#	endif
	my_fl = ((GC_thread)tsd) -> normal_freelists + index;
	my_entry = *my_fl;
	if (EXPECT((word)my_entry >= HBLKSIZE, 1)) {
	    ptr_t next = obj_link(my_entry);
	    GC_PTR result = (GC_PTR)my_entry;
	    *my_fl = next;
	    obj_link(my_entry) = 0;
	    PREFETCH_FOR_WRITE(next);
	    return result;
	} else if ((word)my_entry - 1 < DIRECT_GRANULES) {
	    *my_fl = my_entry + index + 1;
            return GC_malloc(bytes);
	} else {
	    GC_generic_malloc_many(BYTES_FROM_INDEX(index), NORMAL, my_fl);
	    if (*my_fl == 0) return GC_oom_fn(bytes);
	    return GC_local_malloc(bytes);
	}
    }
}
Example #5
0
/* Must be called before a second thread is created.	*/
void GC_init_parallel(void)
{
    if (parallel_initialized) return;
    parallel_initialized = TRUE;
    /* GC_init() calls us back, so set flag first.	*/
    
    if (!GC_is_initialized) GC_init();
    if (GC_win32_dll_threads) {
      GC_need_to_lock = TRUE;
	/* Cannot intercept thread creation.  Hence we don't know if	*/
	/* other threads exist.  However, client is not allowed to 	*/
	/* create other threads before collector initialization.	*/
	/* Thus it's OK not to lock before this.			*/
    }
    /* Initialize thread local free lists if used.	*/
#   if defined(THREAD_LOCAL_ALLOC)
      LOCK();
      GC_init_thread_local(&(GC_lookup_thread(GetCurrentThreadId())->tlfs));
      UNLOCK();
#   endif
}