separate functions
This commit is contained in:
parent
8a93a0e94c
commit
e7a82bfb66
@ -5,16 +5,12 @@ project(libtopo)
|
|||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
pkg_check_modules(XML libxml-2.0 REQUIRED)
|
pkg_check_modules(XML libxml-2.0 REQUIRED)
|
||||||
set(C_FLAGS -O2 -g -Wall -Wextra -Werror -std=c17
|
set(C_FLAGS -O2 -g -Wall -Wextra -Werror -Wpedantic -Wconversion -std=c17
|
||||||
-Wno-deprecated-declarations
|
|
||||||
-Wno-address-of-packed-member
|
|
||||||
-Wno-zero-length-array
|
|
||||||
-Wno-gnu-zero-variadic-macro-arguments
|
|
||||||
-march=native)
|
-march=native)
|
||||||
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/inc)
|
include_directories(${CMAKE_SOURCE_DIR}/inc)
|
||||||
|
|
||||||
add_library(topo SHARED topo.c alloc.c timestamp.c)
|
add_library(topo SHARED topo.c timestamp.c)
|
||||||
target_compile_options(topo PRIVATE ${C_FLAGS} ${XML_CFLAGS})
|
target_compile_options(topo PRIVATE ${C_FLAGS} ${XML_CFLAGS})
|
||||||
target_include_directories(topo PRIVATE ${XML_INCLUDE_DIRS})
|
target_include_directories(topo PRIVATE ${XML_INCLUDE_DIRS})
|
||||||
target_link_libraries(topo PRIVATE ${XML_LINK_LIBRARIES})
|
target_link_libraries(topo PRIVATE ${XML_LINK_LIBRARIES})
|
||||||
|
103
alloc.c
103
alloc.c
@ -1,103 +0,0 @@
|
|||||||
#include <pthread.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/cpuset.h>
|
|
||||||
#include <sys/domainset.h>
|
|
||||||
#include <sys/thr.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "topo.h"
|
|
||||||
#include "topop.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
topo_alloc_init(struct topo_desc * desc, int verbose)
|
|
||||||
{
|
|
||||||
long tid;
|
|
||||||
thr_self(&tid);
|
|
||||||
domainset_t orig_dom;
|
|
||||||
int orig_policy;
|
|
||||||
|
|
||||||
pthread_mutex_init(&desc->alloc_lock, NULL);
|
|
||||||
|
|
||||||
DOMAINSET_ZERO(&orig_dom);
|
|
||||||
|
|
||||||
// save existing thread's allocation strategy
|
|
||||||
int ret = cpuset_getdomain(CPU_LEVEL_WHICH, CPU_WHICH_TID, tid, sizeof(orig_dom), &orig_dom, &orig_policy);
|
|
||||||
if (ret != 0) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
domainset_t tmp_domain;
|
|
||||||
for (int i = 0; i < desc->num_numa; i++) {
|
|
||||||
DOMAINSET_ZERO(&tmp_domain);
|
|
||||||
DOMAINSET_SET(i, &tmp_domain);
|
|
||||||
|
|
||||||
ret = cpuset_setdomain(CPU_LEVEL_WHICH, CPU_WHICH_TID, tid, sizeof(tmp_domain), &tmp_domain, DOMAINSET_POLICY_PREFER);
|
|
||||||
if (ret != 0) {
|
|
||||||
fprintf(stderr, "libtopo: cpuset_setdomain failed with %d\n", errno);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int j = 0; j < ALLOC_MEM_REGION_NUM; j++) {
|
|
||||||
if ((desc->mem_regions[i][j] = mmap(NULL, ALLOC_MEM_OBJ_NUM * ALLOC_MEM_OBJ_SIZE, PROT_READ | PROT_WRITE,
|
|
||||||
MAP_ANON | MAP_ALIGNED_SUPER | MAP_NOCORE | MAP_PRIVATE | MAP_NOSYNC, -1, 0)) == MAP_FAILED) {
|
|
||||||
fprintf(stderr, "libtopo: mmap failed with %d\n", errno);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// touch the pages to prefault the pages
|
|
||||||
for (unsigned int k = 0; k < ALLOC_MEM_OBJ_NUM; k++) {
|
|
||||||
*(uint32_t*)((char*)desc->mem_regions[i][j] + k * ALLOC_MEM_OBJ_SIZE) = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose) {
|
|
||||||
fprintf(stdout, "libtopo: reserved %u bytes (%u MB) on node %d. vaddr: 0x%p\n", ALLOC_MEM_OBJ_NUM * ALLOC_MEM_OBJ_SIZE,
|
|
||||||
ALLOC_MEM_OBJ_SIZE * ALLOC_MEM_OBJ_NUM / 1024 / 1024,
|
|
||||||
i, desc->mem_regions[i][j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
desc->mem_idx[i] = 0;
|
|
||||||
desc->mem_region_idx[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// restore existing thread's allocation strategy
|
|
||||||
ret = cpuset_setdomain(CPU_LEVEL_WHICH, CPU_WHICH_TID, tid, sizeof(orig_dom), &orig_dom, orig_policy);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
topo_desc_malloc(struct topo_desc * desc, unsigned int node, size_t size)
|
|
||||||
{
|
|
||||||
void * ret = NULL;
|
|
||||||
int num_objs = (size + ALLOC_MEM_OBJ_SIZE - 1) / ALLOC_MEM_OBJ_SIZE;
|
|
||||||
int retry = 0;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&desc->alloc_lock);
|
|
||||||
int cur_region = desc->mem_region_idx[node];
|
|
||||||
int cur_idx = desc->mem_idx[node];
|
|
||||||
|
|
||||||
retry:
|
|
||||||
if ((int)ALLOC_MEM_OBJ_NUM - cur_idx >= num_objs) {
|
|
||||||
ret = (char*)desc->mem_regions[node][cur_region] + ALLOC_MEM_OBJ_SIZE * cur_idx;
|
|
||||||
desc->mem_region_idx[node] = cur_region;
|
|
||||||
desc->mem_idx[node] = cur_idx + num_objs;
|
|
||||||
} else if (!retry && (cur_region < (int)ALLOC_MEM_REGION_NUM)) {
|
|
||||||
// check next region
|
|
||||||
cur_region++;
|
|
||||||
cur_idx = 0;
|
|
||||||
retry = 1;
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&desc->alloc_lock);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
topo_desc_free(struct topo_desc * desc __attribute__((unused)), unsigned int node __attribute__((unused)), void * addr __attribute__((unused)))
|
|
||||||
{
|
|
||||||
// dummy function
|
|
||||||
}
|
|
10
inc/topo.h
10
inc/topo.h
@ -22,16 +22,10 @@ void
|
|||||||
topo_destroy(void);
|
topo_destroy(void);
|
||||||
|
|
||||||
int
|
int
|
||||||
topo_init(int enable_alloc, int verbose);
|
topo_init(int verbose);
|
||||||
|
|
||||||
void *
|
|
||||||
topo_malloc(unsigned int node, size_t size);
|
|
||||||
|
|
||||||
void
|
|
||||||
topo_free(unsigned int node, void * addr);
|
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
topo_uptime_ns();
|
topo_uptime_ns(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include <stdint.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -12,7 +13,7 @@ get_uptime()
|
|||||||
{
|
{
|
||||||
struct timespec tp;
|
struct timespec tp;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &tp);
|
clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||||
return (tp.tv_sec * S2NS + tp.tv_nsec);
|
return ((uint64_t)tp.tv_sec * S2NS + (uint64_t)tp.tv_nsec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test(const char * case_name, struct timespec * ts)
|
void test(const char * case_name, struct timespec * ts)
|
||||||
@ -95,8 +96,8 @@ int ts_test()
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
topo_init(1, 1);
|
topo_init(1);
|
||||||
topo_init(0, 1);
|
topo_init(1);
|
||||||
ts_test();
|
ts_test();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -43,4 +43,4 @@ topo_desc_uptime_ns(struct topo_desc * desc)
|
|||||||
uint64_t tsc = __rdtscp(&dummy);
|
uint64_t tsc = __rdtscp(&dummy);
|
||||||
_mm_lfence();
|
_mm_lfence();
|
||||||
return tsc2ns(tsc, desc->tsc_freq);
|
return tsc2ns(tsc, desc->tsc_freq);
|
||||||
}
|
}
|
||||||
|
32
topo.c
32
topo.c
@ -55,9 +55,9 @@ mask_to_cpuset(const char * mask, cpuset_t * cset)
|
|||||||
int qword = 0;
|
int qword = 0;
|
||||||
while (first != NULL) {
|
while (first != NULL) {
|
||||||
int shift = 0;
|
int shift = 0;
|
||||||
for (int i = strlen(first) - 1; i >= 0; i--) {
|
for (int i = (int)strlen(first) - 1; i >= 0; i--) {
|
||||||
tmp[0] = first[i];
|
tmp[0] = first[i];
|
||||||
int val = strtol(tmp, NULL, 16);
|
int val = (int)strtol(tmp, NULL, 16);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while (val > 0) {
|
while (val > 0) {
|
||||||
int bit = val & 1;
|
int bit = val & 1;
|
||||||
@ -103,7 +103,7 @@ tobj_preorder_dump(struct topo_obj * root, int indent) {
|
|||||||
|
|
||||||
printf("%*scache-level: %d, flag: %s, cores: ", indent * 4, "", root->cache_level, flag_str);
|
printf("%*scache-level: %d, flag: %s, cores: ", indent * 4, "", root->cache_level, flag_str);
|
||||||
while (CPU_FFS(&tmpset) != 0) {
|
while (CPU_FFS(&tmpset) != 0) {
|
||||||
int u = CPU_FFS(&tmpset);
|
int u = (int)CPU_FFS(&tmpset);
|
||||||
printf("%d ", u - 1);
|
printf("%d ", u - 1);
|
||||||
CPU_CLR(u -1 , &tmpset);
|
CPU_CLR(u -1 , &tmpset);
|
||||||
}
|
}
|
||||||
@ -256,7 +256,7 @@ tobj_populate(struct topo_obj **out)
|
|||||||
|
|
||||||
//printf("xml:\n%s",buf);
|
//printf("xml:\n%s",buf);
|
||||||
|
|
||||||
xmlDoc * doc = xmlReadMemory(buf, sz, NULL, NULL, 0);
|
xmlDoc * doc = xmlReadMemory(buf, (int)sz, NULL, NULL, 0);
|
||||||
if (doc == NULL) {
|
if (doc == NULL) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
@ -368,7 +368,7 @@ desc_destroy(struct topo_desc * desc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
desc_init(struct topo_desc * desc, int enable_alloc, int verbose)
|
desc_init(struct topo_desc * desc, int verbose)
|
||||||
{
|
{
|
||||||
desc->root = NULL;
|
desc->root = NULL;
|
||||||
int rc = tobj_populate(&desc->root);
|
int rc = tobj_populate(&desc->root);
|
||||||
@ -400,10 +400,6 @@ desc_init(struct topo_desc * desc, int enable_alloc, int verbose)
|
|||||||
rc = topo_ts_init(desc, verbose);
|
rc = topo_ts_init(desc, verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enable_alloc && rc == 0) {
|
|
||||||
rc = topo_alloc_init(desc, verbose);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
if (desc->root != NULL) {
|
if (desc->root != NULL) {
|
||||||
tobj_free_root(desc->root);
|
tobj_free_root(desc->root);
|
||||||
@ -440,18 +436,6 @@ topo_destroy(void)
|
|||||||
desc_destroy(&g_default_desc);
|
desc_destroy(&g_default_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
|
||||||
topo_malloc(unsigned int node, size_t size)
|
|
||||||
{
|
|
||||||
return topo_desc_malloc(&g_default_desc, node, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
topo_free(unsigned int node, void * addr)
|
|
||||||
{
|
|
||||||
return topo_desc_free(&g_default_desc, node, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
topo_uptime_ns(void)
|
topo_uptime_ns(void)
|
||||||
{
|
{
|
||||||
@ -459,11 +443,11 @@ topo_uptime_ns(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
topo_init(int enable_alloc, int verbose)
|
topo_init(int verbose)
|
||||||
{
|
{
|
||||||
int expected = 0;
|
int expected = 0;
|
||||||
if (atomic_compare_exchange_strong(&initialized, &expected, 2)) {
|
if (atomic_compare_exchange_strong(&initialized, &expected, 2)) {
|
||||||
init_rc = desc_init(&g_default_desc, enable_alloc, verbose);
|
init_rc = desc_init(&g_default_desc, verbose);
|
||||||
atomic_store(&initialized, 1);
|
atomic_store(&initialized, 1);
|
||||||
} else {
|
} else {
|
||||||
while(atomic_load(&initialized) != 1) {} // wait for init
|
while(atomic_load(&initialized) != 1) {} // wait for init
|
||||||
@ -472,4 +456,4 @@ topo_init(int enable_alloc, int verbose)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return init_rc;
|
return init_rc;
|
||||||
}
|
}
|
||||||
|
9
topop.h
9
topop.h
@ -26,17 +26,8 @@ struct topo_desc {
|
|||||||
void* mem_regions[ALLOC_MAX_OBJS_PER_LVL][ALLOC_MEM_REGION_NUM];
|
void* mem_regions[ALLOC_MAX_OBJS_PER_LVL][ALLOC_MEM_REGION_NUM];
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
|
||||||
topo_alloc_init(struct topo_desc * desc, int verbose);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
topo_ts_init(struct topo_desc *desc, int verbose);
|
topo_ts_init(struct topo_desc *desc, int verbose);
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
topo_desc_uptime_ns(struct topo_desc * desc);
|
topo_desc_uptime_ns(struct topo_desc * desc);
|
||||||
|
|
||||||
void *
|
|
||||||
topo_desc_malloc(struct topo_desc * desc, unsigned int node, size_t size);
|
|
||||||
|
|
||||||
void
|
|
||||||
topo_desc_free(struct topo_desc * desc __attribute__((unused)), unsigned int node __attribute__((unused)), void * addr __attribute__((unused)));
|
|
Loading…
Reference in New Issue
Block a user