separate functions
This commit is contained in:
parent
8a93a0e94c
commit
e7a82bfb66
@ -5,16 +5,12 @@ project(libtopo)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
pkg_check_modules(XML libxml-2.0 REQUIRED)
|
||||
set(C_FLAGS -O2 -g -Wall -Wextra -Werror -std=c17
|
||||
-Wno-deprecated-declarations
|
||||
-Wno-address-of-packed-member
|
||||
-Wno-zero-length-array
|
||||
-Wno-gnu-zero-variadic-macro-arguments
|
||||
set(C_FLAGS -O2 -g -Wall -Wextra -Werror -Wpedantic -Wconversion -std=c17
|
||||
-march=native)
|
||||
|
||||
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_include_directories(topo PRIVATE ${XML_INCLUDE_DIRS})
|
||||
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);
|
||||
|
||||
int
|
||||
topo_init(int enable_alloc, int verbose);
|
||||
|
||||
void *
|
||||
topo_malloc(unsigned int node, size_t size);
|
||||
|
||||
void
|
||||
topo_free(unsigned int node, void * addr);
|
||||
topo_init(int verbose);
|
||||
|
||||
uint64_t
|
||||
topo_uptime_ns();
|
||||
topo_uptime_ns(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
@ -12,7 +13,7 @@ get_uptime()
|
||||
{
|
||||
struct timespec 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)
|
||||
@ -95,8 +96,8 @@ int ts_test()
|
||||
|
||||
int main()
|
||||
{
|
||||
topo_init(1, 1);
|
||||
topo_init(0, 1);
|
||||
topo_init(1);
|
||||
topo_init(1);
|
||||
ts_test();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -43,4 +43,4 @@ topo_desc_uptime_ns(struct topo_desc * desc)
|
||||
uint64_t tsc = __rdtscp(&dummy);
|
||||
_mm_lfence();
|
||||
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;
|
||||
while (first != NULL) {
|
||||
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];
|
||||
int val = strtol(tmp, NULL, 16);
|
||||
int val = (int)strtol(tmp, NULL, 16);
|
||||
int count = 0;
|
||||
while (val > 0) {
|
||||
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);
|
||||
while (CPU_FFS(&tmpset) != 0) {
|
||||
int u = CPU_FFS(&tmpset);
|
||||
int u = (int)CPU_FFS(&tmpset);
|
||||
printf("%d ", u - 1);
|
||||
CPU_CLR(u -1 , &tmpset);
|
||||
}
|
||||
@ -256,7 +256,7 @@ tobj_populate(struct topo_obj **out)
|
||||
|
||||
//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) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
@ -368,7 +368,7 @@ desc_destroy(struct topo_desc * desc)
|
||||
}
|
||||
|
||||
static int
|
||||
desc_init(struct topo_desc * desc, int enable_alloc, int verbose)
|
||||
desc_init(struct topo_desc * desc, int verbose)
|
||||
{
|
||||
desc->root = NULL;
|
||||
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);
|
||||
}
|
||||
|
||||
if (enable_alloc && rc == 0) {
|
||||
rc = topo_alloc_init(desc, verbose);
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
if (desc->root != NULL) {
|
||||
tobj_free_root(desc->root);
|
||||
@ -440,18 +436,6 @@ topo_destroy(void)
|
||||
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
|
||||
topo_uptime_ns(void)
|
||||
{
|
||||
@ -459,11 +443,11 @@ topo_uptime_ns(void)
|
||||
}
|
||||
|
||||
int
|
||||
topo_init(int enable_alloc, int verbose)
|
||||
topo_init(int verbose)
|
||||
{
|
||||
int expected = 0;
|
||||
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);
|
||||
} else {
|
||||
while(atomic_load(&initialized) != 1) {} // wait for init
|
||||
@ -472,4 +456,4 @@ topo_init(int enable_alloc, int verbose)
|
||||
}
|
||||
}
|
||||
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];
|
||||
};
|
||||
|
||||
int
|
||||
topo_alloc_init(struct topo_desc * desc, int verbose);
|
||||
|
||||
int
|
||||
topo_ts_init(struct topo_desc *desc, int verbose);
|
||||
|
||||
uint64_t
|
||||
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