Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #ifndef _ink_queue_h_
00025 #define _ink_queue_h_
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 #include "ink_platform.h"
00038 #include "ink_defs.h"
00039 #include "ink_apidefs.h"
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 #ifdef __cplusplus
00061 extern "C"
00062 {
00063 #endif                          
00064 
00065   void ink_queue_load_64(void *dst, void *src);
00066 
00067 #ifdef __x86_64__
00068 #define INK_QUEUE_LD64(dst,src) *((uint64_t*)&(dst)) = *((uint64_t*)&(src))
00069 #else
00070 #define INK_QUEUE_LD64(dst,src) (ink_queue_load_64((void *)&(dst), (void *)&(src)))
00071 #endif
00072 
00073 #if TS_HAS_128BIT_CAS
00074 #define INK_QUEUE_LD(dst, src) do { \
00075   *(__int128_t*)&(dst) = __sync_val_compare_and_swap((__int128_t*)&(src), 0, 0); \
00076 } while (0)
00077 #else
00078 #define INK_QUEUE_LD(dst,src) INK_QUEUE_LD64(dst,src)
00079 #endif
00080 
00081 
00082 
00083 
00084   
00085   
00086   typedef union
00087   {
00088 #if (defined(__i386__) || defined(__arm__) || defined(__mips__)) && (SIZEOF_VOIDP == 4)
00089     struct
00090     {
00091       void *pointer;
00092       int32_t version;
00093     } s;
00094     int64_t data;
00095 #elif TS_HAS_128BIT_CAS
00096     struct
00097     {
00098       void *pointer;
00099       int64_t version;
00100     } s;
00101     __int128_t data;
00102 #else
00103     int64_t data;
00104 #endif
00105   } head_p;
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 #define ZERO_HEAD_P(_x)
00118 
00119 #ifdef DEBUG
00120 #define FROM_PTR(_x) (void*)(((uintptr_t)_x)+1)
00121 #define TO_PTR(_x) (void*)(((uintptr_t)_x)-1)
00122 #else
00123 #define FROM_PTR(_x) ((void*)(_x))
00124 #define TO_PTR(_x) ((void*)(_x))
00125 #endif
00126 
00127 #if (defined(__i386__) || defined(__arm__) || defined(__mips__)) && (SIZEOF_VOIDP == 4)
00128 #define FREELIST_POINTER(_x) (_x).s.pointer
00129 #define FREELIST_VERSION(_x) (_x).s.version
00130 #define SET_FREELIST_POINTER_VERSION(_x,_p,_v) \
00131 (_x).s.pointer = _p; (_x).s.version = _v
00132 #elif TS_HAS_128BIT_CAS
00133 #define FREELIST_POINTER(_x) (_x).s.pointer
00134 #define FREELIST_VERSION(_x) (_x).s.version
00135 #define SET_FREELIST_POINTER_VERSION(_x,_p,_v) \
00136 (_x).s.pointer = _p; (_x).s.version = _v
00137 #elif defined(__x86_64__) || defined(__ia64__) || defined(__powerpc64__) || defined(__aarch64__)
00138 #define FREELIST_POINTER(_x) ((void*)(((((intptr_t)(_x).data)<<16)>>16) | \
00139  (((~((((intptr_t)(_x).data)<<16>>63)-1))>>48)<<48)))  // sign extend
00140 #define FREELIST_VERSION(_x) (((intptr_t)(_x).data)>>48)
00141 #define SET_FREELIST_POINTER_VERSION(_x,_p,_v) \
00142   (_x).data = ((((intptr_t)(_p))&0x0000FFFFFFFFFFFFULL) | (((_v)&0xFFFFULL) << 48))
00143 #else
00144 #error "unsupported processor"
00145 #endif
00146 
00147   typedef void *void_p;
00148 
00149 #if TS_USE_RECLAIMABLE_FREELIST
00150   extern float cfg_reclaim_factor;
00151   extern int64_t cfg_max_overage;
00152   extern int64_t cfg_enable_reclaim;
00153   extern int64_t cfg_debug_filter;
00154 #else
00155   struct _InkFreeList
00156   {
00157     volatile head_p head;
00158     const char *name;
00159     uint32_t type_size, chunk_size, used, allocated, alignment;
00160     uint32_t allocated_base, used_base;
00161   };
00162 
00163   inkcoreapi extern volatile int64_t fastalloc_mem_in_use;
00164   inkcoreapi extern volatile int64_t fastalloc_mem_total;
00165   inkcoreapi extern volatile int64_t freelist_allocated_mem;
00166 #endif
00167 
00168   typedef struct _InkFreeList InkFreeList, *PInkFreeList;
00169   typedef struct _ink_freelist_list
00170   {
00171     InkFreeList *fl;
00172     struct _ink_freelist_list *next;
00173   } ink_freelist_list;
00174   extern ink_freelist_list *freelists;
00175 
00176   
00177 
00178 
00179   InkFreeList *ink_freelist_create(const char *name, uint32_t type_size,
00180                                    uint32_t chunk_size, uint32_t alignment);
00181 
00182   inkcoreapi void ink_freelist_init(InkFreeList **fl, const char *name,
00183                                     uint32_t type_size, uint32_t chunk_size,
00184                                     uint32_t alignment);
00185   inkcoreapi void *ink_freelist_new(InkFreeList * f);
00186   inkcoreapi void ink_freelist_free(InkFreeList * f, void *item);
00187   void ink_freelists_dump(FILE * f);
00188   void ink_freelists_dump_baselinerel(FILE * f);
00189   void ink_freelists_snap_baseline();
00190 
00191   typedef struct
00192   {
00193     volatile head_p head;
00194     const char *name;
00195     uint32_t offset;
00196   } InkAtomicList;
00197 
00198 #if !defined(INK_QUEUE_NT)
00199 #define INK_ATOMICLIST_EMPTY(_x) (!(TO_PTR(FREELIST_POINTER((_x.head)))))
00200 #else
00201   
00202 #define INK_ATOMICLIST_EMPTY(_x) (!(      (FREELIST_POINTER((_x.head)))))
00203 #endif
00204 
00205   inkcoreapi void ink_atomiclist_init(InkAtomicList * l, const char *name, uint32_t offset_to_next);
00206   inkcoreapi void *ink_atomiclist_push(InkAtomicList * l, void *item);
00207   void *ink_atomiclist_pop(InkAtomicList * l);
00208   inkcoreapi void *ink_atomiclist_popall(InkAtomicList * l);
00209 
00210 
00211 
00212 
00213 
00214 
00215   void *ink_atomiclist_remove(InkAtomicList * l, void *item);
00216 
00217 #ifdef __cplusplus
00218 }
00219 #endif 
00220 
00221 #endif