/*
**
** The C code is generated by ATS/Anairiats
** The compilation time is: 2013-8-30: 14h:38m
**
*/

/* include some .h files */
#ifndef _ATS_HEADER_NONE
#include "ats_config.h"
#include "ats_basics.h"
#include "ats_types.h"
#include "ats_exception.h"
#include "ats_memory.h"
#endif /* _ATS_HEADER_NONE */

/* include some .cats files */
#ifndef _ATS_PRELUDE_NONE
#include "prelude/CATS/basics.cats"
#include "prelude/CATS/bool.cats"
#include "prelude/CATS/char.cats"
#include "prelude/CATS/byte.cats"
#include "prelude/CATS/float.cats"
#include "prelude/CATS/integer.cats"
#include "prelude/CATS/integer_ptr.cats"
#include "prelude/CATS/integer_fixed.cats"
#include "prelude/CATS/sizetype.cats"
#include "prelude/CATS/pointer.cats"
#include "prelude/CATS/reference.cats"
#include "prelude/CATS/string.cats"
#include "prelude/CATS/lazy.cats"
#include "prelude/CATS/lazy_vt.cats"
#include "prelude/CATS/printf.cats"
#include "prelude/CATS/list.cats"
#include "prelude/CATS/option.cats"
#include "prelude/CATS/array.cats"
#include "prelude/CATS/matrix.cats"
#endif /* _ATS_PRELUDE_NONE */
/* prologues from statically loaded files */

/* external codes at top */
#line 51 "gcats1_top.dats"


int the_chunk_count = 0 ;
// a soft threshold that can be extended
int the_chunk_count_limit = 1 ;
// int the_chunk_count_limit = 1024 ;
// a hard threshold that cannot be extended
int the_chunk_count_limit_max = 8192 ;

// a list of freed chunk data
freeitmlst the_freeitmlst_chunk_data = (freeitmlst)0 ;

#ifdef _ATS_MULTITHREAD
// this is the lock that protects the previous variables
pthread_mutex_t the_gc_main_lock = PTHREAD_MUTEX_INITIALIZER ;
#endif // [_ATS_MULTITHREAD]

/* ****** ****** */

chunklst the_sweeplst_array[FREEITMLST_ARRAYSIZE] = { (chunklst)0 } ;

#ifdef _ATS_MULTITHREAD
pthread_mutex_t the_sweeplst_lock_array[FREEITMLST_ARRAYSIZE] ;

ats_void_type gc_sweeplst_lock_array_init () {
  int i ; pthread_mutex_t *p_lock ;
  i = 0 ; p_lock = the_sweeplst_lock_array ;
  while (i < FREEITMLST_ARRAYSIZE) { 
    pthread_mutex_init (p_lock, NULL); i += 1; p_lock += 1 ;
  }
/*
  fprintf (stderr, "the_sweeplst_lock_array has been initialized.\n") ;
*/
  return ;
}
#endif

/* ****** ****** */

#ifdef _ATS_MULTITHREAD
// __thread
// freeitmlst the_freeitmlst_array[FREEITMLST_ARRAYSIZE] =
//  { (freeitmlst)0 } ;
__thread freeitmlst *the_freeitmlst_array = (freeitmlst*)0 ;
#else /* single thread */
freeitmlst the_freeitmlst_array[FREEITMLST_ARRAYSIZE] =
  { (freeitmlst)0 } ;
#endif

/* ****** ****** */

// protecting [the_globalentrylst] in [gc_globalentrylst.dats]
#ifdef _ATS_MULTITHREAD
pthread_mutex_t the_globalentrylst_lock = PTHREAD_MUTEX_INITIALIZER ;
#endif

/* ****** ****** */

// manually managed list of allocated memories
manmemlst the_manmemlst = (manmemlst)0 ;
#ifdef _ATS_MULTITHREAD
pthread_mutex_t the_manmemlst_lock = PTHREAD_MUTEX_INITIALIZER ;
#endif

/* ****** ****** */

#ifdef _ATS_MULTITHREAD
pthread_mutex_t the_threadinfolst_lock = PTHREAD_MUTEX_INITIALIZER ;
#endif

/* ****** ****** */

#if (__WORDSIZE == 32)
botsegtbllst the_topsegtbl[TOPSEG_TABLESIZE] = { (botsegtbllst)0 } ;
#endif // end of [__WORDSIZE == 32]

#if (__WORDSIZE == 64)
botsegtbllst the_topsegtbl[TOPSEG_HASHTABLESIZE] = { (botsegtbllst)0 } ;
#endif // end of [__WORDSIZE == 64]

/* ****** ****** */

ats_int_type the_markstatck_overflow = 0 ;

// for debugging purpose
// ats_void_type segfault (void) { return *(int*)0 ; }


/* type definitions */
/* external typedefs */
/* external dynamic constructor declarations */
/* external dynamic constant declarations */
ATSextern_fun(ats_ptr_type, atspre_stdout_get) () ;
ATSextern_fun(ats_void_type, atspre_stdout_view_set) () ;
ATSextern_fun(ats_ptr_type, atspre_stderr_get) () ;
ATSextern_fun(ats_void_type, atspre_stderr_view_set) () ;
ATSextern_fun(ats_int_type, atspre_iadd) (ats_int_type, ats_int_type) ;
ATSextern_fun(ats_bool_type, atspre_ilt) (ats_int_type, ats_int_type) ;
ATSextern_fun(ats_void_type, atspre_fprintf_exn) (ats_ref_type, ats_ptr_type, ...) ;
ATSextern_fun(ats_int_type, gc_stack_dir_get) () ;
ATSextern_fun(ats_void_type, gc_stack_beg_set) (ats_int_type) ;
ATSextern_fun(ats_int_type, freeitmlst_length) (ats_ptr_type) ;
ATSextern_fun(ats_ptr_type, the_freeitmlst_array_get) (ats_int_type) ;
ATSextern_fun(ats_int_type, the_chunk_count_get) () ;
ATSextern_fun(ats_void_type, the_markstack_extend) (ats_int_type) ;
ATSextern_fun(ats_void_type, ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_2esats__gc_fprint_stats) (ats_ref_type) ;
ATSextern_fun(ats_ptr_type, freeitmlst_chunk_data_get) () ;

/* external dynamic terminating constant declarations */
#ifdef _ATS_PROOFCHECK
extern
ats_void_type ATS_2d0_2e2_2e10_2prelude_2basics_dyn_2esats__file_mode_lte_w_w_prfck () ;
#endif /* _ATS_PROOFCHECK */

/* assuming abstract types */
/* sum constructor declarations */
/* exn constructor declarations */
/* global dynamic (non-functional) constant declarations */
/* internal function declarations */
static
ats_void_type gcats1_top_loop_1 (ats_ref_type arg0, ats_int_type arg1) ;

/* partial value template declarations */
/* static temporary variable declarations */
ATSstatic (ats_int_type, gcats1_top_statmp21) ;
// ATSstatic_void (gcats1_top_statmp22) ;
// ATSstatic_void (gcats1_top_statmp23) ;

/* external value variable declarations */

/* function implementations */

/*
// /home/hwxi/research/Anairiats/ccomp/runtime/GCATS1/gcats1_top.dats: 5175(line=208, offs=7) -- 5490(line=218, offs=6)
*/
ATSstaticdec()
ats_void_type
gcats1_top_loop_1 (ats_ref_type arg0, ats_int_type arg1) {
/* local vardec */
// ATSlocal_void (tmp6) ;
ATSlocal (ats_bool_type, tmp7) ;
ATSlocal (ats_int_type, tmp8) ;
ATSlocal (ats_ptr_type, tmp9) ;
ATSlocal (ats_int_type, tmp10) ;
// ATSlocal_void (tmp11) ;
ATSlocal (ats_int_type, tmp12) ;

__ats_lab_gcats1_top_loop_1:
#line 210 "gcats1_top.dats"
tmp8 = atspre_iadd (11, 1) ;
#line 210 "gcats1_top.dats"
tmp7 = atspre_ilt (arg1, tmp8) ;
#line 210 "gcats1_top.dats"
if (tmp7) {
#line 211 "gcats1_top.dats"
tmp9 = the_freeitmlst_array_get (arg1) ;
#line 212 "gcats1_top.dats"
tmp10 = freeitmlst_length (tmp9) ;
#line 213 "gcats1_top.dats"
/* tmp11 = */ atspre_fprintf_exn (arg0, ATSstrcst("freeitmlst(%i):\t%i\n"), arg1, tmp10) ;
#line 216 "gcats1_top.dats"
tmp12 = atspre_iadd (arg1, 1) ;
#line 216 "gcats1_top.dats"
arg0 = arg0 ;
#line 216 "gcats1_top.dats"
arg1 = tmp12 ;
#line 216 "gcats1_top.dats"
goto __ats_lab_gcats1_top_loop_1 ; // tail call
} else {
/* empty */
} /* end of [if] */
return /* (tmp6) */ ;
} /* end of [gcats1_top_loop_1] */

/*
// /home/hwxi/research/Anairiats/ccomp/runtime/GCATS1/gcats1_top.dats: 4833(line=196, offs=31) -- 5550(line=222, offs=4)
*/
ATSglobaldec()
ats_void_type
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_2esats__gc_fprint_stats (ats_ref_type arg0) {
/* local vardec */
// ATSlocal_void (tmp0) ;
ATSlocal (ats_int_type, tmp1) ;
// ATSlocal_void (tmp2) ;
ATSlocal (ats_int_type, tmp3) ;
ATSlocal (ats_ptr_type, tmp4) ;
// ATSlocal_void (tmp5) ;

__ats_lab_ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_2esats__gc_fprint_stats:
#line 198 "gcats1_top.dats"
tmp1 = the_chunk_count_get () ;
#line 200 "gcats1_top.dats"
/* tmp2 = */ atspre_fprintf_exn (arg0, ATSstrcst("the_chunk_count:\t%i\n"), tmp1) ;
#line 203 "gcats1_top.dats"
tmp4 = freeitmlst_chunk_data_get () ;
#line 203 "gcats1_top.dats"
tmp3 = freeitmlst_length (tmp4) ;
#line 205 "gcats1_top.dats"
/* tmp5 = */ atspre_fprintf_exn (arg0, ATSstrcst("the_free_chunk_data_count:\t%i\n"), tmp3) ;
#line 219 "gcats1_top.dats"
/* tmp0 = */ gcats1_top_loop_1 (arg0, 0) ;
return /* (tmp0) */ ;
} /* end of [ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_2esats__gc_fprint_stats] */

/*
// /home/hwxi/research/Anairiats/ccomp/runtime/GCATS1/gcats1_top.dats: 5605(line=224, offs=26) -- 5785(line=231, offs=4)
*/
ATSglobaldec()
ats_void_type
gc_print_stats () {
/* local vardec */
// ATSlocal_void (tmp13) ;
ATSlocal (ats_ptr_type, tmp14) ;
ATSlocal (ats_ptr_type, tmp15) ;
// ATSlocal_void (tmp16) ;

__ats_lab_gc_print_stats:
#line 225 "gcats1_top.dats"
tmp14 = atspre_stdout_get () ;
#line 225 "gcats1_top.dats"
tmp15 = ats_selsin_mac(tmp14, atslab_1) ;
#line 227 "gcats1_top.dats"
/* tmp16 = */ ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_2esats__gc_fprint_stats (tmp15) ;
#line 230 "gcats1_top.dats"
/* tmp13 = */ atspre_stdout_view_set () ;
return /* (tmp13) */ ;
} /* end of [gc_print_stats] */

/*
// /home/hwxi/research/Anairiats/ccomp/runtime/GCATS1/gcats1_top.dats: 5839(line=233, offs=26) -- 6021(line=240, offs=4)
*/
ATSglobaldec()
ats_void_type
gc_prerr_stats () {
/* local vardec */
// ATSlocal_void (tmp17) ;
ATSlocal (ats_ptr_type, tmp18) ;
ATSlocal (ats_ptr_type, tmp19) ;
// ATSlocal_void (tmp20) ;

__ats_lab_gc_prerr_stats:
#line 234 "gcats1_top.dats"
tmp18 = atspre_stderr_get () ;
#line 234 "gcats1_top.dats"
tmp19 = ats_selsin_mac(tmp18, atslab_1) ;
#line 236 "gcats1_top.dats"
/* tmp20 = */ ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_2esats__gc_fprint_stats (tmp19) ;
#line 239 "gcats1_top.dats"
/* tmp17 = */ atspre_stderr_view_set () ;
return /* (tmp17) */ ;
} /* end of [gc_prerr_stats] */

/* static load function */

extern ats_void_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_2esats__staload (void) ;
extern ats_void_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_2esats__staload (void) ;

ats_void_type
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_top_2edats__staload () {
static int ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_top_2edats__staload_flag = 0 ;
if (ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_top_2edats__staload_flag) return ;
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_top_2edats__staload_flag = 1 ;

ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_2esats__staload () ;
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_2esats__staload () ;

return ;
} /* staload function */

/* dynamic load function */

ats_int_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_manops_2edats__dynload_flag = 0 ;
extern ats_void_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_manops_2edats__dynload (void) ;
ats_int_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_autops_2edats__dynload_flag = 0 ;
extern ats_void_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_autops_2edats__dynload (void) ;
ats_int_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_collecting_2edats__dynload_flag = 0 ;
extern ats_void_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_collecting_2edats__dynload (void) ;
ats_int_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_marking_2edats__dynload_flag = 0 ;
extern ats_void_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_marking_2edats__dynload (void) ;
ats_int_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_globalentry_2edats__dynload_flag = 0 ;
extern ats_void_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_globalentry_2edats__dynload (void) ;
ats_int_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_chunk_2edats__dynload_flag = 0 ;
extern ats_void_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_chunk_2edats__dynload (void) ;
ats_int_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_freeitmlst_2edats__dynload_flag = 0 ;
extern ats_void_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_freeitmlst_2edats__dynload (void) ;
ats_int_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_misc_2edats__dynload_flag = 0 ;
extern ats_void_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_misc_2edats__dynload (void) ;

// dynload flag declaration
// extern ats_int_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_top_2edats__dynload_flag ;

ats_void_type
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_top_2edats__dynload () {
// ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_top_2edats__dynload_flag = 1 ;
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_top_2edats__staload () ;

#ifdef _ATS_PROOFCHECK
ATS_2d0_2e2_2e10_2prelude_2basics_dyn_2esats__file_mode_lte_w_w_prfck () ;
#endif /* _ATS_PROOFCHECK */

/* marking static variables for GC */
ATS_GC_MARKROOT(&gcats1_top_statmp21, sizeof(ats_int_type)) ;

/* marking external values for GC */

/* code for dynamic loading */
#line 244 "gcats1_top.dats"
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_misc_2edats__dynload () ;
#line 245 "gcats1_top.dats"
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_freeitmlst_2edats__dynload () ;
#line 246 "gcats1_top.dats"
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_chunk_2edats__dynload () ;
#line 247 "gcats1_top.dats"
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_globalentry_2edats__dynload () ;
#line 251 "gcats1_top.dats"
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_marking_2edats__dynload () ;
#line 252 "gcats1_top.dats"
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_collecting_2edats__dynload () ;
#line 253 "gcats1_top.dats"
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_autops_2edats__dynload () ;
#line 254 "gcats1_top.dats"
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_manops_2edats__dynload () ;
#line 263 "gcats1_top.dats"
gcats1_top_statmp21 = gc_stack_dir_get () ;
#line 264 "gcats1_top.dats"
/* gcats1_top_statmp22 = */ gc_stack_beg_set (gcats1_top_statmp21) ;
#line 281 "gcats1_top.dats"
/* gcats1_top_statmp23 = */ the_markstack_extend (1) ;
return ;
} /* end of [dynload function] */

ats_void_type gc_init () {
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_top_2edats__dynload () ; return ;
}

/* external codes at mid */
/* external codes at bot */
#line 150 "gcats1_top.dats"


ats_int_type
gc_chunk_count_limit_get () {
  return the_chunk_count_limit ; 
}

ats_void_type
gc_chunk_count_limit_set (ats_int_type n) {
  if (n >= 0) {
    the_chunk_count_limit = n ;
  } else {
    fprintf (stderr, "GC Fatal Error: [gc_chunk_count_limit_set]: negative argument.\n") ;
    exit (1) ;
  }
  return ;
}

ats_int_type
gc_chunk_count_limit_max_get () {
  return the_chunk_count_limit_max ; 
}

ats_void_type
gc_chunk_count_limit_max_set (ats_int_type n) {
  the_chunk_count_limit_max = n ; return ;
}

#line 185 "gcats1_top.dats"


extern
ats_ptr_type the_freeitmlst_chunk_data ;

ats_ptr_type freeitmlst_chunk_data_get () {
  return the_freeitmlst_chunk_data ;
}

#line 293 "gcats1_top.dats"


ats_ptr_type
  the_globalentrylst = (ats_ptr_type)0 ; // GLOBALENTRYLSTnil
// end of ...

extern void globalentrylst_insert
  (ats_ref_type ents, ats_ptr_type ptr, ats_int_type wsz) ;

ats_void_type gc_markroot_bsz
  (ats_ptr_type ptr, ats_int_type bsz/*bytesize*/) {
  int wsz = (bsz >> NBYTE_PER_WORD_LOG) ;
/*
  fprintf (stderr, "gc_markroot_bsz: ptr = %p\n", ptr) ;
  fprintf (stderr, "gc_markroot_bsz: bsz = %i\n", bsz) ;
  fprintf (stderr, "gc_markroot_bsz: wsz = %i\n", wsz) ;
*/
  globalentrylst_insert (&the_globalentrylst, ptr, wsz) ;
  return ;
} /* end of [gc_markroot_bsz] */



/* ****** ****** */

/* end of [gcats1_top_dats.c] */
