Skip to content
Snippets Groups Projects
misc.c 32.3 KiB
Newer Older
tromey's avatar
tromey committed
}

void GC_err_puts(s)
GC_CONST char *s;
tromey's avatar
tromey committed
{
    if (WRITE(GC_stderr, s, strlen(s)) < 0) ABORT("write to stderr failed");
}

#if defined(LINUX) && !defined(SMALL_CONFIG)
void GC_err_write(buf, len)
GC_CONST char *buf;
size_t len;
{
    if (WRITE(GC_stderr, buf, len) < 0) ABORT("write to stderr failed");
}
#endif

tromey's avatar
tromey committed
# if defined(__STDC__) || defined(__cplusplus)
    void GC_default_warn_proc(char *msg, GC_word arg)
# else
    void GC_default_warn_proc(msg, arg)
    char *msg;
    GC_word arg;
# endif
{
    GC_err_printf1(msg, (unsigned long)arg);
}

GC_warn_proc GC_current_warn_proc = GC_default_warn_proc;

# if defined(__STDC__) || defined(__cplusplus)
    GC_warn_proc GC_set_warn_proc(GC_warn_proc p)
# else
    GC_warn_proc GC_set_warn_proc(p)
    GC_warn_proc p;
# endif
{
    GC_warn_proc result;

#   ifdef GC_WIN32_THREADS
      GC_ASSERT(GC_is_initialized);
#   endif
tromey's avatar
tromey committed
    LOCK();
    result = GC_current_warn_proc;
    GC_current_warn_proc = p;
    UNLOCK();
    return(result);
}

jsturm's avatar
jsturm committed
# if defined(__STDC__) || defined(__cplusplus)
    GC_word GC_set_free_space_divisor (GC_word value)
# else
    GC_word GC_set_free_space_divisor (value)
    GC_word value;
# endif
{
    GC_word old = GC_free_space_divisor;
    GC_free_space_divisor = value;
    return old;
}
tromey's avatar
tromey committed

#ifndef PCR
void GC_abort(msg)
GC_CONST char * msg;
tromey's avatar
tromey committed
{
#   if defined(MSWIN32)
      (void) MessageBoxA(NULL, msg, "Fatal error in gc", MB_ICONERROR|MB_OK);
#   else
      GC_err_printf1("%s\n", msg);
#   endif
    if (GETENV("GC_LOOP_ON_ABORT") != NULL) {
	    /* In many cases it's easier to debug a running process.	*/
	    /* It's arguably nicer to sleep, but that makes it harder	*/
	    /* to look at the thread if the debugger doesn't know much	*/
	    /* about threads.						*/
bryce's avatar
bryce committed
#   if defined(MSWIN32) || defined(MSWINCE)
	DebugBreak();
#   else
        (void) abort();
#   endif
tromey's avatar
tromey committed
}
#endif

void GC_enable()
{
jsturm's avatar
jsturm committed
    LOCK();
tromey's avatar
tromey committed
    GC_dont_gc--;
jsturm's avatar
jsturm committed
    UNLOCK();
tromey's avatar
tromey committed
}

void GC_disable()
{
jsturm's avatar
jsturm committed
    LOCK();
tromey's avatar
tromey committed
    GC_dont_gc++;
jsturm's avatar
jsturm committed
    UNLOCK();
tromey's avatar
tromey committed
}

bryce's avatar
bryce committed
/* Helper procedures for new kind creation.	*/
void ** GC_new_free_list_inner()
{
    void *result = GC_INTERNAL_MALLOC((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE);
    if (result == 0) ABORT("Failed to allocate freelist for new kind");
    BZERO(result, (MAXOBJSZ+1)*sizeof(ptr_t));
    return result;
}

void ** GC_new_free_list()
{
    void *result;
    LOCK(); DISABLE_SIGNALS();
    result = GC_new_free_list_inner();
    UNLOCK(); ENABLE_SIGNALS();
    return result;
}

int GC_new_kind_inner(fl, descr, adjust, clear)
void **fl;
GC_word descr;
int adjust;
int clear;
{
    int result = GC_n_kinds++;

    if (GC_n_kinds > MAXOBJKINDS) ABORT("Too many kinds");
    GC_obj_kinds[result].ok_freelist = (ptr_t *)fl;
    GC_obj_kinds[result].ok_reclaim_list = 0;
    GC_obj_kinds[result].ok_descriptor = descr;
    GC_obj_kinds[result].ok_relocate_descr = adjust;
    GC_obj_kinds[result].ok_init = clear;
    return result;
}

int GC_new_kind(fl, descr, adjust, clear)
void **fl;
GC_word descr;
int adjust;
int clear;
{
    int result;
    LOCK(); DISABLE_SIGNALS();
    result = GC_new_kind_inner(fl, descr, adjust, clear);
    UNLOCK(); ENABLE_SIGNALS();
    return result;
}

int GC_new_proc_inner(proc)
GC_mark_proc proc;
{
    int result = GC_n_mark_procs++;

    if (GC_n_mark_procs > MAX_MARK_PROCS) ABORT("Too many mark procedures");
    GC_mark_procs[result] = proc;
    return result;
}

int GC_new_proc(proc)
GC_mark_proc proc;
{
    int result;
    LOCK(); DISABLE_SIGNALS();
    result = GC_new_proc_inner(proc);
    UNLOCK(); ENABLE_SIGNALS();
    return result;
}


tromey's avatar
tromey committed
#if !defined(NO_DEBUGGING)

void GC_dump()
{
    GC_printf0("***Static roots:\n");
    GC_print_static_roots();
    GC_printf0("\n***Heap sections:\n");
    GC_print_heap_sects();
    GC_printf0("\n***Free blocks:\n");
    GC_print_hblkfreelist();
    GC_printf0("\n***Blocks in use:\n");
    GC_print_block_list();
jsturm's avatar
jsturm committed
    GC_printf0("\n***Finalization statistics:\n");
    GC_print_finalization_stats();
tromey's avatar
tromey committed
}

#endif /* NO_DEBUGGING */