Back to index

plt-scheme  4.2.1
Defines | Functions | Variables
misc.c File Reference
#include <stdio.h>
#include <limits.h>
#include <signal.h>
#include "private/gc_pmark.h"
#include <unistd.h>

Go to the source code of this file.

Defines

#define I_HIDE_POINTERS   /* To make GC_call_with_alloc_lock visible */
#define GC_REGISTER_MAIN_STATIC_DATA()   TRUE
#define CLEAR_SIZE   213 /* Granularity for GC_clear_stack_inner */
#define DEGRADE_RATE   50
#define SLOP   400
#define GC_SLOP   4000
#define CLEAR_THRESHOLD   100000
#define GC_no_win32_dlls   FALSE
#define maybe_install_looping_handler()
#define WRITE(f, buf, len)   GC_write((f), (buf), (len))

Functions

void GC_check_heap GC_PROTO ((void))
GC_PTR GC_default_oom_fn GC_PROTO ((size_t bytes_requested))
voidGC_project2 (void *arg1, void *arg2)
ptr_t GC_clear_stack_inner (ptr_t arg, word limit)
ptr_t GC_clear_stack (ptr_t arg)
GC_PTR GC_base (GC_PTR p)
size_t GC_size (GC_PTR p)
size_t GC_get_heap_size GC_PROTO (())
void GC_init ()
void GC_setpagesize ()
void GC_init_inner ()
int GC_write (int fd, GC_CONST char *buf, size_t len)
void GC_printf (GC_CONST char *format, long a, long b, long c, long d, long e, long f)
void GC_err_printf (GC_CONST char *format, long a, long b, long c, long d, long e, long f)
void GC_err_puts (GC_CONST char *s)
void GC_default_warn_proc (char *msg, GC_word arg)
GC_warn_proc GC_set_warn_proc (GC_warn_proc p)
GC_word GC_set_free_space_divisor (GC_word value)
void GC_abort (GC_CONST char *msg)
void GC_enable ()
void GC_disable ()
void ** GC_new_free_list_inner ()
void ** GC_new_free_list ()
int GC_new_kind_inner (void **fl, GC_word descr, int adjust, int clear)
int GC_new_kind (void **fl, GC_word descr, int adjust, int clear)
int GC_new_proc_inner (GC_mark_proc proc)
int GC_new_proc (GC_mark_proc proc)
void GC_dump ()
static void get_size (struct hblk *h, word lptr)
long GC_get_memory_use ()

Variables

GC_FAR struct _GC_arrays
GC_bool GC_debugging_started = FALSE
ptr_t GC_stackbottom = 0
GC_bool GC_dont_gc = 0
GC_bool GC_dont_precollect = 0
GC_bool GC_quiet = 0
GC_bool GC_print_stats = 0
GC_bool GC_print_back_height = 0
GC_bool GC_dump_regularly = 0
int GC_find_leak = 0
int GC_all_interior_pointers = 0
long GC_large_alloc_warn_interval = 5
long GC_large_alloc_warn_suppressed = 0
signed_word GC_mem_found
word GC_stack_last_cleared = 0
word GC_min_sp
word GC_high_water
word GC_words_allocd_at_reset
GC_bool GC_is_initialized = FALSE
int GC_stdout = 1
int GC_stderr = 2
GC_warn_proc GC_current_warn_proc = GC_default_warn_proc

Define Documentation

#define CLEAR_SIZE   213 /* Granularity for GC_clear_stack_inner */

Definition at line 274 of file misc.c.

#define CLEAR_THRESHOLD   100000
#define DEGRADE_RATE   50

Definition at line 275 of file misc.c.

#define GC_no_win32_dlls   FALSE

Definition at line 535 of file misc.c.

Definition at line 89 of file misc.c.

#define GC_SLOP   4000
#define I_HIDE_POINTERS   /* To make GC_call_with_alloc_lock visible */

Definition at line 24 of file misc.c.

Definition at line 572 of file misc.c.

#define SLOP   400
#define WRITE (   f,
  buf,
  len 
)    GC_write((f), (buf), (len))

Definition at line 968 of file misc.c.


Function Documentation

void GC_abort ( GC_CONST char *  msg)

Definition at line 1063 of file misc.c.

{
#   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.                                          */
           for(;;) {}
    }
#   if defined(MSWIN32) || defined(MSWINCE)
       DebugBreak();
#   else
        (void) abort();
#   endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 389 of file misc.c.

{
    register word r;
    register struct hblk *h;
    register bottom_index *bi;
    register hdr *candidate_hdr;
    register word limit;
    
    r = (word)p;
    if (!GC_is_initialized) return 0;
    h = HBLKPTR(r);
    GET_BI(r, bi);
    candidate_hdr = HDR_FROM_BI(bi, r);
    if (candidate_hdr == 0) return(0);
    /* If it's a pointer to the middle of a large object, move it     */
    /* to the beginning.                                       */
       while (IS_FORWARDING_ADDR_OR_NIL(candidate_hdr)) {
          h = FORWARDED_ADDR(h,candidate_hdr);
          r = (word)h;
          candidate_hdr = HDR(h);
       }
    if (candidate_hdr -> hb_map == GC_invalid_map) return(0);
    /* Make sure r points to the beginning of the object */
       r &= ~(WORDS_TO_BYTES(1) - 1);
        {
           register int offset = HBLKDISPL(r);
           register signed_word sz = candidate_hdr -> hb_sz;
           register signed_word map_entry;
             
           map_entry = MAP_ENTRY((candidate_hdr -> hb_map), offset);
           if (map_entry > CPP_MAX_OFFSET) {
              map_entry = (signed_word)(BYTES_TO_WORDS(offset)) % sz;
            }
            r -= WORDS_TO_BYTES(map_entry);
            limit = r + WORDS_TO_BYTES(sz);
           if (limit > (word)(h + 1)
               && sz <= BYTES_TO_WORDS(HBLKSIZE)) {
               return(0);
           }
           if ((word)p >= limit) return(0);
       }
    return((GC_PTR)r);
}

Here is the caller graph for this function:

Definition at line 311 of file misc.c.

{
    register word sp = (word)GC_approx_sp();  /* Hotter than actual sp */
#   ifdef THREADS
        word dummy[SMALL_CLEAR_SIZE];
       static unsigned random_no = 0;
                                    /* Should be more random than it is ... */
                             /* Used to occasionally clear a bigger    */
                             /* chunk.                          */
#   endif
    register word limit;
    
#   define SLOP 400
       /* Extra bytes we clear every time.  This clears our own       */
       /* activation record, and should cause more frequent           */
       /* clearing near the cold end of the stack, a good thing.      */
#   define GC_SLOP 4000
       /* We make GC_high_water this much hotter than we really saw          */
       /* saw it, to cover for GC noise etc. above our current frame. */
#   define CLEAR_THRESHOLD 100000
       /* We restart the clearing process after this many bytes of    */
       /* allocation.  Otherwise very heavily recursive programs      */
       /* with sparse stacks may result in heaps that grow almost     */
       /* without bounds.  As the heap gets larger, collection        */
       /* frequency decreases, thus clearing frequency would decrease, */
       /* thus more junk remains accessible, thus the heap gets       */
       /* larger ...                                           */
# ifdef THREADS
    if (++random_no % 13 == 0) {
       limit = sp;
       MAKE_HOTTER(limit, BIG_CLEAR_SIZE*sizeof(word));
        limit &= ~0xf;      /* Make it sufficiently aligned for assembly     */
                     /* implementations of GC_clear_stack_inner.      */
       return GC_clear_stack_inner(arg, limit);
    } else {
       BZERO(dummy, SMALL_CLEAR_SIZE*sizeof(word));
       return arg;
    }
# else
    if (GC_gc_no > GC_stack_last_cleared) {
        /* Start things over, so we clear the entire stack again */
        if (GC_stack_last_cleared == 0) GC_high_water = (word) GC_stackbottom;
        GC_min_sp = GC_high_water;
        GC_stack_last_cleared = GC_gc_no;
        GC_words_allocd_at_reset = GC_words_allocd;
    }
    /* Adjust GC_high_water */
        MAKE_COOLER(GC_high_water, WORDS_TO_BYTES(DEGRADE_RATE) + GC_SLOP);
        if (sp HOTTER_THAN GC_high_water) {
            GC_high_water = sp;
        }
        MAKE_HOTTER(GC_high_water, GC_SLOP);
    limit = GC_min_sp;
    MAKE_HOTTER(limit, SLOP);
    if (sp COOLER_THAN limit) {
        limit &= ~0xf;      /* Make it sufficiently aligned for assembly     */
                     /* implementations of GC_clear_stack_inner.      */
        GC_min_sp = sp;
        return(GC_clear_stack_inner(arg, limit));
    } else if (WORDS_TO_BYTES(GC_words_allocd - GC_words_allocd_at_reset)
              > CLEAR_THRESHOLD) {
       /* Restart clearing process, but limit how much clearing we do. */
       GC_min_sp = sp;
       MAKE_HOTTER(GC_min_sp, CLEAR_THRESHOLD/4);
       if (GC_min_sp HOTTER_THAN GC_high_water) GC_min_sp = GC_high_water;
       GC_words_allocd_at_reset = GC_words_allocd;
    }  
    return(arg);
# endif
}

Here is the call graph for this function:

ptr_t GC_clear_stack_inner ( ptr_t  arg,
word  limit 
)

Definition at line 291 of file misc.c.

{
    word dummy[CLEAR_SIZE];
    
    BZERO(dummy, CLEAR_SIZE*sizeof(word));
    if ((word)(dummy) COOLER_THAN limit) {
        (void) GC_clear_stack_inner(arg, limit);
    }
    /* Make sure the recursive call is not a tail call, and the bzero */
    /* call is not recognized as dead code.                           */
    GC_noop1((word)dummy);
    return(arg);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void GC_default_warn_proc ( char *  msg,
GC_word  arg 
)

Definition at line 1021 of file misc.c.

{
    GC_err_printf1(msg, (unsigned long)arg);
}

Definition at line 1093 of file misc.c.

{
    LOCK();
    GC_dont_gc++;
    UNLOCK();
}
void GC_dump ( void  )

Definition at line 1171 of file misc.c.

{
    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();
    GC_printf0("\n***Finalization statistics:\n");
    GC_print_finalization_stats();
}

Here is the caller graph for this function:

Definition at line 1086 of file misc.c.

{
    LOCK();
    GC_dont_gc--;
    UNLOCK();
}
void GC_err_printf ( GC_CONST char *  format,
long  a,
long  b,
long  c,
long  d,
long  e,
long  f 
)

Definition at line 991 of file misc.c.

{
    char buf[1025];
    
    buf[1024] = 0x15;
    (void) sprintf(buf, format, a, b, c, d, e, f);
    if (buf[1024] != 0x15) ABORT("GC_err_printf clobbered stack");
    if (WRITE(GC_stderr, buf, strlen(buf)) < 0) ABORT("write to stderr failed");
}

Here is the call graph for this function:

void GC_err_puts ( GC_CONST char *  s)

Definition at line 1003 of file misc.c.

{
    if (WRITE(GC_stderr, s, strlen(s)) < 0) ABORT("write to stderr failed");
}

Here is the caller graph for this function:

long GC_get_memory_use ( void  )

Definition at line 1198 of file misc.c.

{
  long c = 0;
  LOCK();
  GC_apply_to_all_blocks(get_size, (word)&c);
  UNLOCK();
  return c;
}

Definition at line 475 of file misc.c.

{
    DCL_LOCK_STATE;
    
    DISABLE_SIGNALS();

#if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS)
    if (!GC_is_initialized) {
      BOOL (WINAPI *pfn) (LPCRITICAL_SECTION, DWORD) = NULL;
      HMODULE hK32 = GetModuleHandleA("kernel32.dll");
      if (hK32)
         pfn = (BOOL (WINAPI *) (LPCRITICAL_SECTION, DWORD))
              GetProcAddress (hK32,
                            "InitializeCriticalSectionAndSpinCount");
      if (pfn)
          pfn(&GC_allocate_ml, 4000);
      else
         InitializeCriticalSection (&GC_allocate_ml);
    }
#endif /* MSWIN32 */

    LOCK();
    GC_init_inner();
    UNLOCK();
    ENABLE_SIGNALS();

#   if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC)
       /* Make sure marker threads and started and thread local */
       /* allocation is initialized, in case we didn't get      */
       /* called from GC_init_parallel();                */
        {
         extern void GC_init_parallel(void);
         GC_init_parallel();
       }
#   endif /* PARALLEL_MARK || THREAD_LOCAL_ALLOC */

#   if defined(DYNAMIC_LOADING) && defined(DARWIN)
    {
        /* This must be called WITHOUT the allocation lock held
        and before any threads are created */
        extern void GC_init_dyld();
        GC_init_dyld();
    }
#   endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 576 of file misc.c.

{
#   if !defined(THREADS) && defined(GC_ASSERTIONS)
        word dummy;
#   endif
    word initial_heap_sz = (word)MINHINCR;
    
    if (GC_is_initialized) return;
#   ifdef PRINTSTATS
      GC_print_stats = 1;
#   endif
#   if defined(MSWIN32) || defined(MSWINCE)
      InitializeCriticalSection(&GC_write_cs);
#   endif
    if (0 != GETENV("GC_PRINT_STATS")) {
      GC_print_stats = 1;
    } 
#   ifndef NO_DEBUGGING
      if (0 != GETENV("GC_DUMP_REGULARLY")) {
        GC_dump_regularly = 1;
      }
#   endif
#   ifdef KEEP_BACK_PTRS
      {
        char * backtraces_string = GETENV("GC_BACKTRACES");
        if (0 != backtraces_string) {
          GC_backtraces = atol(backtraces_string);
         if (backtraces_string[0] == '\0') GC_backtraces = 1;
        }
      }
#   endif
    if (0 != GETENV("GC_FIND_LEAK")) {
      GC_find_leak = 1;
#     ifdef __STDC__
        atexit(GC_exit_check);
#     endif
    }
    if (0 != GETENV("GC_ALL_INTERIOR_POINTERS")) {
      GC_all_interior_pointers = 1;
    }
    if (0 != GETENV("GC_DONT_GC")) {
      GC_dont_gc = 1;
    }
    if (0 != GETENV("GC_PRINT_BACK_HEIGHT")) {
      GC_print_back_height = 1;
    }
    if (0 != GETENV("GC_NO_BLACKLIST_WARNING")) {
      GC_large_alloc_warn_interval = LONG_MAX;
    }
    {
      char * time_limit_string = GETENV("GC_PAUSE_TIME_TARGET");
      if (0 != time_limit_string) {
        long time_limit = atol(time_limit_string);
        if (time_limit < 5) {
         WARN("GC_PAUSE_TIME_TARGET environment variable value too small "
              "or bad syntax: Ignoring\n", 0);
        } else {
         GC_time_limit = time_limit;
        }
      }
    }
    {
      char * interval_string = GETENV("GC_LARGE_ALLOC_WARN_INTERVAL");
      if (0 != interval_string) {
        long interval = atol(interval_string);
        if (interval <= 0) {
         WARN("GC_LARGE_ALLOC_WARN_INTERVAL environment variable has "
              "bad value: Ignoring\n", 0);
        } else {
         GC_large_alloc_warn_interval = interval;
        }
      }
    }
    maybe_install_looping_handler();
    /* Adjust normal object descriptor for extra allocation.   */
    if (ALIGNMENT > GC_DS_TAGS && EXTRA_BYTES != 0) {
      GC_obj_kinds[NORMAL].ok_descriptor = ((word)(-ALIGNMENT) | GC_DS_LENGTH);
    }
    GC_setpagesize();
    GC_exclude_static_roots(beginGC_arrays, endGC_arrays);
    GC_exclude_static_roots(beginGC_obj_kinds, endGC_obj_kinds);
#   ifdef SEPARATE_GLOBALS
      GC_exclude_static_roots(beginGC_objfreelist, endGC_objfreelist);
      GC_exclude_static_roots(beginGC_aobjfreelist, endGC_aobjfreelist);
#   endif
#   ifdef MSWIN32
       GC_init_win32();
#   endif
#   if defined(SEARCH_FOR_DATA_START)
       GC_init_linux_data_start();
#   endif
#   if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__)
       if (!GC_no_dls) /* PLTSCHEME: hack */
         GC_init_netbsd_elf();
#   endif
#   if defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS) \
       || defined(GC_WIN32_THREADS)
        GC_thr_init();
#   endif
#   ifdef GC_SOLARIS_THREADS
       /* We need dirty bits in order to find live stack sections.    */
        GC_dirty_init();
#   endif
#   if !defined(THREADS) || defined(GC_PTHREADS) || defined(GC_WIN32_THREADS) \
       || defined(GC_SOLARIS_THREADS)
      if (GC_stackbottom == 0) {
       GC_stackbottom = GC_get_stack_base();
#       if (defined(LINUX) || defined(HPUX)) && defined(IA64)
         GC_register_stackbottom = GC_get_register_stack_base();
#       endif
      } else {
#       if (defined(LINUX) || defined(HPUX)) && defined(IA64)
         if (GC_register_stackbottom == 0) {
           WARN("GC_register_stackbottom should be set with GC_stackbottom", 0);
           /* The following may fail, since we may rely on            */
           /* alignment properties that may not hold with a user set  */
           /* GC_stackbottom.                                         */
           GC_register_stackbottom = GC_get_register_stack_base();
         }
#      endif
      }
#   endif
    GC_STATIC_ASSERT(sizeof (ptr_t) == sizeof(word));
    GC_STATIC_ASSERT(sizeof (signed_word) == sizeof(word));
    GC_STATIC_ASSERT(sizeof (struct hblk) == HBLKSIZE);
#   ifndef THREADS
#     if defined(STACK_GROWS_UP) && defined(STACK_GROWS_DOWN)
       ABORT(
         "Only one of STACK_GROWS_UP and STACK_GROWS_DOWN should be defd\n");
#     endif
#     if !defined(STACK_GROWS_UP) && !defined(STACK_GROWS_DOWN)
       ABORT(
         "One of STACK_GROWS_UP and STACK_GROWS_DOWN should be defd\n");
#     endif
#     ifdef STACK_GROWS_DOWN
        GC_ASSERT((word)(&dummy) <= (word)GC_stackbottom);
#     else
        GC_ASSERT((word)(&dummy) >= (word)GC_stackbottom);
#     endif
#   endif
#   if !defined(_AUX_SOURCE) || defined(__GNUC__)
      GC_ASSERT((word)(-1) > (word)0);
      /* word should be unsigned */
#   endif
    GC_ASSERT((signed_word)(-1) < (signed_word)0);
    
    /* Add initial guess of root sets.  Do this first, since sbrk(0)  */
    /* might be used.                                                 */
    if (!GC_no_dls) /* PLTSCHEME: hack */
      if (GC_REGISTER_MAIN_STATIC_DATA()) GC_register_data_segments();
    GC_init_headers();
    GC_bl_init();
    GC_mark_init();
    {
       char * sz_str = GETENV("GC_INITIAL_HEAP_SIZE");
       if (sz_str != NULL) {
         initial_heap_sz = atoi(sz_str);
         if (initial_heap_sz <= MINHINCR * HBLKSIZE) {
           WARN("Bad initial heap size %s - ignoring it.\n",
               sz_str);
         } 
         initial_heap_sz = divHBLKSZ(initial_heap_sz);
       }
    }
    {
       char * sz_str = GETENV("GC_MAXIMUM_HEAP_SIZE");
       if (sz_str != NULL) {
         word max_heap_sz = (word)atol(sz_str);
         if (max_heap_sz < initial_heap_sz * HBLKSIZE) {
           WARN("Bad maximum heap size %s - ignoring it.\n",
               sz_str);
         } 
         if (0 == GC_max_retries) GC_max_retries = 2;
         GC_set_max_heap_size(max_heap_sz);
       }
    }
    if (!GC_expand_hp_inner(initial_heap_sz)) {
        GC_err_printf0("Can't start up: not enough memory\n");
        EXIT();
    }
    /* Preallocate large object map.  It's otherwise inconvenient to  */
    /* deal with failure.                                      */
      if (!GC_add_map_entry((word)0)) {
        GC_err_printf0("Can't start up: not enough memory\n");
        EXIT();
      }
    GC_register_displacement_inner(0L);
#   ifdef MERGE_SIZES
      GC_init_size_map();
#   endif
#   ifdef PCR
      if (PCR_IL_Lock(PCR_Bool_false, PCR_allSigsBlocked, PCR_waitForever)
          != PCR_ERes_okay) {
          ABORT("Can't lock load state\n");
      } else if (PCR_IL_Unlock() != PCR_ERes_okay) {
          ABORT("Can't unlock load state\n");
      }
      PCR_IL_Unlock();
      GC_pcr_install();
#   endif
#   if !defined(SMALL_CONFIG)
      if (!GC_no_win32_dlls && 0 != GETENV("GC_ENABLE_INCREMENTAL")) {
       GC_ASSERT(!GC_incremental);
        GC_setpagesize();
#       ifndef GC_SOLARIS_THREADS
          GC_dirty_init();
#       endif
        GC_ASSERT(GC_words_allocd == 0)
       GC_incremental = TRUE;
      }
#   endif /* !SMALL_CONFIG */
    COND_DUMP;
    /* Get black list set up and/or incremental GC started */
      if (!GC_dont_precollect || GC_incremental) GC_gcollect_inner();
    GC_is_initialized = TRUE;
#   ifdef STUBBORN_ALLOC
       GC_stubborn_init();
#   endif
    /* Convince lint that some things are used */
#   ifdef LINT
      {
          extern char * GC_copyright[];
          extern int GC_read();
          extern void GC_register_finalizer_no_order();
          
          GC_noop(GC_copyright, GC_find_header,
                  GC_push_one, GC_call_with_alloc_lock, GC_read,
                  GC_dont_expand,
#               ifndef NO_DEBUGGING
                  GC_dump,
#               endif
                  GC_register_finalizer_no_order);
      }
#   endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1109 of file misc.c.

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

Here is the call graph for this function:

Definition at line 1101 of file misc.c.

{
    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;
}

Here is the caller graph for this function:

int GC_new_kind ( void **  fl,
GC_word  descr,
int  adjust,
int  clear 
)

Definition at line 1135 of file misc.c.

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

Here is the call graph for this function:

int GC_new_kind_inner ( void **  fl,
GC_word  descr,
int  adjust,
int  clear 
)

Definition at line 1118 of file misc.c.

{
    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;
}

Here is the caller graph for this function:

int GC_new_proc ( GC_mark_proc  proc)

Definition at line 1158 of file misc.c.

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

Here is the call graph for this function:

int GC_new_proc_inner ( GC_mark_proc  proc)

Definition at line 1148 of file misc.c.

{
    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;
}

Here is the caller graph for this function:

void GC_printf ( GC_CONST char *  format,
long  a,
long  b,
long  c,
long  d,
long  e,
long  f 
)

Definition at line 978 of file misc.c.

{
    char buf[1025];
    
    if (GC_quiet) return;
    buf[1024] = 0x15;
    (void) sprintf(buf, format, a, b, c, d, e, f);
    if (buf[1024] != 0x15) ABORT("GC_printf clobbered stack");
    if (WRITE(GC_stdout, buf, strlen(buf)) < 0) ABORT("write to stdout failed");
}

Here is the call graph for this function:

void* GC_project2 ( void arg1,
void arg2 
)

Definition at line 156 of file misc.c.

{
  return arg2;
}
void GC_check_heap GC_PROTO ( (void )

Definition at line 117 of file alloc.c.

{ return(0); }
GC_PTR GC_default_oom_fn GC_PROTO ( (size_t bytes_requested)  )

Definition at line 147 of file misc.c.

{
    return(0);
}
size_t GC_get_heap_size GC_PROTO ( ()  )

Definition at line 453 of file misc.c.

{
    return ((size_t) GC_heapsize);
}

Definition at line 1053 of file misc.c.

GC_warn_proc GC_set_warn_proc ( GC_warn_proc  p)

Definition at line 1034 of file misc.c.

{
    GC_warn_proc result;

#   ifdef GC_WIN32_THREADS
      GC_ASSERT(GC_is_initialized);
#   endif
    LOCK();
    result = GC_current_warn_proc;
    GC_current_warn_proc = p;
    UNLOCK();
    return(result);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 601 of file os_dep.c.

Here is the caller graph for this function:

size_t GC_size ( GC_PTR  p)

Definition at line 442 of file misc.c.

{
    register int sz;
    register hdr * hhdr = HDR(p);
    
    sz = WORDS_TO_BYTES(hhdr -> hb_sz);
    return(sz);
}

Here is the caller graph for this function:

int GC_write ( int  fd,
GC_CONST char *  buf,
size_t  len 
)

Definition at line 921 of file misc.c.

{
     register int bytes_written = 0;
     register int result;
     
     while (bytes_written < len) {
#      ifdef GC_SOLARIS_THREADS
           result = syscall(SYS_write, fd, buf + bytes_written,
                                       len - bytes_written);
#      else
           result = write(fd, buf + bytes_written, len - bytes_written);
#      endif
       if (-1 == result) return(result);
       bytes_written += result;
    }
    return(bytes_written);
}
static void get_size ( struct hblk h,
word  lptr 
) [static]

Definition at line 1188 of file misc.c.

{
  hdr *hhdr = HDR(h);
  long bytes = WORDS_TO_BYTES(hhdr->hb_sz);

  bytes += HBLKSIZE-1;
  bytes &= ~(HBLKSIZE-1);

  *(long *)lptr += bytes;
}

Here is the caller graph for this function:


Variable Documentation

Definition at line 92 of file misc.c.

Definition at line 137 of file misc.c.

Definition at line 1029 of file misc.c.

Definition at line 95 of file misc.c.

Definition at line 109 of file misc.c.

Definition at line 111 of file misc.c.

Definition at line 120 of file misc.c.

Definition at line 131 of file misc.c.

Definition at line 280 of file misc.c.

Definition at line 473 of file misc.c.

Definition at line 140 of file misc.c.

Definition at line 143 of file misc.c.

Definition at line 20 of file reclaim.c.

Definition at line 277 of file misc.c.

Definition at line 117 of file misc.c.

Definition at line 115 of file misc.c.

Definition at line 113 of file misc.c.

Definition at line 269 of file misc.c.

Definition at line 103 of file misc.c.

Definition at line 913 of file misc.c.

Definition at line 912 of file misc.c.

Definition at line 284 of file misc.c.