check correctness
This commit is contained in:
parent
f42ecfae91
commit
5daaace5f2
|
@ -15,9 +15,11 @@
|
|||
#include <mm/nvm.h>
|
||||
#include <ckpt/hybird_mem.h>
|
||||
#include <ckpt/hot_pages_tracker.h>
|
||||
#include <immintrin.h>
|
||||
|
||||
/* Global big kernel lock */
|
||||
struct lock big_kernel_lock;
|
||||
int start_rtm = false;
|
||||
|
||||
void run_test(void);
|
||||
void init_fpu_owner_locks(void);
|
||||
|
@ -129,6 +131,8 @@ void main(u64 mbmagic, paddr_t mbaddr)
|
|||
#ifdef RESTORE_ENABLED
|
||||
skip_create_root_thread:
|
||||
#endif
|
||||
start_rtm = true;
|
||||
|
||||
sched();
|
||||
eret_to_thread(switch_context());
|
||||
BUG("Should never be here!\n");
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#define USE_TSX
|
||||
// #define PRE_TOUCH
|
||||
// #define PRINT_ABORT_COUNT
|
||||
|
||||
#ifndef __RTM__
|
||||
#pragma GCC push_options
|
||||
#pragma GCC target("rtm")
|
||||
|
@ -15,6 +19,7 @@
|
|||
#define _XABORT_NESTED (1 << 5)
|
||||
#define _XABORT_CODE(x) (((x) >> 24) & 0xFF)
|
||||
|
||||
extern int start_rtm;
|
||||
|
||||
static __inline__ unsigned int __attribute__((__always_inline__))
|
||||
_xbegin(void)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
/* Should be set at boot time */
|
||||
#define PLAT_CPU_NUM 2
|
||||
#define PLAT_CPU_NUM 10
|
||||
|
||||
/* MSR Registers */
|
||||
#define IA32_APIC_BASE 0x0000001b
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
#include <common/kprint.h>
|
||||
#include <mm/buddy.h>
|
||||
#include <mm/rmap.h>
|
||||
#include <immintrin.h>
|
||||
|
||||
int split_abort_count = 0;
|
||||
|
||||
static struct page *get_buddy_chunk(struct phys_mem_pool *pool,
|
||||
struct page *chunk)
|
||||
|
@ -156,6 +159,25 @@ void init_buddy(struct phys_mem_pool *pool, struct page *start_page,
|
|||
}
|
||||
}
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("O0")
|
||||
__attribute__ ((unused)) static void buddy_get_pages_touch_vars(struct phys_mem_pool *pool, int cur_order, struct page *chunk) {
|
||||
int tmp1 = pool->free_lists[cur_order].nr_free;
|
||||
(void) tmp1;
|
||||
struct page *buddy_chunk = get_buddy_chunk(pool, chunk);
|
||||
(void) buddy_chunk;
|
||||
if (buddy_chunk == NULL) {
|
||||
return;
|
||||
}
|
||||
int tmp2 = buddy_chunk->order;
|
||||
(void) tmp2;
|
||||
int tmp3 = chunk->order;
|
||||
(void) tmp3;
|
||||
int tmp4 = pool->free_lists[buddy_chunk->order].nr_free;
|
||||
(void) tmp4;
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
|
||||
struct page *buddy_get_pages(struct phys_mem_pool *pool, int order)
|
||||
{
|
||||
int cur_order;
|
||||
|
@ -169,7 +191,7 @@ struct page *buddy_get_pages(struct phys_mem_pool *pool, int order)
|
|||
}
|
||||
|
||||
lock(&pool->buddy_lock);
|
||||
|
||||
#ifndef USE_TSX
|
||||
/* Search a chunk (with just enough size) in the free lists. */
|
||||
for (cur_order = order; cur_order < BUDDY_MAX_ORDER; ++cur_order) {
|
||||
free_list = &(pool->free_lists[cur_order].free_list);
|
||||
|
@ -196,6 +218,46 @@ struct page *buddy_get_pages(struct phys_mem_pool *pool, int order)
|
|||
* which can meet the required size.
|
||||
*/
|
||||
page = split_chunk(pool, order, page);
|
||||
#else
|
||||
/* Search a chunk (with just enough size) in the free lists. */
|
||||
for (cur_order = order; cur_order < BUDDY_MAX_ORDER; ++cur_order) {
|
||||
free_list = &(pool->free_lists[cur_order].free_list);
|
||||
if (!list_empty(free_list)) {
|
||||
/* Get a free memory chunck from the free list */
|
||||
page = list_entry(free_list->next, struct page, node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely(page == NULL)) {
|
||||
kwarn("[OOM] No enough memory in memory pool %p\n", pool);
|
||||
goto out;
|
||||
}
|
||||
if (page->order == order) {
|
||||
#ifdef PRE_TOUCH
|
||||
buddy_get_pages_touch_vars(pool, cur_order, page);
|
||||
#endif
|
||||
int status;
|
||||
redo:
|
||||
if ((status = _xbegin()) == _XBEGIN_STARTED) {
|
||||
list_del(&page->node);
|
||||
pool->free_lists[cur_order].nr_free -= 1;
|
||||
_xend();
|
||||
} else {
|
||||
split_abort_count++;
|
||||
kdebug("[%s] abort status %d count %d\n", __func__, status, split_abort_count);
|
||||
goto redo;
|
||||
}
|
||||
} else {
|
||||
prepare_latest_log(pool,
|
||||
ADD_PAGES,
|
||||
(u64)page,
|
||||
order, cur_order);
|
||||
list_del(&page->node);
|
||||
pool->free_lists[cur_order].nr_free -= 1;
|
||||
page = split_chunk(pool, order, page);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set information of pages followed by head */
|
||||
for (int i = 0; i < (1 << order); i++) {
|
||||
|
|
|
@ -13,6 +13,28 @@
|
|||
/* slab_pool is also static. We do not add the static modifier due to unit test. */
|
||||
struct slab_pointer *slab_pool;
|
||||
static struct lock slabs_locks[SLAB_MAX_ORDER + 1];
|
||||
int slab_abort_count = 0;
|
||||
|
||||
struct slab_log_entry {
|
||||
u8 commited;
|
||||
void *free_list_head;
|
||||
void *next_slot;
|
||||
int current_free_cnt;
|
||||
u8 from_init;
|
||||
void *current_slab;
|
||||
int order;
|
||||
};
|
||||
|
||||
static void prepare_slab_log(struct slab_log_entry *log, void *free_list_head, int current_free_count, void *next_slot, int order) {
|
||||
log->commited = false;
|
||||
log->free_list_head = free_list_head;
|
||||
log->current_free_cnt = current_free_count;
|
||||
log->order = order;
|
||||
}
|
||||
|
||||
static void commit_slab_log(struct slab_log_entry *log) {
|
||||
log->commited = true;
|
||||
}
|
||||
|
||||
/*
|
||||
static inline int order_to_index(int order)
|
||||
|
@ -133,49 +155,77 @@ static void choose_new_current_slab(struct slab_pointer *pool, int order)
|
|||
}
|
||||
}
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("O0")
|
||||
static void *alloc_in_slab_impl(int order)
|
||||
{
|
||||
struct slab_header *current_slab;
|
||||
struct slab_slot_list* free_list;
|
||||
void* next_slot;
|
||||
int status;
|
||||
struct slab_log_entry log;
|
||||
|
||||
lock(&slabs_locks[order]);
|
||||
|
||||
current_slab = slab_pool[order].current_slab;
|
||||
log.from_init = false;
|
||||
log.current_slab = current_slab;
|
||||
/* When serving the first allocation request. */
|
||||
|
||||
if (unlikely(current_slab == NULL)) {
|
||||
current_slab = init_slab_cache(order, SIZE_OF_ONE_SLAB);
|
||||
if (current_slab == NULL) {
|
||||
unlock(&slabs_locks[order]);
|
||||
return NULL;
|
||||
}
|
||||
log.from_init = true;
|
||||
log.current_slab = current_slab;
|
||||
slab_pool[order].current_slab = current_slab;
|
||||
}
|
||||
redo:
|
||||
status = _xbegin();
|
||||
if (status == _XBEGIN_STARTED) {
|
||||
|
||||
free_list = (struct slab_slot_list*)current_slab->free_list_head;
|
||||
BUG_ON(free_list == NULL);
|
||||
next_slot = free_list->next_free;
|
||||
|
||||
free_list = (struct slab_slot_list*)current_slab->free_list_head;
|
||||
BUG_ON(free_list == NULL);
|
||||
prepare_slab_log(&log, current_slab->free_list_head, current_slab->current_free_cnt, next_slot, order);
|
||||
|
||||
next_slot = free_list->next_free;
|
||||
current_slab->free_list_head = next_slot;
|
||||
|
||||
current_slab->current_free_cnt -= 1;
|
||||
_xend();
|
||||
#ifdef USE_TSX
|
||||
if (start_rtm == true) {
|
||||
int status;
|
||||
#ifdef PRE_TOUCH
|
||||
void *tmp1 = current_slab->free_list_head;
|
||||
int tmp2 = current_slab->current_free_cnt;
|
||||
(void) tmp1;
|
||||
(void) tmp2;
|
||||
#endif
|
||||
redo:
|
||||
if ((status = _xbegin()) == _XBEGIN_STARTED) {
|
||||
current_slab->free_list_head = next_slot;
|
||||
current_slab->current_free_cnt -= 1;
|
||||
_xend();
|
||||
} else {
|
||||
// printk("[%s] abort status:%d tid:%d\n", __func__, status, smp_get_cpu_id());
|
||||
slab_abort_count++;
|
||||
kdebug("[%s] abort count %d status %d\n", __func__, slab_abort_count, status);
|
||||
goto redo;
|
||||
}
|
||||
} else {
|
||||
// printk("[%s] abort status:%d tid:%d\n", __func__, status, smp_get_cpu_id());
|
||||
goto redo;
|
||||
current_slab->free_list_head = next_slot;
|
||||
current_slab->current_free_cnt -= 1;
|
||||
}
|
||||
#else
|
||||
current_slab->free_list_head = next_slot;
|
||||
current_slab->current_free_cnt -= 1;
|
||||
#endif
|
||||
/* When current_slab is full, choose a new slab as the current one. */
|
||||
if (unlikely(current_slab->current_free_cnt == 0))
|
||||
choose_new_current_slab(&slab_pool[order], order);
|
||||
|
||||
commit_slab_log(&log);
|
||||
unlock(&slabs_locks[order]);
|
||||
|
||||
return (void *)free_list;
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
|
||||
#if DETECTING_DOUBLE_FREE_IN_SLAB == ON
|
||||
static int check_slot_is_free(struct slab_header *slab_header, struct slab_slot_list* slot)
|
||||
|
|
|
@ -24,6 +24,8 @@ target_compile_options(assert.bin PRIVATE -g3 -ggdb)
|
|||
add_executable(udp_echo_server.bin udp_echo_server.c)
|
||||
add_executable(tcp_echo_server.bin tcp_echo_server.c)
|
||||
|
||||
add_executable(tsx_test.bin tsx_test.c)
|
||||
|
||||
# TreeSLS
|
||||
add_subdirectory(treesls)
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <chcore/pmu.h>
|
||||
#include <pthread.h>
|
||||
#include <chcore/syscall.h>
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("O0")
|
||||
const int num_threads = 10;
|
||||
|
||||
void *work(void *arg) {
|
||||
int i = *(int *)arg;
|
||||
usys_set_affinity(-1, i);
|
||||
usys_yield();
|
||||
s64 start = 0, end = 0;
|
||||
int size = 4096;
|
||||
int count = 1000000 / num_threads;
|
||||
pmu_clear_cnt();
|
||||
start = pmu_read_real_cycle();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
void *m = malloc(size);
|
||||
(void)m;
|
||||
}
|
||||
|
||||
end = pmu_read_real_cycle();
|
||||
printf("tsx_test total %ld\n", end - start);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
pthread_t threads[num_threads];
|
||||
int thread_index[num_threads];
|
||||
for (int i = 0; i < num_threads; i++) {
|
||||
thread_index[i] = i;
|
||||
if (pthread_create(&threads[i], NULL, work, thread_index + i) != 0) {
|
||||
perror("Failed to create thread");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_threads; i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#pragma GCC pop_options
|
Loading…
Reference in New Issue