| 134 | } |
| 135 | |
| 136 | void |
| 137 | ink_freelist_init(InkFreeList **fl, const char *name, uint32_t type_size, uint32_t chunk_size, uint32_t alignment, |
| 138 | bool use_hugepages) |
| 139 | { |
| 140 | InkFreeList *f; |
| 141 | ink_freelist_list *fll; |
| 142 | |
| 143 | /* its safe to add to this global list because ink_freelist_init() |
| 144 | is only called from single-threaded initialization code. */ |
| 145 | f = static_cast<InkFreeList *>(ats_memalign(alignment, sizeof(InkFreeList))); |
| 146 | ink_zero(*f); |
| 147 | |
| 148 | fll = static_cast<ink_freelist_list *>(ats_malloc(sizeof(ink_freelist_list))); |
| 149 | fll->fl = f; |
| 150 | fll->next = freelists; |
| 151 | freelists = fll; |
| 152 | |
| 153 | f->name = name; |
| 154 | /* quick test for power of 2 */ |
| 155 | ink_assert(!(alignment & (alignment - 1))); |
| 156 | // It is never useful to have alignment requirement looser than a page size |
| 157 | // so clip it. This makes the item alignment checks in the actual allocator simpler. |
| 158 | f->alignment = alignment; |
| 159 | f->use_hugepages = ats_hugepage_enabled() && use_hugepages; |
| 160 | f->hugepages_failure = 0; |
| 161 | if (f->use_hugepages) { |
| 162 | // for hugepages, always make the allocation alignment on a hugepage boundary |
| 163 | f->alignment = ats_hugepage_size(); |
| 164 | f->type_size = type_size; |
| 165 | } else { |
| 166 | if (f->alignment > ats_pagesize()) { |
| 167 | f->alignment = ats_pagesize(); |
| 168 | } |
| 169 | // Make sure we align *all* the objects in the allocation, not just the first one |
| 170 | f->type_size = INK_ALIGN(type_size, f->alignment); |
| 171 | } |
| 172 | Dbg(dbg_ctl_freelist_init, "<%s> Alignment request/actual (%" PRIu32 "/%" PRIu32 ")", name, alignment, f->alignment); |
| 173 | Dbg(dbg_ctl_freelist_init, "<%s> Type Size request/actual (%" PRIu32 "/%" PRIu32 ")", name, type_size, f->type_size); |
| 174 | if (f->use_hugepages) { |
| 175 | f->chunk_size = INK_ALIGN(chunk_size * f->type_size, ats_hugepage_size()) / f->type_size; |
| 176 | } else { |
| 177 | f->chunk_size = INK_ALIGN(chunk_size * f->type_size, ats_pagesize()) / f->type_size; |
| 178 | } |
| 179 | Dbg(dbg_ctl_freelist_init, "<%s> Chunk Size request/actual (%" PRIu32 "/%" PRIu32 ")", name, chunk_size, f->chunk_size); |
| 180 | SET_FREELIST_POINTER_VERSION(f->head, FROM_PTR(0), 0); |
| 181 | |
| 182 | *fl = f; |
| 183 | } |
| 184 | |
| 185 | void |
| 186 | ink_freelist_madvise_init(InkFreeList **fl, const char *name, uint32_t type_size, uint32_t chunk_size, uint32_t alignment, |
no test coverage detected