cache line locking on AMD x86_64 utilising L3 CAT pseudo-locking
26

Configure Feed

Select the types of activity you want to include in your feed.

icepick / src / region.c
1.8 kB 68 lines
1#define _GNU_SOURCE 2#include "internal.h" 3#include <sys/mman.h> 4#include <numaif.h> 5#include <errno.h> 6#include <string.h> 7 8#ifndef MAP_HUGE_2MB 9#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT) 10#endif 11 12#ifndef MAP_HUGE_SHIFT 13#define MAP_HUGE_SHIFT 26 14#endif 15 16int region_alloc(size_t size, int numa_node, bool huge_pages, void **out_ptr) 17{ 18 int flags = MAP_PRIVATE | MAP_ANONYMOUS; 19 size_t alloc_size = size; 20 21 if (huge_pages) { 22 flags |= MAP_HUGETLB | MAP_HUGE_2MB; 23 size_t huge_page_size = 2 * 1024 * 1024; 24 alloc_size = (size + huge_page_size - 1) & ~(huge_page_size - 1); 25 } 26 27 void *ptr = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, flags, -1, 0); 28 if (ptr == MAP_FAILED) { 29 if (huge_pages && errno == ENOMEM) { 30 flags = MAP_PRIVATE | MAP_ANONYMOUS; 31 alloc_size = size; 32 ptr = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, flags, -1, 0); 33 if (ptr == MAP_FAILED) 34 return ICEPICK_E_ALLOC; 35 } else { 36 return huge_pages ? ICEPICK_E_HUGEPAGE : ICEPICK_E_ALLOC; 37 } 38 } 39 40 if (numa_node >= 0) { 41 unsigned long nodemask = 1UL << numa_node; 42 if (mbind(ptr, alloc_size, MPOL_BIND, &nodemask, sizeof(nodemask) * 8, 43 MPOL_MF_MOVE | MPOL_MF_STRICT) < 0) { 44 munmap(ptr, alloc_size); 45 return ICEPICK_E_NUMA; 46 } 47 } 48 49 if (mlock(ptr, alloc_size) < 0) { 50 munmap(ptr, alloc_size); 51 return ICEPICK_E_PERMISSION; 52 } 53 54 madvise(ptr, alloc_size, MADV_DONTFORK); 55 56 memset(ptr, 0, alloc_size); 57 58 *out_ptr = ptr; 59 return 0; 60} 61 62void region_free(void *ptr, size_t size) 63{ 64 if (ptr) { 65 munlock(ptr, size); 66 munmap(ptr, size); 67 } 68}