/*
**
** 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 */
/* type definitions */
/* external typedefs */
/* external dynamic constructor declarations */
/* external dynamic constant declarations */
ATSextern_fun(ats_void_type, atspre_prerr_newline) () ;
ATSextern_fun(ats_int_type, atspre_asl_int_int1) (ats_int_type, ats_int_type) ;
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_prerr_string) (ats_ptr_type) ;
ATSextern_fun(ats_void_type, gc_main_lock_acquire) () ;
ATSextern_fun(ats_void_type, gc_main_lock_release) () ;
ATSextern_fun(ats_void_type, the_globalentrylst_lock_acquire) () ;
ATSextern_fun(ats_void_type, the_globalentrylst_lock_release) () ;
ATSextern_fun(ats_void_type, the_manmemlst_lock_acquire) () ;
ATSextern_fun(ats_void_type, the_manmemlst_lock_release) () ;
ATSextern_fun(ats_void_type, the_threadinfolst_lock_acquire) () ;
ATSextern_fun(ats_void_type, the_threadinfolst_lock_release) () ;
ATSextern_fun(ats_void_type, the_sweeplst_lock_acquire_one) (ats_int_type) ;
ATSextern_fun(ats_void_type, the_sweeplst_lock_release_one) (ats_int_type) ;
ATSextern_fun(ats_void_type, the_sweeplst_lock_acquire_rest) (ats_int_type) ;
ATSextern_fun(ats_void_type, the_sweeplst_lock_release_rest) (ats_int_type) ;
ATSextern_fun(ats_bool_type, freeitmlst_is_nil) (ats_ptr_type) ;
ATSextern_fun(ats_bool_type, chunklst_is_cons) (ats_ptr_type) ;
ATSextern_fun(ats_ptr_type, chunklst_sweep_next_get) (ats_ptr_type) ;
ATSextern_fun(ats_ptr_type, chunklst_create_release) (ats_int_type, ats_int_type) ;
ATSextern_fun(ats_bool_type, the_chunk_count_limit_is_not_reached) () ;
ATSextern_fun(ats_ptr_type, botsegtbllst_get) (ats_ptr_type, ats_int_type) ;
ATSextern_fun(ats_ptr_type, the_sweeplst_array_get) (ats_int_type) ;
ATSextern_fun(ats_void_type, the_sweeplst_array_set) (ats_int_type, ats_ptr_type) ;
ATSextern_fun(ats_void_type, the_sweeplst_array_clear_one) (ats_int_type) ;
ATSextern_fun(ats_void_type, gc_collect) () ;
ATSextern_fun(ats_ptr_type, gc_chunk_threading) (ats_ptr_type) ;
ATSextern_fun(ats_void_type, the_sweeplst_array_clear_all) () ;
ATSextern_fun(ats_void_type, gc_sweeplst_build_chunk) (ats_ptr_type) ;
ATSextern_fun(ats_void_type, gc_sweeplst_build_botsegtbl) (ats_ptr_type) ;
ATSextern_fun(ats_void_type, fprint_the_sweeplst_array_all) () ;

/* external dynamic terminating constant declarations */
#ifdef _ATS_PROOFCHECK
extern
ats_void_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_2esats__sweeplst_lock_all_takeout_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_collecting_loop_1 (ats_int_type arg0) ;
static
ats_void_type gcats1_collecting_loop_3 (ats_ptr_type arg0, ats_int_type arg1) ;

/* partial value template declarations */
/* static temporary variable declarations */
/* external value variable declarations */

/* function implementations */

/*
// /home/hwxi/research/Anairiats/ccomp/runtime/GCATS1/gcats1_collecting.dats: 1953(line=61, offs=7) -- 2267(line=69, offs=8)
*/
ATSstaticdec()
ats_void_type
gcats1_collecting_loop_1 (ats_int_type arg0) {
/* local vardec */
// ATSlocal_void (tmp1) ;
ATSlocal (ats_bool_type, tmp2) ;
ATSlocal (ats_int_type, tmp3) ;
// ATSlocal_void (tmp4) ;
ATSlocal (ats_int_type, tmp5) ;

__ats_lab_gcats1_collecting_loop_1:
#line 63 "gcats1_collecting.dats"
tmp3 = atspre_iadd (11, 1) ;
#line 63 "gcats1_collecting.dats"
tmp2 = atspre_ilt (arg0, tmp3) ;
#line 63 "gcats1_collecting.dats"
if (tmp2) {
#line 65 "gcats1_collecting.dats"
/* tmp4 = */ the_sweeplst_array_clear_one (arg0) ;
#line 68 "gcats1_collecting.dats"
tmp5 = atspre_iadd (arg0, 1) ;
#line 68 "gcats1_collecting.dats"
arg0 = tmp5 ;
#line 68 "gcats1_collecting.dats"
goto __ats_lab_gcats1_collecting_loop_1 ; // tail call
} else {
/* empty */
} /* end of [if] */
return /* (tmp1) */ ;
} /* end of [gcats1_collecting_loop_1] */

/*
// /home/hwxi/research/Anairiats/ccomp/runtime/GCATS1/gcats1_collecting.dats: 1892(line=59, offs=40) -- 2305(line=72, offs=4)
*/
ATSglobaldec()
ats_void_type
the_sweeplst_array_clear_all () {
/* local vardec */
// ATSlocal_void (tmp0) ;

__ats_lab_the_sweeplst_array_clear_all:
#line 71 "gcats1_collecting.dats"
/* tmp0 = */ gcats1_collecting_loop_1 (0) ;
return /* (tmp0) */ ;
} /* end of [the_sweeplst_array_clear_all] */

/*
// /home/hwxi/research/Anairiats/ccomp/runtime/GCATS1/gcats1_collecting.dats: 2618(line=83, offs=7) -- 2964(line=92, offs=6)
*/
ATSstaticdec()
ats_void_type
gcats1_collecting_loop_3 (ats_ptr_type arg0, ats_int_type arg1) {
/* local vardec */
// ATSlocal_void (tmp7) ;
ATSlocal (ats_bool_type, tmp8) ;
ATSlocal (ats_ptr_type, tmp9) ;
// ATSlocal_void (tmp10) ;
ATSlocal (ats_bool_type, tmp11) ;
ATSlocal (ats_int_type, tmp12) ;

__ats_lab_gcats1_collecting_loop_3:
#line 85 "gcats1_collecting.dats"
tmp8 = atspre_ilt (arg1, 1024) ;
#line 85 "gcats1_collecting.dats"
if (tmp8) {
#line 86 "gcats1_collecting.dats"
tmp9 = botsegtbllst_get (arg0, arg1) ;
#line 87 "gcats1_collecting.dats"
tmp11 = chunklst_is_cons (tmp9) ;
#line 87 "gcats1_collecting.dats"
if (tmp11) {
#line 87 "gcats1_collecting.dats"
/* tmp10 = */ gc_sweeplst_build_chunk (tmp9) ;
} else {
/* empty */
} /* end of [if] */
#line 90 "gcats1_collecting.dats"
tmp12 = atspre_iadd (arg1, 1) ;
#line 90 "gcats1_collecting.dats"
arg0 = arg0 ;
#line 90 "gcats1_collecting.dats"
arg1 = tmp12 ;
#line 90 "gcats1_collecting.dats"
goto __ats_lab_gcats1_collecting_loop_3 ; // tail call
} else {
/* empty */
} /* end of [if] */
return /* (tmp7) */ ;
} /* end of [gcats1_collecting_loop_3] */

/*
// /home/hwxi/research/Anairiats/ccomp/runtime/GCATS1/gcats1_collecting.dats: 2599(line=82, offs=39) -- 3005(line=95, offs=4)
*/
ATSglobaldec()
ats_void_type
gc_sweeplst_build_botsegtbl (ats_ptr_type arg0) {
/* local vardec */
// ATSlocal_void (tmp6) ;

__ats_lab_gc_sweeplst_build_botsegtbl:
#line 94 "gcats1_collecting.dats"
/* tmp6 = */ gcats1_collecting_loop_3 (arg0, 0) ;
return /* (tmp6) */ ;
} /* end of [gc_sweeplst_build_botsegtbl] */

/*
// /home/hwxi/research/Anairiats/ccomp/runtime/GCATS1/gcats1_collecting.dats: 3190(line=102, offs=34) -- 6455(line=184, offs=4)
*/
ATSglobaldec()
ats_ptr_type
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_2esats__gc_freeitmlst_generate (ats_int_type arg0) {
/* local vardec */
ATSlocal (ats_ptr_type, tmp13) ;
// ATSlocal_void (tmp14) ;
// ATSlocal_void (tmp15) ;
ATSlocal (ats_ptr_type, tmp16) ;
ATSlocal (ats_ptr_type, tmp17) ;
ATSlocal (ats_bool_type, tmp18) ;
// ATSlocal_void (tmp19) ;
// ATSlocal_void (tmp20) ;
// ATSlocal_void (tmp21) ;
// ATSlocal_void (tmp22) ;
// ATSlocal_void (tmp23) ;
ATSlocal (ats_ptr_type, tmp24) ;
ATSlocal (ats_bool_type, tmp25) ;
// ATSlocal_void (tmp26) ;
ATSlocal (ats_bool_type, tmp27) ;
ATSlocal (ats_int_type, tmp28) ;
// ATSlocal_void (tmp29) ;
// ATSlocal_void (tmp30) ;
// ATSlocal_void (tmp31) ;
// ATSlocal_void (tmp32) ;
// ATSlocal_void (tmp33) ;
// ATSlocal_void (tmp34) ;
// ATSlocal_void (tmp35) ;
// ATSlocal_void (tmp36) ;
// ATSlocal_void (tmp37) ;
// ATSlocal_void (tmp38) ;
// ATSlocal_void (tmp39) ;
// ATSlocal_void (tmp40) ;
// ATSlocal_void (tmp41) ;
// ATSlocal_void (tmp42) ;
ATSlocal (ats_ptr_type, tmp43) ;
ATSlocal (ats_bool_type, tmp44) ;
// ATSlocal_void (tmp45) ;
ATSlocal (ats_int_type, tmp46) ;
ATSlocal (ats_ptr_type, tmp47) ;
// ATSlocal_void (tmp48) ;
// ATSlocal_void (tmp49) ;
ATSlocal (ats_ptr_type, tmp50) ;
ATSlocal (ats_bool_type, tmp51) ;
// ATSlocal_void (tmp52) ;
// ATSlocal_void (tmp53) ;
// ATSlocal_void (tmp54) ;

__ats_lab_ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_2esats__gc_freeitmlst_generate:
#line 110 "gcats1_collecting.dats"
/* tmp14 = */ the_sweeplst_lock_acquire_one (arg0) ;
#line 110 "gcats1_collecting.dats"
/* tmp15 = ats_selsin_mac(tmp14, atslab_1) */ ;
#line 111 "gcats1_collecting.dats"
tmp16 = the_sweeplst_array_get (arg0) ;
#line 113 "gcats1_collecting.dats"
tmp18 = chunklst_is_cons (tmp16) ;
#line 113 "gcats1_collecting.dats"
if (tmp18) {
#line 113 "gcats1_collecting.dats"
tmp17 = tmp16 ;
} else {
#line 114 "gcats1_collecting.dats"
/* tmp19 = */ the_sweeplst_lock_release_one (arg0) ;
#line 115 "gcats1_collecting.dats"
/* tmp20 = */ gc_main_lock_acquire () ;
#line 115 "gcats1_collecting.dats"
/* tmp21 = ats_selsin_mac(tmp20, atslab_1) */ ;
#line 116 "gcats1_collecting.dats"
/* tmp22 = */ the_sweeplst_lock_acquire_one (arg0) ;
#line 116 "gcats1_collecting.dats"
/* tmp23 = ats_selsin_mac(tmp22, atslab_1) */ ;
#line 118 "gcats1_collecting.dats"
tmp24 = the_sweeplst_array_get (arg0) ;
#line 120 "gcats1_collecting.dats"
tmp25 = chunklst_is_cons (tmp24) ;
#line 120 "gcats1_collecting.dats"
if (tmp25) {
#line 121 "gcats1_collecting.dats"
/* tmp26 = */ gc_main_lock_release () ;
#line 121 "gcats1_collecting.dats"
tmp17 = tmp24 ;
} else {
#line 124 "gcats1_collecting.dats"
tmp27 = the_chunk_count_limit_is_not_reached () ;
#line 126 "gcats1_collecting.dats"
if (tmp27) {
#line 127 "gcats1_collecting.dats"
tmp28 = atspre_asl_int_int1 (1, arg0) ;
#line 127 "gcats1_collecting.dats"
tmp17 = chunklst_create_release (arg0, tmp28) ;
} else {
#line 129 "gcats1_collecting.dats"
/* tmp29 = */ the_globalentrylst_lock_acquire () ;
#line 129 "gcats1_collecting.dats"
/* tmp30 = ats_selsin_mac(tmp29, atslab_1) */ ;
#line 130 "gcats1_collecting.dats"
/* tmp31 = */ the_manmemlst_lock_acquire () ;
#line 130 "gcats1_collecting.dats"
/* tmp32 = ats_selsin_mac(tmp31, atslab_1) */ ;
#line 131 "gcats1_collecting.dats"
/* tmp33 = */ the_threadinfolst_lock_acquire () ;
#line 131 "gcats1_collecting.dats"
/* tmp34 = ats_selsin_mac(tmp33, atslab_1) */ ;
#line 133 "gcats1_collecting.dats"
/* tmp35 = */ the_sweeplst_lock_acquire_rest (arg0) ;
#line 132 "gcats1_collecting.dats"
/* tmp36 = ats_selsin_mac(tmp35, atslab_1) */ ;
#line 135 "gcats1_collecting.dats"
/* tmp37 = */ gc_collect () ;
#line 139 "gcats1_collecting.dats"
/* tmp38 = */ the_sweeplst_lock_release_rest (arg0) ;
#line 138 "gcats1_collecting.dats"
/* tmp39 = ats_selsin_mac(tmp38, atslab_1) */ ;
#line 142 "gcats1_collecting.dats"
/* tmp40 = */ the_threadinfolst_lock_release () ;
#line 143 "gcats1_collecting.dats"
/* tmp41 = */ the_manmemlst_lock_release () ;
#line 144 "gcats1_collecting.dats"
/* tmp42 = */ the_globalentrylst_lock_release () ;
#line 145 "gcats1_collecting.dats"
tmp43 = the_sweeplst_array_get (arg0) ;
#line 152 "gcats1_collecting.dats"
tmp44 = chunklst_is_cons (tmp43) ;
#line 152 "gcats1_collecting.dats"
if (tmp44) {
#line 153 "gcats1_collecting.dats"
/* tmp45 = */ gc_main_lock_release () ;
#line 153 "gcats1_collecting.dats"
tmp17 = tmp43 ;
} else {
#line 155 "gcats1_collecting.dats"
tmp46 = atspre_asl_int_int1 (1, arg0) ;
#line 155 "gcats1_collecting.dats"
tmp17 = chunklst_create_release (arg0, tmp46) ;
} /* end of [if] */
} /* end of [if] */
} /* end of [if] */
} /* end of [if] */
#line 166 "gcats1_collecting.dats"
tmp47 = chunklst_sweep_next_get (tmp17) ;
#line 167 "gcats1_collecting.dats"
/* tmp48 = */ the_sweeplst_array_set (arg0, tmp47) ;
#line 168 "gcats1_collecting.dats"
/* tmp49 = */ the_sweeplst_lock_release_one (arg0) ;
#line 169 "gcats1_collecting.dats"
tmp50 = gc_chunk_threading (tmp17) ;
#line 176 "gcats1_collecting.dats"
tmp51 = freeitmlst_is_nil (tmp50) ;
#line 176 "gcats1_collecting.dats"
if (tmp51) {
#line 177 "gcats1_collecting.dats"
/* tmp52 = */ atspre_prerr_string (ATSstrcst("GC: Fatal Error")) ;
#line 178 "gcats1_collecting.dats"
/* tmp53 = */ atspre_prerr_string (ATSstrcst(": [gc_freeitmlst_generate]: the generated freeitmlst is nil")) ;
#line 179 "gcats1_collecting.dats"
/* tmp54 = */ atspre_prerr_newline () ;
#line 180 "gcats1_collecting.dats"
/* tmp13 = */ ats_exit (1) ;
} else {
#line 182 "gcats1_collecting.dats"
tmp13 = tmp50 ;
} /* end of [if] */
return (tmp13) ;
} /* end of [ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_2esats__gc_freeitmlst_generate] */

/* static load function */

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_collecting_2edats__staload () {
static int ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_collecting_2edats__staload_flag = 0 ;
if (ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_collecting_2edats__staload_flag) return ;
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_collecting_2edats__staload_flag = 1 ;

ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_2esats__staload () ;

return ;
} /* staload function */

/* dynamic load function */

// dynload flag declaration
extern ats_int_type ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_collecting_2edats__dynload_flag ;

ats_void_type
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_collecting_2edats__dynload () {
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_collecting_2edats__dynload_flag = 1 ;
ATS_2d0_2e2_2e10_2ccomp_2runtime_2GCATS1_2gcats1_collecting_2edats__staload () ;

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

/* marking static variables for GC */

/* marking external values for GC */

/* code for dynamic loading */
return ;
} /* end of [dynload function] */

/* external codes at mid */
/* external codes at bot */
#line 188 "gcats1_collecting.dats"


// [chks] must not be NULL!
ats_void_type gc_sweeplst_build_chunk (ats_ptr_type chks) {
  int i, j ; freeitmlst *pi, *pij ;
  int itemwsz_log, itemtot, markcnt ;
  int freecnt ;

  markcnt = chunklst_markcnt_get (chks) ;
/*
  fprintf (stderr, "gc_sweeplst_build_chunk: markcnt = %i\n", markcnt) ;
*/
#ifdef _ATS_MULTITHREAD
  // this logic is problematic!
  freecnt = chunklst_freecnt_get (chks) ;
  if (freecnt > 0) {
    fprintf (stderr, "gc_sweeplst_build_chunk: freecnt = %i\n", freecnt) ;
    return ;
  }
#endif
  if (markcnt == 0) { chunklst_destroy (chks) ; return ; }

  itemtot = chunklst_itemtot_get (chks) ;
  if (markcnt > itemtot * CHUNK_SWEEP_CUTOFF) return ;

  itemwsz_log = chunklst_itemwsz_log_get (chks) ;
/*
  if (itemwsz_log < 0) { // chks->itemtot = 1 and markcnt = 1
    fprintf (stderr, "GC: Fatal Error: [gc_sweeplst_build_chunk]") ;
    fprintf (stderr, ": itemwsz_log = %i\n", itemwsz_log) ;
    exit (1) ;
  }
*/
/*
  fprintf (stderr, "gc_sweeplst_build_chunk: itemwsz_log = %i\n", itemwsz_log) ;
*/
  the_sweeplst_array_insert_at (chks, itemwsz_log) ;
  return ;
} /* end of [gc_sweeplst_build_chunk] */

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

#if (__WORDSIZE == 32)

ats_void_type
gc_sweeplst_build_the_topsegtbl () {
  int i ; botsegtbllst tbls ;
  the_sweeplst_array_clear_all () ;
  for (i = 0; i < TOPSEG_TABLESIZE; i += 1) {
    tbls = the_topsegtbl[i] ;
    if (tbls) gc_sweeplst_build_botsegtbl (tbls) ;
  } // end of [for]
  return ;
} /* end of [gc_sweeplst_build_the_topsegtbl] */

#endif // end of [__WORDSIZE == 32]

#if (__WORDSIZE == 64)

ats_void_type
gc_sweeplst_build_the_topsegtbl () {
  int i ; botsegtbllst tbls ;
  the_sweeplst_array_clear_all () ;
  for (i = 0; i < TOPSEG_HASHTABLESIZE; i += 1) {
    tbls = the_topsegtbl[i] ;
    while (tbls) { // termination: obvious
      gc_sweeplst_build_botsegtbl (tbls) ; tbls = tbls->hash_next ;
    } // end of [while]
  } // end of [for]
  return ;
} /* end of [gc_sweeplst_build_the_topsegtbl] */

#endif // end of [__WORDSIZE == 64]

#line 266 "gcats1_collecting.dats"


#define NCHUNK_PER_MARKSTACKPAGE 32
#define MARKSTACK_EXTEND_INCREMENT 2

extern int the_chunk_count ;
extern int the_chunk_count_limit ;
extern int the_chunk_count_limit_max ;
extern int the_markstackpagecnt ;

#ifdef _ATS_MULTITHREAD
extern sem_t the_sleep_semaphore ;
extern threadinfolst the_threadinfolst_fst ;
extern __thread threadinfolst the_threadinfolst_self ;
#endif

ats_void_type gc_collect () {
  int overflow, nchunk, nmarkstackpage ;
  jmp_buf reg_save ; // register contents are roots
#ifdef _ATS_MULTITHREAD
  threadinfolst infolst ; int nother ;
#endif
/*
  fprintf(
    stderr
  , "GC begs: the_chunk_count = %i and the_chunk_count_limit = %i\n"
  , the_chunk_count
  , the_chunk_count_limit
  ) ;
*/
  setjmp (reg_save) ; // push registers onto the stack
  asm volatile ("": : :"memory") ; // stop potential optimization

  nmarkstackpage = (the_chunk_count << CHUNK_WORDSIZE_LOG) ;
  nmarkstackpage /= (MARKSTACK_PAGESIZE * NCHUNK_PER_MARKSTACKPAGE) ;
  nmarkstackpage += 1 ; nmarkstackpage -= the_markstackpagecnt ;
/*
  fprintf (stderr, "gc_collect: nmarkstackpage = %i\n", nmarkstackpage) ;
*/
  the_markstack_extend (nmarkstackpage) ;

#ifdef _ATS_MULTITHREAD
  // put all of the other threads into sleep
  infolst = the_threadinfolst_fst ; nother = 0 ;
  while (infolst) {
    if (infolst != the_threadinfolst_self) {
      fprintf (stderr, "gc_collect: SIGUSR1: infolst->pid = %i\n", (int)(infolst->pid)) ;
      pthread_kill (infolst->pid, SIGUSR1) ; nother += 1 ;
    }
    infolst = infolst->next ;
  }
  while (nother) { // ordering is irrelevant
    fprintf (stderr, "gc_collect: sem_wait: bef: nother = %i\n", nother) ;
    sem_wait (&the_sleep_semaphore) ; nother -= 1 ;
    fprintf (stderr, "gc_collect: sem_wait: aft: nother = %i\n", nother) ;
  }
  fprintf (stderr, "gc_collect: nother = %i\n", nother) ;
#endif // end of [_ATS_MULTITHREAD]

  gc_markbits_clear_the_topsegtbl () ; // clear all mark bits
/*
  fprintf (
    stderr, "gc_collect: gc_markbits_clear_topsegtbl: done\n", nmarkstackpage
  ) ; // end of [fprintf]
*/

  overflow = gc_mark_all () ; // marking phase
/*
  fprintf (stderr, "gc_collect: gc_mark_all: done\n") ;
*/

#ifdef _ATS_MULTITHREAD
  // wake up all of the sleeping threads
  infolst = the_threadinfolst_fst ;
  while (infolst) {
    if (infolst != the_threadinfolst_self) {
      fprintf (stderr, "gc_collect: SIGUSR2: infolst->pid = %i\n", (int)(infolst->pid)) ;
      pthread_kill (infolst->pid, SIGUSR2) ;
    }
    infolst = infolst->next ;
  }
#endif // end of [_ATS_MULTITHREAD]

  the_freeitmlst_array_mark_unset () ; /* is this really needed? */
  // [gc_mark_threadinfolst_one] is not called on [the_threadinfolst_self]
  // Therefore [the_freeitmlst_array_clear_all] must be called!
  the_freeitmlst_array_clear_all () ; /* clear the freeitmlst array */
  gc_sweeplst_build_the_topsegtbl () ; // sweep chunks into [the_sweeplst_array]

  if (overflow > 0) {
/*
    fprintf (stderr, "gc_collect: markstack overflow happend.\n") ;
*/
    the_markstack_extend (MARKSTACK_EXTEND_INCREMENT) ;
  }
/*
  fprintf(
    stderr
  , "GC ends: the_chunk_count = %i and the_chunk_count_limit = %i\n"
  , the_chunk_count
  , the_chunk_count_limit
  ) ;
*/
  if (the_chunk_count_limit_max >= 0) {
    // [the_chunk_count_limit_max] is finite
    if (the_chunk_count_limit >= the_chunk_count_limit_max) {
      // fprintf(stderr, "GC: the_chunk_count_limit = %i\n", the_chunk_count_limit) ;
      // fprintf(stderr, "GC: the_chunk_count_limit_max = %i\n", the_chunk_count_limit_max) ;
      fprintf(stderr, "GC: Warning: the maximal chunk count limit is reached!\n") ;
      return ;
    }
  } /* end of [if] */

  if (the_chunk_count >= the_chunk_count_limit * CHUNK_LIMIT_EXTEND_CUTOFF)
    the_chunk_count_limit *= 2 ;
/*
  fprintf(
    stderr
  , "GC ends: update: the_chunk_count_limit = %i\n", the_chunk_count_limit
  ) ;
*/
  return ;

} /* end of [gc_collect] */

#line 395 "gcats1_collecting.dats"


ats_ptr_type gc_chunk_threading (ats_ptr_type chks) {
  int i, j ;
  int itemwsz, itemtot ;
  freeitmlst data0, data, data_next ;
  int markcnt ; byte *markbits ;

  itemwsz = ((chunklst)chks)->itemwsz ;
  itemtot = ((chunklst)chks)->itemtot ;
  markcnt = ((chunklst)chks)->markcnt ;

  data0 = ((chunklst)chks)->data ;

  if (markcnt == 0) { // fast threading
    // threading all the freeitms in the created chunk
    data = data0 ; data_next = data0 ;
    for (i = 1; i < itemtot; i += 1) {
      data_next = (freeitmlst*)data_next + itemwsz ;
      *(freeitmlst*)data = data_next ; data = data_next ;
    } // end of [for]
    *(freeitmlst*)data = (freeitmlst)0 ;
    goto GC_CHUNK_THREADING_IS_DONE ;
  } // end of [if]

  markbits = ((chunklst)chks)-> markbits ;
  for (i = 0; i < itemtot; i += 1) {
    if (!MARK_GET (markbits, i)) break ;
  }

  if (i == itemtot) {
    data0 = (freeitmlst)0 ; goto GC_CHUNK_THREADING_IS_DONE ;
  }

  data0 = (freeitmlst*)data0 + i * itemwsz;
  data = data0 ; data_next = data0 ;
  for (j = i + 1; j < itemtot; j += 1) {
    data_next = (freeitmlst*)data_next + itemwsz ;
    if (!MARK_GET (markbits, j)) {
      *(freeitmlst*)data = data_next ; data = data_next ;
    } // end of [if]
  } // end of [for]

  *(freeitmlst*)data = (freeitmlst)0 ;

/*
  if (itemtot - markcnt != freeitmlst_length (data0)) {
    fprintf (stderr, "GC: Fatal Error") ;
    fprintf (stderr, ": [gc_chunk_threading]: consistency check failed.\n") ;
    fprintf (stderr, "itemtot = %i\n", itemtot) ;
    fprintf (stderr, "markcnt = %i\n", markcnt) ;
    fprintf (stderr, "freeitmlst_length(data0) = %i\n", freeitmlst_length(data0)) ;
    exit (1) ;
  }
*/

  GC_CHUNK_THREADING_IS_DONE: return data0 ;
  
} /* end of [gc_chunk_threading] */



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

/* end of [gcats1_collecting_dats.c] */
