/* Copyright 2005 Chris Thomasson */
#include "../../ac_thread.h"


#ifndef AC_I686_LFGC_SMR_H
#define AC_I686_LFGC_SMR_H


#ifdef __cplusplus
extern "C"
{
#endif




#define AC_I686_LFGC_SMR_HAZARD_DEPTH 3
#define AC_I686_LFGC_SMR_COLLECT_MAX_DEPTH 1024


typedef ac_i686_node_t** ac_i686_lfgc_smr_hazard_t;




#ifdef _MSC_VER 
/* 4324: structure was padded due to __declspec(align()) */
#pragma warning ( disable : 4324 )
#endif


/* MUST be ( AC_I686_LFGC_HAZARD_DEPTH + 7 ) adjacent words */
typedef struct 
AC_DECLSPEC_PACKED_ALIGN_CACHE_LINE
ac_i686_lfgc_smr_
{
  struct ac_i686_lfgc_smr_ *next;
  struct ac_i686_lfgc_smr_ *prev;
  ac_i686_node_t *hazards[AC_I686_LFGC_SMR_HAZARD_DEPTH];
  ac_i686_node_t *cache_front;
  ac_i686_node_t *cache_back;
  ac_i686_intword_t cache_count;
  ac_i686_tls_t *_tls;
  void *this_mem;

} ac_i686_lfgc_smr_t;


#ifdef _MSC_VER 
/* 4324: structure was padded due to __declspec(align()) */
#pragma warning ( default : 4324 )
#endif




AC_SYS_APIEXPORT ac_i686_node_t* AC_CDECL 
np_ac_i686_lfgc_smr_stack_mpmc_pop_dwcas
( ac_i686_stack_mpmc_t*,
  ac_i686_lfgc_smr_hazard_t );


AC_SYS_APIEXPORT ac_i686_node_t* AC_CDECL
ac_i686_lfgc_smr_activate
( ac_i686_lfgc_smr_hazard_t,
  ac_i686_node_t** );


AC_SYS_APIEXPORT void AC_CDECL
ac_i686_lfgc_smr_deactivate
( ac_i686_lfgc_smr_hazard_t );


AC_APIEXPORT void AC_APIDECL
ac_i686_lfgc_smr_scan
( ac_i686_lfgc_smr_t* );




AC_DECLSPEC_INLINE ac_i686_lfgc_smr_hazard_t AC_APIDECL
ac_i686_lfgc_smr_get
( ac_thread_t *_tls,
  ac_i686_intword_t index )
{
  assert( index > -1 && index < AC_I686_LFGC_SMR_HAZARD_DEPTH );
  return &_tls->cpu_atomic.lfgc_smr->hazards[index];
}


AC_DECLSPEC_INLINE void AC_APIDECL
ac_i686_lfgc_smr_collect
( ac_thread_t *_tls,
  ac_fp_dtor_t fp_dtor,
  ac_i686_node_t *node )
{
  ac_i686_lfgc_smr_t *smr = _tls->cpu_atomic.lfgc_smr;
  
  if ( fp_dtor ) { node->fp_dtor = fp_dtor; }

  node->lfgc_next = smr->cache_front;
  smr->cache_front = node;

  if ( ++smr->cache_count > 
       AC_I686_LFGC_SMR_COLLECT_MAX_DEPTH )
  {
    ac_i686_lfgc_smr_scan( smr );
  }
}





typedef ac_i686_lfgc_smr_hazard_t ac_lfgc_smr_hazard_t;

#define AC_LFGC_SMR_HAZARD_DEPTH AC_I686_LFGC_SMR_HAZARD_DEPTH
#define ac_lfgc_smr_get ac_i686_lfgc_smr_get
#define ac_lfgc_smr_collect ac_i686_lfgc_smr_collect
#define ac_lfgc_smr_activate ac_i686_lfgc_smr_activate
#define ac_lfgc_smr_deactivate ac_i686_lfgc_smr_deactivate
#define np_ac_cpu_lfgc_smr_stack_mpmc_pop_dwcas np_ac_i686_lfgc_smr_stack_mpmc_pop_dwcas




#ifdef __cplusplus
}
#endif


#endif