separate functions

This commit is contained in:
quackerd 2022-06-10 19:29:01 +08:00
parent 8a93a0e94c
commit e7a82bfb66
7 changed files with 18 additions and 155 deletions

View File

@ -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
View File

@ -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
}

View File

@ -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"

View File

@ -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;
} }

30
topo.c
View File

@ -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

View File

@ -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)));