From 66e54768ef7b5e2e23ad93b14540216b91c90216 Mon Sep 17 00:00:00 2001 From: Sparchatus Date: Thu, 2 Jun 2022 18:58:49 +0000 Subject: [PATCH] Added performance measurements and improvements --- hake/menu.lst.armv8_imx8x | 1 + include/aos/performance.h | 11 +- lib/aos/aos_urpc.c | 26 +- lib/aos/paging.c | 37 + lib/aos/performance.c | 14 +- lib/block_driver/block_driver.c | 29 + lib/fs/fat32.c | 332 +- lib/grading/test_spawn.c | 5 +- lib/spawn/spawn.c | 22 +- performance/performance_evaluation.py | 193 +- .../plots/block_driver/disk_latency.jpg | Bin 0 -> 32840 bytes .../plots/block_driver/no_optimization.jpg | Bin 24800 -> 24630 bytes .../plots/block_driver/no_optimization.log | 3550 +++++++++++------ performance/plots/block_driver/no_sleep.log | Bin 102659 -> 168162 bytes .../plots/block_driver/optimizations.jpg | Bin 25096 -> 24977 bytes performance/plots/file_system/latency.jpg | Bin 0 -> 25128 bytes .../plots/file_system/makro_multi_cache.log | 483 +++ .../file_system/makro_no_optimization.log | 659 +++ .../plots/file_system/micro_multi_cache.log | 1215 ++++++ .../file_system/micro_no_optimization.log | 1391 +++++++ performance/plots/file_system/throughput.jpg | Bin 0 -> 24027 bytes .../plots/paging/no_optimization_core_0.log | 620 +++ .../plots/paging/no_optimization_core_1.log | 620 +++ .../plots/paging/paging_makro_latency.jpg | Bin 0 -> 38533 bytes .../plots/paging/paging_micro_latency.jpg | Bin 0 -> 24773 bytes performance/plots/perf/perf.jpg | Bin 0 -> 39375 bytes performance/plots/perf/perf.log | Bin 0 -> 27481 bytes performance/plots/ump/different_cores.log | 507 +++ performance/plots/ump/latency.jpg | Bin 0 -> 36619 bytes performance/plots/ump/same_core.log | 504 +++ performance/plots/urpc/empty_loop.log | 729 ++++ performance/plots/urpc/micro.jpg | Bin 0 -> 24099 bytes performance/plots/urpc/performance.jpg | Bin 0 -> 22173 bytes performance/plots/urpc/yield.log | Bin 0 -> 48154 bytes platforms/Hakefile | 2 +- usr/drivers/block_driver_server/main.c | 158 +- usr/drivers/sdhc/main.c | 2 +- usr/init/main.c | 20 +- usr/test/filesystem_performance/Hakefile | 19 + usr/test/filesystem_performance/main.c | 291 ++ 40 files changed, 9966 insertions(+), 1474 deletions(-) create mode 100644 performance/plots/block_driver/disk_latency.jpg create mode 100644 performance/plots/file_system/latency.jpg create mode 100644 performance/plots/file_system/makro_multi_cache.log create mode 100644 performance/plots/file_system/makro_no_optimization.log create mode 100644 performance/plots/file_system/micro_multi_cache.log create mode 100644 performance/plots/file_system/micro_no_optimization.log create mode 100644 performance/plots/file_system/throughput.jpg create mode 100644 performance/plots/paging/no_optimization_core_0.log create mode 100644 performance/plots/paging/no_optimization_core_1.log create mode 100644 performance/plots/paging/paging_makro_latency.jpg create mode 100644 performance/plots/paging/paging_micro_latency.jpg create mode 100644 performance/plots/perf/perf.jpg create mode 100644 performance/plots/perf/perf.log create mode 100644 performance/plots/ump/different_cores.log create mode 100644 performance/plots/ump/latency.jpg create mode 100644 performance/plots/ump/same_core.log create mode 100644 performance/plots/urpc/empty_loop.log create mode 100644 performance/plots/urpc/micro.jpg create mode 100644 performance/plots/urpc/performance.jpg create mode 100644 performance/plots/urpc/yield.log create mode 100644 usr/test/filesystem_performance/Hakefile create mode 100644 usr/test/filesystem_performance/main.c diff --git a/hake/menu.lst.armv8_imx8x b/hake/menu.lst.armv8_imx8x index 94510ad..306adf9 100644 --- a/hake/menu.lst.armv8_imx8x +++ b/hake/menu.lst.armv8_imx8x @@ -13,5 +13,6 @@ module /armv8/sbin/stackoverflow module /armv8/sbin/echoserver module /armv8/sbin/shelly module /armv8/sbin/filereader +module /armv8/sbin/filesystem_performance module /armv8/sbin/block_driver_server module /armv8/sbin/netcat diff --git a/include/aos/performance.h b/include/aos/performance.h index 70c9e16..f1122a0 100644 --- a/include/aos/performance.h +++ b/include/aos/performance.h @@ -1,12 +1,15 @@ #ifndef LIBBARRELFISH_PERFORMANCE_H #define LIBBARRELFISH_PERFORMANCE_H -#include +#define PERFORMANCE_MEASUREMENT_COUNT_MAX 100 -#define PERFORMANCE_MEASUREMENT_COUNT_MAX 10 +#include -// uncomment to enable performance measurements -// #define PERFORMANCE_ENABLED +// uncomment to enable performance measurements for the measurement system +// #define PERFORMANCE_PERFORMANCE + +// uncomment to measure URPC performance +// #define URPC_PERFORMANCE struct measurement { const char *tag; diff --git a/lib/aos/aos_urpc.c b/lib/aos/aos_urpc.c index 6511213..1b5f837 100644 --- a/lib/aos/aos_urpc.c +++ b/lib/aos/aos_urpc.c @@ -23,8 +23,8 @@ extern coreid_t my_core_id; extern rpc_handler_t rpc_handlers[RPC_MTYPE_COUNT]; -#ifdef PERFORMANCE_ENABLED -struct performance_context p; +#ifdef URPC_PERFORMANCE +static struct performance_context p; #endif errval_t do_aos_urpc( @@ -143,6 +143,10 @@ static void urpc_server_handler(void *arg) { } static void urpc_server_send_reply(struct aos_urpc_server *urpc, errval_t err) { +#ifdef URPC_PERFORMANCE + uintptr_t msg_type = urpc->meta->a0; +#endif + urpc->meta->a0 = err; if (!capref_is_null(urpc->ret_cap)) { err = cap_direct_identify(urpc->ret_cap, &urpc->meta->cap); @@ -159,15 +163,19 @@ static void urpc_server_send_reply(struct aos_urpc_server *urpc, errval_t err) { "dmb sy\n" ); - // tell the other side that we are done - urpc->meta->call_in_progress = false; - -#ifdef PERFORMANCE_ENABLED +#ifdef URPC_PERFORMANCE if(msg_type == RPC_MTYPE_NOP) { perf_add_now(&p, "done"); } + // memory barrier + __asm volatile ( + "dmb sy\n" + ); #endif + // tell the other side that we are done + urpc->meta->call_in_progress = false; + // Unblock the URPC thread thread_sem_post(&urpc->sem); } @@ -218,7 +226,7 @@ int urpc_server(void *arg) { "dmb sy\n" ); -#ifdef PERFORMANCE_ENABLED +#ifdef URPC_PERFORMANCE bool type_nop = urpc->meta->a0 == RPC_MTYPE_NOP; if(type_nop) { perf_init(&p, "aos_urpc_server"); @@ -229,7 +237,7 @@ int urpc_server(void *arg) { // handle the URPC on the same thread that handles regular RPCs, to avoid concurrency for the handlers waitset_chan_trigger_closure(default_ws, &chan, MKCLOSURE(urpc_server_handler, urpc)); -#ifdef PERFORMANCE_ENABLED +#ifdef URPC_PERFORMANCE if(type_nop) { perf_add_now(&p, "triggered_closure"); } @@ -238,7 +246,7 @@ int urpc_server(void *arg) { // wait until the rpc is handled thread_sem_wait(&urpc->sem); -#ifdef PERFORMANCE_ENABLED +#ifdef URPC_PERFORMANCE if(type_nop) { perf_print(&p); } diff --git a/lib/aos/paging.c b/lib/aos/paging.c index dd96d3c..95bd283 100644 --- a/lib/aos/paging.c +++ b/lib/aos/paging.c @@ -30,6 +30,12 @@ #define PT_STATIC_EXCEPTION_STACK_SIZE (4 * BASE_PAGE_SIZE) +// #define PT_FAULT_PERFORMANCE +#ifdef PT_FAULT_PERFORMANCE +#include +static struct performance_context pcontext; +#endif + static struct paging_state current; // initial page fault handler stack space static char pt_static_exception_stack[PT_STATIC_EXCEPTION_STACK_SIZE]; @@ -95,6 +101,12 @@ static void pt_exception_handler(enum exception_type type, int subtype, void *addr, arch_registers_state_t *regs) { errval_t err; + + #ifdef PT_FAULT_PERFORMANCE + perf_init(&pcontext, "pt_exception"); + perf_add_now(&pcontext, "start"); + #endif + lvaddr_t ip = registers_get_ip(regs); // debug_printf("[pt_exception_handler] type=%s, addr=%p, ip=%p\n", @@ -120,12 +132,21 @@ static void pt_exception_handler(enum exception_type type, int subtype, thread_mutex_lock_nested(&st->lock); // debug_printf("[pt_exception_handler] Got paging mutex.\n"); + #ifdef PT_FAULT_PERFORMANCE + perf_add_now(&pcontext, "locked"); + #endif + struct pt_vaddr_reg_t *vaddr_reg = &st->vaddr_head; for (; vaddr_reg != NULL; vaddr_reg = vaddr_reg->next) { if (vaddr_reg->base <= page_addr && page_addr < vaddr_reg->base + vaddr_reg->size) { break; } } + + #ifdef PT_FAULT_PERFORMANCE + perf_add_now(&pcontext, "vaddr"); + #endif + if (vaddr_reg == NULL) { thread_mutex_unlock(&st->lock); static char str[256]; @@ -148,6 +169,9 @@ static void pt_exception_handler(enum exception_type type, int subtype, if (is_mapped(st, page_addr)) { // Page has already been mapped by another thread before we took the lock. thread_mutex_unlock(&st->lock); + #ifdef PT_FAULT_PERFORMANCE + perf_add_now(&pcontext, "unlocked"); + #endif return; } @@ -158,15 +182,28 @@ static void pt_exception_handler(enum exception_type type, int subtype, USER_PANIC_ERR(err, "Failed to allocate frame in page fault handler"); } + #ifdef PT_FAULT_PERFORMANCE + perf_add_now(&pcontext, "got_frame"); + #endif + err = _paging_map_fixed_attr(st, page_addr, frame, BASE_PAGE_SIZE, VREGION_FLAGS_READ_WRITE); if (err_is_fail(err)) { thread_mutex_unlock(&st->lock); USER_PANIC_ERR(err, "Failed to map frame in page fault handler"); } + #ifdef PT_FAULT_PERFORMANCE + perf_add_now(&pcontext, "mapped"); + #endif + // debug_printf("[pt_exception_handler] Releasing paging mutex.\n"); thread_mutex_unlock(&st->lock); // debug_printf("[pt_exception_handler] done\n"); + + #ifdef PT_FAULT_PERFORMANCE + perf_add_now(&pcontext, "unlocked"); + perf_print(&pcontext); + #endif } /** diff --git a/lib/aos/performance.c b/lib/aos/performance.c index 77cbd1e..0957426 100644 --- a/lib/aos/performance.c +++ b/lib/aos/performance.c @@ -11,21 +11,21 @@ void perf_init(struct performance_context *c, const char *name) { inline void perf_add_measurement(struct performance_context *c, const char *tag, systime_t timestamp) { assert(c->count < PERFORMANCE_MEASUREMENT_COUNT_MAX); - - __asm volatile ( - "dmb sy\n" - ); c->measurements[c->count].tag = tag; c->measurements[c->count].timestamp = timestamp; c->count++; - __asm volatile ( - "dmb sy\n" - ); + } inline void perf_add_now(struct performance_context *c, const char *tag) { + __asm volatile ( + "dmb sy\n" + ); systime_t now = systime_now(); + __asm volatile ( + "dmb sy\n" + ); perf_add_measurement(c, tag, now); } diff --git a/lib/block_driver/block_driver.c b/lib/block_driver/block_driver.c index 6cf05f0..c609438 100644 --- a/lib/block_driver/block_driver.c +++ b/lib/block_driver/block_driver.c @@ -4,6 +4,14 @@ #include +// #define BLOCK_DRIVER_CLIENT_PERFORMANCE +#ifdef BLOCK_DRIVER_CLIENT_PERFORMANCE +#include +static struct performance_context pcontext; +#endif +#ifdef BLOCK_DRIVER_CLIENT_PERFORMANCE +#endif + struct block_driver_state { struct ump_send_chan *send_chan; struct ump_recv_chan *recv_chan; @@ -55,12 +63,19 @@ errval_t block_driver_init(void) { } static void handle_payload(void *arg, size_t payload_size, void *payload) { + #ifdef BLOCK_DRIVER_CLIENT_PERFORMANCE + perf_add_now(&pcontext, "payload"); + #endif state.request_ongoing = false; } static void handle_response(void *arg, size_t header_size, void *header, size_t payload_size) { struct block_driver_result *result = header; + #ifdef BLOCK_DRIVER_CLIENT_PERFORMANCE + perf_add_now(&pcontext, "header"); + #endif + state.result = result->err; if (state.current_request->action == BLOCK_DRIVER_ACTION_READ && err_is_ok(result->err)) { @@ -93,6 +108,11 @@ static errval_t send_blocking_request(enum block_driver_action action, uint64_t assert(state.send_chan != NULL); assert(!state.request_ongoing); + #ifdef BLOCK_DRIVER_CLIENT_PERFORMANCE + perf_init(&pcontext, "block_driver_client"); + perf_add_now(&pcontext, "start"); + #endif + errval_t err; state.request_ongoing = true; @@ -124,6 +144,10 @@ static errval_t send_blocking_request(enum block_driver_action action, uint64_t // register response handler ump_recv_header(state.recv_chan, handle_response, NULL); + #ifdef BLOCK_DRIVER_CLIENT_PERFORMANCE + perf_add_now(&pcontext, "dispatching"); + #endif + // wait for the response while (state.request_ongoing) { err = event_dispatch(&ws); @@ -133,6 +157,11 @@ static errval_t send_blocking_request(enum block_driver_action action, uint64_t } } + #ifdef BLOCK_DRIVER_CLIENT_PERFORMANCE + perf_add_now(&pcontext, "done"); + perf_print(&pcontext); + #endif + return state.result; } diff --git a/lib/fs/fat32.c b/lib/fs/fat32.c index 2476443..1711e7e 100644 --- a/lib/fs/fat32.c +++ b/lib/fs/fat32.c @@ -1,5 +1,4 @@ #include -#include #include #include @@ -7,6 +6,16 @@ #include "fs_internal.h" #include +// enable debug printing +// #define FAT32_DEBUG_ENABLE +#ifdef FAT32_DEBUG_ENABLE +#define FAT32_DEBUG_PRINTF(fmt, args...) DEBUG_PRINTF("[%s] " fmt "\n", __FUNCTION__, args) +#define FAT32_DEBUG_PRINT(s) DEBUG_PRINTF("[%s] " s "\n", __FUNCTION__) +#else +#define FAT32_DEBUG_PRINTF(...) +#define FAT32_DEBUG_PRINT(...) +#endif + // NOTE rueegges: uncomment to enable fat32 performance measurements // #define FAT32_PERFORMANCE #ifdef FAT32_PERFORMANCE @@ -18,7 +27,7 @@ static struct performance_context fat32_perf_context; #define FAT32_PERFORMANCE_START #define FAT32_PERFORMANCE_END #endif -#define FAT32_RUN_LOCKED(s) { /*debug_printf("Locking in %s\n", __FUNCTION__);*/ FAT32_PERFORMANCE_START; err = fat32->lock_fn(); if (err_is_fail(err)) { DEBUG_ERR(err, "locking"); FAT32_PERFORMANCE_END; return err; } err = s; fat32->unlock_fn(); FAT32_PERFORMANCE_END; return err; } +#define FAT32_RUN_LOCKED(s) { FAT32_DEBUG_PRINT("Locking"); FAT32_PERFORMANCE_START; err = fat32->lock_fn(); if (err_is_fail(err)) { DEBUG_ERR(err, "locking"); FAT32_PERFORMANCE_END; return err; } err = s; fat32->unlock_fn(); FAT32_PERFORMANCE_END; return err; } struct fat32_path_resolve_result { struct fat32_directory_entry directory_entry; @@ -81,6 +90,8 @@ static void fat32_fat_entry_parameters(struct fat32 *fat32, uint32_t cluster_num *fat_sector_offset = fat_offset % fat32->bytes_per_sector; } +// set some memory to zero for the operation +static uint8_t zero_mem[FAT32_BLOCK_SIZE] = {0}; /** * @brief set all bytes of all sectors of a cluster to zero */ @@ -89,10 +100,11 @@ static errval_t fat32_zero_cluster(struct fat32 *fat32, uint32_t cluster_number) assert(cluster_number > 1); - // debug_printf("[fat32_zero_cluster] cluster_number: %u\n", cluster_number); + FAT32_DEBUG_PRINTF("cluster_number: %u", cluster_number); - // set some memory to zero - uint8_t zero_mem[FAT32_BLOCK_SIZE] = {0}; + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_zero_cluster" "_pre"); + #endif uint32_t first_sector = fat32_first_sector_of_cluster(fat32, cluster_number); for (size_t i = 0; i < fat32->sectors_per_cluster; ++i) { @@ -102,6 +114,10 @@ static errval_t fat32_zero_cluster(struct fat32 *fat32, uint32_t cluster_number) } + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_zero_cluster" "_post"); + #endif + return SYS_ERR_OK; } @@ -111,6 +127,10 @@ static errval_t fat32_zero_cluster(struct fat32 *fat32, uint32_t cluster_number) static errval_t fat32_fat_write_entry(struct fat32 *fat32, uint32_t cluster_number, uint32_t entry) { errval_t err; + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_fat_write_entry" "_pre"); + #endif + // write to the first or active FAT uint32_t fat_sector_num, fat_sector_offset; fat32_fat_entry_parameters(fat32, cluster_number, &fat_sector_num, &fat_sector_offset); @@ -125,6 +145,10 @@ static errval_t fat32_fat_write_entry(struct fat32 *fat32, uint32_t cluster_numb } } + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_fat_write_entry" "_post"); + #endif + return SYS_ERR_OK; } @@ -136,6 +160,10 @@ static errval_t fat32_next_cluster_in_chain(struct fat32 *fat32, uint32_t cluste static errval_t fat32_alloc_cluster(struct fat32 *fat32, uint32_t *return_cluster_number) { errval_t err; + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_alloc_cluster" "_pre"); + #endif + // just iterate over all FAT entries and return the first free one uint32_t fat[FAT32_FAT_ENTRIES_PER_SECTOR]; for (size_t cluster_number = 2; cluster_number <= fat32->max_cluster_number; ++cluster_number) { @@ -159,12 +187,16 @@ static errval_t fat32_alloc_cluster(struct fat32 *fat32, uint32_t *return_cluste err = fat32_fat_write_entry(fat32, cluster_number, entry); if (err_is_fail(err)) return err; - // debug_printf("[fat32_alloc_cluster] found free cluster: %u\n", cluster_number); + // FAT32_DEBUG_PRINTF("found free cluster: %u", cluster_number); *return_cluster_number = cluster_number; return SYS_ERR_OK; } } + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_alloc_cluster" "_post"); + #endif + // no more free space left return FAT_ERR_FAT_LOOKUP; } @@ -178,6 +210,10 @@ static errval_t fat32_free_cluster(struct fat32 *fat32, uint32_t cluster_number) assert(cluster_number > 1); + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_free_cluster" "_pre"); + #endif + uint32_t fat_sector_num, fat_sector_offset; fat32_fat_entry_parameters(fat32, cluster_number, &fat_sector_num, &fat_sector_offset); @@ -190,6 +226,10 @@ static errval_t fat32_free_cluster(struct fat32 *fat32, uint32_t cluster_number) err = fat32_fat_write_entry(fat32, cluster_number, fat_entry); if (err_is_fail(err)) return err; + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_free_cluster" "_post"); + #endif + return SYS_ERR_OK; } @@ -202,6 +242,10 @@ static errval_t fat32_extend_cluster_chain(struct fat32 *fat32, uint32_t current assert(current_tail_cluster_number > 1); assert(new_tail_cluster_number > 1); + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_extend_cluster_chain" "_pre"); + #endif + uint32_t fat_sector_num, fat_sector_offset; fat32_fat_entry_parameters(fat32, current_tail_cluster_number, &fat_sector_num, &fat_sector_offset); @@ -215,6 +259,10 @@ static errval_t fat32_extend_cluster_chain(struct fat32 *fat32, uint32_t current err = fat32_fat_write_entry(fat32, current_tail_cluster_number, new_entry); if (err_is_fail(err)) return err; + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_extend_cluster_chain" "_post"); + #endif + return SYS_ERR_OK; } @@ -228,6 +276,10 @@ static errval_t fat32_next_cluster_in_chain(struct fat32 *fat32, uint32_t cluste assert(!fat32_is_end_of_cluster_chain(cluster_number)); + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_next_cluster_in_chain" "_pre"); + #endif + uint32_t fat_sector_num, fat_sector_offset; fat32_fat_entry_parameters(fat32, cluster_number, &fat_sector_num, &fat_sector_offset); @@ -237,7 +289,11 @@ static errval_t fat32_next_cluster_in_chain(struct fat32 *fat32, uint32_t cluste // upper 4 bits have to be ignored *return_next_cluster_number &= 0x0FFFFFFF; - // debug_printf("[fat32_next_cluster_in_chain] FAT entry %u: %u\n", cluster_number, *return_next_cluster_number); + // FAT32_DEBUG_PRINTF("FAT entry %u: %u", cluster_number, *return_next_cluster_number); + + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_next_cluster_in_chain" "_post"); + #endif return SYS_ERR_OK; } @@ -248,6 +304,10 @@ static errval_t fat32_next_cluster_in_chain(struct fat32 *fat32, uint32_t cluste static errval_t fat32_next_cluster_in_chain_or_extend(struct fat32 *fat32, uint32_t cluster_number, uint32_t *return_next_cluster_number) { errval_t err; + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_next_cluster_in_chain_or_extend" "_pre"); + #endif + // first see what the next cluster might be err = fat32_next_cluster_in_chain(fat32, cluster_number, return_next_cluster_number); if (err_is_fail(err)) return err; @@ -271,6 +331,10 @@ static errval_t fat32_next_cluster_in_chain_or_extend(struct fat32 *fat32, uint3 err = fat32_extend_cluster_chain(fat32, cluster_number, *return_next_cluster_number); if (err_is_fail(err)) return err; + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_next_cluster_in_chain_or_extend" "_post"); + #endif + return SYS_ERR_OK; } @@ -282,6 +346,10 @@ static errval_t fat32_next_cluster_in_chain_or_extend(struct fat32 *fat32, uint3 static errval_t fat32_free_cluster_chain(struct fat32 *fat32, uint32_t first_cluster) { errval_t err; + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_free_cluster_chain" "_pre"); + #endif + uint32_t current_cluster = first_cluster; while (!fat32_is_end_of_cluster_chain(current_cluster)) { // free cluster entry @@ -295,6 +363,10 @@ static errval_t fat32_free_cluster_chain(struct fat32 *fat32, uint32_t first_clu current_cluster = next_cluster; } + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_free_cluster_chain" "_post"); + #endif + return SYS_ERR_OK; } @@ -359,7 +431,7 @@ static char* fat32_directory_entry_get_nice_name(struct fat32_directory_entry *d name[0] = 0xE5; } - // debug_printf("[fat32_directory_entry_get_nice_name] short_name[%lu]: '%.8s', short_name_ext[%lu]: '%.3s', name: '%s'\n", short_name_len, directory_entry->short_name, short_name_ext_len, directory_entry->short_name_ext, name); + FAT32_DEBUG_PRINTF("short_name[%lu]: '%.8s', short_name_ext[%lu]: '%.3s', name: '%s'", short_name_len, directory_entry->short_name, short_name_ext_len, directory_entry->short_name_ext, name); // empty short_name is not allowed in FAT32 spec assert(short_name_len > 0); @@ -387,6 +459,10 @@ static errval_t fat32_extract_next_path_element( assert(return_short_name != NULL); assert(return_short_name_ext != NULL); + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_extract_next_path_element" "_post"); + #endif + // remove any leading separators while (path_cursor < path_end && *path_cursor == FS_PATH_SEP) { path_cursor++; @@ -417,7 +493,7 @@ static errval_t fat32_extract_next_path_element( return_short_name[1] = '.'; ++path_cursor; } else { - // debug_printf("[fat32_extract_next_path_element] invalid dot start\n"); + FAT32_DEBUG_PRINT("invalid dot start"); // short names of other FAT entries are not allowed to start with a '.' return FAT_ERR_BAD_FILENAME; } @@ -429,7 +505,7 @@ static errval_t fat32_extract_next_path_element( for (size_t short_name_index = 0; path_cursor < path_end && *path_cursor != FS_PATH_SEP && *path_cursor != '.'; ++path_cursor, ++short_name_index) { // the first part of a short name can only contain up to FAT32_SHORTNAME_SIZE characters if (short_name_index >= FAT32_SHORTNAME_SIZE) { - // debug_printf("[fat32_extract_next_path_element] short_name too long\n"); + FAT32_DEBUG_PRINT("short_name too long"); return FAT_ERR_BAD_FILENAME; } @@ -446,7 +522,7 @@ static errval_t fat32_extract_next_path_element( } // short name may not be empty according to FAT32 spec if (return_short_name[0] == ' ') { - // debug_printf("[fat32_extract_next_path_element] short_name empty\n"); + FAT32_DEBUG_PRINT("short_name empty"); return FAT_ERR_BAD_FILENAME; } // the dot is not stored so we need to skip it @@ -457,7 +533,7 @@ static errval_t fat32_extract_next_path_element( for (size_t short_name_ext_index = 0; path_cursor < path_end && *path_cursor != FS_PATH_SEP; ++path_cursor, ++short_name_ext_index) { // the second part of a short name can only contain up to FAT32_SHORTNAME_EXT_SIZE characters if (short_name_ext_index >= FAT32_SHORTNAME_EXT_SIZE) { - // debug_printf("[fat32_extract_next_path_element] short_name_ext too long\n"); + FAT32_DEBUG_PRINT("short_name_ext too long"); return FAT_ERR_BAD_FILENAME; } // no dot allowed in shortname extension @@ -478,6 +554,10 @@ static errval_t fat32_extract_next_path_element( *return_path_cursor = path_cursor; } + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_extract_next_path_element" "_post"); + #endif + return SYS_ERR_OK; } @@ -504,7 +584,7 @@ static errval_t fat32_write_directory_entry( struct fat32_directory_entry_ref directory_entry_ref, struct fat32_directory_entry *directory_entry ) { - // debug_printf("[fat32_write_directory_entry] ref: %lu@%u\n", directory_entry_ref.index_in_sector, directory_entry_ref.sector_number); + // FAT32_DEBUG_PRINTF("ref: %lu@%u", directory_entry_ref.index_in_sector, directory_entry_ref.sector_number); assert(directory_entry_ref.sector_number >= fat32->reserved_sector_count); return fat32->write_object_fn( directory_entry_ref.sector_number, @@ -526,6 +606,10 @@ static errval_t fat32_allocate_directory_entry( errval_t err; + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_allocate_directory_entry" "_pre"); + #endif + uint32_t current_cluster = fat32_directory_entry_to_first_cluster(search_directory); while (!fat32_is_end_of_cluster_chain(current_cluster)) { @@ -550,6 +634,9 @@ static errval_t fat32_allocate_directory_entry( if (directory_entries[directory_index].short_name[0] == 0xE5 || directory_entries[directory_index].short_name[0] == 0x00) { path_resolve_result->directory_entry_ref.sector_number = current_sector; path_resolve_result->directory_entry_ref.index_in_sector = directory_index; + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_allocate_directory_entry" "_post"); + #endif return SYS_ERR_OK; } } @@ -567,6 +654,10 @@ static errval_t fat32_allocate_directory_entry( static errval_t fat32_free_directory_entry(struct fat32 *fat32, struct fat32_directory_entry_ref directory_entry_ref) { errval_t err; + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_free_directory_entry" "_pre"); + #endif + struct fat32_directory_entry directory_entry; err = fat32_read_directory_entry(fat32, directory_entry_ref, &directory_entry); if(err_is_fail(err)) return err; @@ -587,6 +678,10 @@ static errval_t fat32_free_directory_entry(struct fat32 *fat32, struct fat32_dir err = fat32_free_cluster_chain(fat32, fat32_directory_entry_to_first_cluster(&directory_entry)); if (err_is_fail(err)) return err; + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_free_directory_entry" "_post"); + #endif + return SYS_ERR_OK; } @@ -606,6 +701,10 @@ static errval_t fat32_search_in_directory( errval_t err; + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_search_in_directory" "_pre"); + #endif + uint32_t current_cluster = fat32_directory_entry_to_first_cluster(search_directory); while (!fat32_is_end_of_cluster_chain(current_cluster)) { @@ -627,6 +726,7 @@ static errval_t fat32_search_in_directory( if (err_is_fail(err)) return err; for (size_t directory_index = 0; directory_index < FAT32_DIRECTORY_ENTRIES_PER_SECTOR; ++directory_index) { + FAT32_DEBUG_PRINTF("Found entry: %.8s.%.3s", directory_entries[directory_index].short_name, directory_entries[directory_index].short_name_ext); // empty entry if (directory_entries[directory_index].short_name[0] == 0xE5) continue; // no non-empty entry after this entry @@ -652,6 +752,9 @@ static errval_t fat32_search_in_directory( } } + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_search_in_directory" "_post"); + #endif return SYS_ERR_OK; } } @@ -659,7 +762,12 @@ static errval_t fat32_search_in_directory( err = fat32_next_cluster_in_chain(fat32, current_cluster, ¤t_cluster); if (err_is_fail(err)) return err; } + + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_search_in_directory" "_post"); + #endif + FAT32_DEBUG_PRINT("directory entry not found"); return FS_ERR_NOTFOUND; } @@ -675,6 +783,10 @@ static errval_t fat32_check_directory_empty( errval_t err; + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_check_directory_empty" "_pre"); + #endif + uint32_t current_cluster = fat32_directory_entry_to_first_cluster(search_directory); while (!fat32_is_end_of_cluster_chain(current_cluster)) { @@ -705,6 +817,9 @@ static errval_t fat32_check_directory_empty( !fat32_name_is_dot(directory_entries[directory_index].short_name, directory_entries[directory_index].short_name_ext) && !fat32_name_is_dotdot(directory_entries[directory_index].short_name, directory_entries[directory_index].short_name_ext) ) { + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_check_directory_empty" "_post"); + #endif return FS_ERR_NOTEMPTY; } } @@ -713,6 +828,9 @@ static errval_t fat32_check_directory_empty( if (err_is_fail(err)) return err; } + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_check_directory_empty" "_post"); + #endif return SYS_ERR_OK; } @@ -752,13 +870,11 @@ static errval_t fat32_resolve_path_partial( assert(fat32 != NULL); assert(path != NULL); - // debug_printf("[fat32_resolve_path] Resolving path: %.*s\n", path_end - path, path); + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_resolve_path_partial" "_pre"); + #endif - // this MUST be ensured by whomever calls this library because we only allow absolute paths - if (path[0] != '/') { - debug_printf("[fat32_resolve_path] Only absolute paths are allowed (starting with a '/')"); - return FS_ERR_NOTFOUND; - } + FAT32_DEBUG_PRINTF("Resolving path: %.*s", path_end - path, path); // always start traversal in the root directory so we create a mock structure for root struct fat32_path_resolve_result path_resolve_result = { @@ -785,10 +901,11 @@ static errval_t fat32_resolve_path_partial( if (err == FAT_ERR_PATH_EMPTY) break; if (err_is_fail(err)) return err; - // debug_printf("[fat32_resolve_path] Got dirname: '%.8s.%3s'\n", short_name, short_name_ext); + FAT32_DEBUG_PRINTF("Got dirname: '%.8s.%3s'", short_name, short_name_ext); // we can only traverse directories if (!(path_resolve_result.directory_entry.attributes & FAT32_ATTR_DIRECTORY)) { + FAT32_DEBUG_PRINT("Not a directory on the path"); return FS_ERR_NOTDIR; } err = fat32_search_in_directory(fat32, &path_resolve_result.directory_entry, short_name, short_name_ext, &path_resolve_result); @@ -796,12 +913,15 @@ static errval_t fat32_resolve_path_partial( } // we parsed the full path at this point - // debug_printf("[fat32_resolve_path] successfully resolved\n"); + FAT32_DEBUG_PRINT("successfully resolved"); if (return_path_resolve_result != NULL) { *return_path_resolve_result = path_resolve_result; } + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_resolve_path_partial" "_post"); + #endif return SYS_ERR_OK; } /** @@ -850,6 +970,10 @@ static errval_t fat32_create_handle(struct fat32 *fat32, struct fat32_handle **h errval_t err; + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_create_handle" "_pre"); + #endif + *handle = malloc(sizeof(struct fat32_handle)); if (*handle == NULL) return LIB_ERR_MALLOC_FAIL; @@ -863,6 +987,10 @@ static errval_t fat32_create_handle(struct fat32 *fat32, struct fat32_handle **h err = fat32->register_handle_fn(fat32_id_from_directory_entry_ref(directory_entry_ref)); if (err_is_fail(err)) return err; + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_create_handle" "_post"); + #endif + return SYS_ERR_OK; } @@ -883,11 +1011,13 @@ static errval_t fat32_free_handle(struct fat32 *fat32, struct fat32_handle *hand static errval_t fat32_handle_update_current_cluster(struct fat32 *fat32, struct fat32_handle *handle, bool extend) { errval_t err; - // debug_printf("[fat32_handle_update_current_cluster]\n"); + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_handle_update_current_cluster" "_pre"); + #endif size_t cluster_index = handle->byte_offset / fat32->bytes_per_cluster; - // debug_printf("[fat32_handle_update_current_cluster] target cluster %lu for offset %lu\n", cluster_index, handle->byte_offset); + // FAT32_DEBUG_PRINTF("target cluster %lu for offset %lu", cluster_index, handle->byte_offset); if (handle->current_cluster_index_in_chain == cluster_index) return SYS_ERR_OK; @@ -909,12 +1039,20 @@ static errval_t fat32_handle_update_current_cluster(struct fat32 *fat32, struct err = fat32_next_cluster_in_chain(fat32, handle->current_cluster, &next_cluster); if (err_is_fail(err)) return err; - if(fat32_is_end_of_cluster_chain(next_cluster)) return FS_ERR_INDEX_BOUNDS; + if(fat32_is_end_of_cluster_chain(next_cluster)) { + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_handle_update_current_cluster" "_post"); + #endif + return FS_ERR_INDEX_BOUNDS; + } handle->current_cluster = next_cluster; } ++handle->current_cluster_index_in_chain; } + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_handle_update_current_cluster" "_post"); + #endif return SYS_ERR_OK; } @@ -961,36 +1099,36 @@ __attribute__((__unused__)) static void fat32_print(struct bpb *bpb){ struct bpb_fat32 *fat32 = &bpb->bpb_fat.bpb_fat32; - debug_printf("[fat32_print] BPB\n"); - debug_printf("[fat32_print] boot_jump: 0x%x%x%x\n", bpb->jmp_boot[2], bpb->jmp_boot[1], bpb->jmp_boot[0]); - debug_printf("[fat32_print] oem_name: %.8s\n", bpb->oem_name); - debug_printf("[fat32_print] bytes_per_sector: %u\n", bpb->bytes_per_sector); - debug_printf("[fat32_print] sectors_per_cluster: %u\n", bpb->sectors_per_cluster); - debug_printf("[fat32_print] reserved_sector_count: %u\n", bpb->reserved_sector_count); - debug_printf("[fat32_print] number_fats: %u\n", bpb->fat_count); - debug_printf("[fat32_print] root_entry_count: %u\n", bpb->root_entry_count); - debug_printf("[fat32_print] total_sector_16_count: %u\n", bpb->total_sector_16_count); - debug_printf("[fat32_print] media: 0x%x\n", bpb->media); - debug_printf("[fat32_print] fat_sectors_16_count: %u\n", bpb->fat_sectors_16_count); - debug_printf("[fat32_print] sectors_per_track: %u\n", bpb->sectors_per_track); - debug_printf("[fat32_print] number_of_heads: %u\n", bpb->number_of_heads); - debug_printf("[fat32_print] hidden_sector_count: %u\n", bpb->hidden_sector_count); - debug_printf("[fat32_print] total_sector_32_count: %u\n", bpb->total_sector_32_count); + FAT32_DEBUG_PRINT("BPB"); + FAT32_DEBUG_PRINTF(" boot_jump: 0x%x%x%x", bpb->jmp_boot[2], bpb->jmp_boot[1], bpb->jmp_boot[0]); + FAT32_DEBUG_PRINTF(" oem_name: %.8s", bpb->oem_name); + FAT32_DEBUG_PRINTF(" bytes_per_sector: %u", bpb->bytes_per_sector); + FAT32_DEBUG_PRINTF(" sectors_per_cluster: %u", bpb->sectors_per_cluster); + FAT32_DEBUG_PRINTF(" reserved_sector_count: %u", bpb->reserved_sector_count); + FAT32_DEBUG_PRINTF(" number_fats: %u", bpb->fat_count); + FAT32_DEBUG_PRINTF(" root_entry_count: %u", bpb->root_entry_count); + FAT32_DEBUG_PRINTF(" total_sector_16_count: %u", bpb->total_sector_16_count); + FAT32_DEBUG_PRINTF(" media: 0x%x", bpb->media); + FAT32_DEBUG_PRINTF(" fat_sectors_16_count: %u", bpb->fat_sectors_16_count); + FAT32_DEBUG_PRINTF(" sectors_per_track: %u", bpb->sectors_per_track); + FAT32_DEBUG_PRINTF(" number_of_heads: %u", bpb->number_of_heads); + FAT32_DEBUG_PRINTF(" hidden_sector_count: %u", bpb->hidden_sector_count); + FAT32_DEBUG_PRINTF(" total_sector_32_count: %u", bpb->total_sector_32_count); - debug_printf("[fat32_print] FAT32\n"); - debug_printf("[fat32_print] fat_sectors_32_count: %u\n", fat32->fat_sectors_32_count); - debug_printf("[fat32_print] ext_flag_active_fat: %u\n", fat32->ext_flag_active_fat); - debug_printf("[fat32_print] ext_flag_mirrored: %u\n", fat32->ext_flag_mirrored); - debug_printf("[fat32_print] fs_version: %u\n", fat32->fs_version); - debug_printf("[fat32_print] root_cluster_number: %u\n", fat32->root_cluster_number); - debug_printf("[fat32_print] fs_info_cluster_number: %u\n", fat32->fs_info_sector_number); - debug_printf("[fat32_print] backup_boot_sector_number: %u\n", fat32->backup_boot_sector_number); - debug_printf("[fat32_print] drive_number: %u\n", fat32->drive_number); - debug_printf("[fat32_print] extended_boot_signature: 0x%x\n", fat32->extended_boot_signature); + FAT32_DEBUG_PRINT("FAT32"); + FAT32_DEBUG_PRINTF(" fat_sectors_32_count: %u", fat32->fat_sectors_32_count); + FAT32_DEBUG_PRINTF(" ext_flag_active_fat: %u", fat32->ext_flag_active_fat); + FAT32_DEBUG_PRINTF(" ext_flag_mirrored: %u", fat32->ext_flag_mirrored); + FAT32_DEBUG_PRINTF(" fs_version: %u", fat32->fs_version); + FAT32_DEBUG_PRINTF(" root_cluster_number: %u", fat32->root_cluster_number); + FAT32_DEBUG_PRINTF(" fs_info_cluster_number: %u", fat32->fs_info_sector_number); + FAT32_DEBUG_PRINTF(" backup_boot_sector_number: %u", fat32->backup_boot_sector_number); + FAT32_DEBUG_PRINTF(" drive_number: %u", fat32->drive_number); + FAT32_DEBUG_PRINTF(" extended_boot_signature: 0x%x", fat32->extended_boot_signature); if (fat32->extended_boot_signature == 0x29) { - debug_printf("[fat32_print] volume_serial_number: %u\n", fat32->volume_serial_number); - debug_printf("[fat32_print] volume_label: %.11s\n", fat32->volume_label); - debug_printf("[fat32_print] file_system_type: %.8s\n", fat32->file_system_type); + FAT32_DEBUG_PRINTF(" volume_serial_number: %u", fat32->volume_serial_number); + FAT32_DEBUG_PRINTF(" volume_label: %.11s", fat32->volume_label); + FAT32_DEBUG_PRINTF(" file_system_type: %.8s", fat32->file_system_type); } } @@ -1000,7 +1138,7 @@ static void fat32_print(struct bpb *bpb){ * The authors of the FAT32 specification are very strict that it MUST be done exactly this way so here we go. */ static bool is_fat32(struct bpb *bpb) { - // debug_printf("[is_fat32] check fat type\n"); + // FAT32_DEBUG_PRINTF("check fat type"); uint32_t root_dir_sectors = ((bpb->root_entry_count * 32) + (bpb->bytes_per_sector - 1)) / bpb->bytes_per_sector; uint32_t fat_size; @@ -1023,10 +1161,10 @@ static bool is_fat32(struct bpb *bpb) { // NOTE: the number of clusters uint32_t count_of_clusters = data_sec / bpb->sectors_per_cluster; if (count_of_clusters < 4085) { - debug_printf("Got FAT12 file system\n"); + FAT32_DEBUG_PRINT("Got FAT12 file system"); return false; } else if (count_of_clusters < 65525) { - debug_printf("Got FAT16 file system\n"); + FAT32_DEBUG_PRINT("Got FAT16 file system"); return false; } else { return true; @@ -1046,7 +1184,10 @@ errval_t fat32_init( ) { errval_t err; - // debug_printf("[fat32_init]\n"); + // FAT32_DEBUG_PRINTF("[fat32_init]"); + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_init" "_pre"); + #endif struct fat32 *fat32 = malloc(sizeof(struct fat32)); if (fat32 == NULL) return LIB_ERR_MALLOC_FAIL; @@ -1070,7 +1211,7 @@ errval_t fat32_init( } // initialize struct contents - // debug_printf("[fat32_init] initialize state\n"); + // FAT32_DEBUG_PRINTF("initialize state"); fat32->bytes_per_sector = bpb->bytes_per_sector; fat32->sectors_per_cluster = bpb->sectors_per_cluster; fat32->reserved_sector_count = bpb->reserved_sector_count; @@ -1088,15 +1229,19 @@ errval_t fat32_init( // fat32_print(bpb); fat32_verify(bpb); - DEBUG_PRINTF("[fat32_init] verified FAT32\n"); + // FAT32_DEBUG_PRINTF("verified FAT32"); *return_fat32 = fat32; + #ifdef FAT32_PERFORMANCE + perf_add_now(&fat32_perf_context, "fat32_init" "_post"); + #endif + return SYS_ERR_OK; } static errval_t _fat32_mkdir(struct fat32 *fat32, const char *path) { - // debug_printf("[fat32_mkdir]\n"); + // FAT32_DEBUG_PRINTF("[fat32_mkdir]"); errval_t err; // split the path into the part that should exist and the part to create @@ -1105,14 +1250,14 @@ static errval_t _fat32_mkdir(struct fat32 *fat32, const char *path) { // an error in finding means that the basename is empty and thus we are trying to create the root dir if (err_is_fail(err)) return FS_ERR_EXISTS; - // debug_printf("[fat32_mkdir] basename: %s\n", basename); + // FAT32_DEBUG_PRINTF("basename: %s", basename); // resolve the parent path struct fat32_path_resolve_result parent_path_resolve_result; err = fat32_resolve_path_partial(fat32, path, basename, &parent_path_resolve_result); if (err_is_fail(err)) return err; - // debug_printf("[fat32_mkdir] got parent dir\n"); + // FAT32_DEBUG_PRINTF("got parent dir"); char short_name[FAT32_SHORTNAME_SIZE]; char short_name_ext[FAT32_SHORTNAME_EXT_SIZE]; @@ -1126,7 +1271,7 @@ static errval_t _fat32_mkdir(struct fat32 *fat32, const char *path) { if (err_is_fail(err)) return err; // check if the entry already exists - // debug_printf("[fat32_mkdir] checking if dir exists already\n"); + // FAT32_DEBUG_PRINTF("checking if dir exists already"); err = fat32_search_in_directory( fat32, &parent_path_resolve_result.directory_entry, @@ -1138,7 +1283,7 @@ static errval_t _fat32_mkdir(struct fat32 *fat32, const char *path) { if (err_no(err) != FS_ERR_NOTFOUND) return err; // iterate throught the parent directory to find a free entry - // debug_printf("[fat32_mkdir] allocating directory\n"); + // FAT32_DEBUG_PRINTF("allocating directory"); struct fat32_path_resolve_result free_path_resolve_result; err = fat32_allocate_directory_entry( fat32, @@ -1148,13 +1293,13 @@ static errval_t _fat32_mkdir(struct fat32 *fat32, const char *path) { if (err_is_fail(err)) return err; // find a free cluster for the directory - // debug_printf("[fat32_mkdir] get free cluster\n"); + // FAT32_DEBUG_PRINTF("get free cluster"); uint32_t free_cluster_number; err = fat32_alloc_cluster(fat32, &free_cluster_number); if (err_is_fail(err)) return err; // zero out cluster - // debug_printf("[fat32_mkdir] zeroing\n"); + // FAT32_DEBUG_PRINTF("zeroing"); err = fat32_zero_cluster(fat32, free_cluster_number); if (err_is_fail(err)) return err; @@ -1195,7 +1340,7 @@ static errval_t _fat32_mkdir(struct fat32 *fat32, const char *path) { err = fat32_write_directory_entry(fat32, ref, &dotdot_directory_entry); if (err_is_fail(err)) return err; - // debug_printf("[fat32_mkdir] Create the directory entry\n"); + // FAT32_DEBUG_PRINTF("Create the directory entry"); // store the directory in the space in the parent directory we found struct fat32_directory_entry directory_entry = { .attributes = FAT32_ATTR_DIRECTORY, @@ -1212,7 +1357,7 @@ static errval_t _fat32_mkdir(struct fat32 *fat32, const char *path) { err = fat32_write_directory_entry(fat32, free_path_resolve_result.directory_entry_ref, &directory_entry); if (err_is_fail(err)) return err; - // debug_printf("[fat32_mkdir] done\n"); + // FAT32_DEBUG_PRINTF("done"); return SYS_ERR_OK; } @@ -1234,7 +1379,7 @@ static errval_t _fat32_opendir(struct fat32 *fat32, const char *path, struct fat errval_t err; - // debug_printf("[fat32_opendir]\n"); + // FAT32_DEBUG_PRINTF("[fat32_opendir]"); // resolve the path to a directory entry struct fat32_path_resolve_result path_resolve_result; @@ -1269,7 +1414,7 @@ errval_t fat32_opendir(struct fat32 *fat32, const char *path, struct fat32_handl } static errval_t _fat32_closedir(struct fat32 *fat32, struct fat32_handle *dir_handle) { - debug_printf("[fat32_closedir]\n"); + FAT32_DEBUG_PRINT("[fat32_closedir]"); if (!dir_handle->is_dir) return FS_ERR_INVALID_FH; return fat32_free_handle(fat32, dir_handle); @@ -1280,7 +1425,7 @@ errval_t fat32_closedir(struct fat32 *fat32, struct fat32_handle *dir_handle) { } static errval_t _fat32_stat(struct fat32 *fat32, struct fat32_handle *handle, struct fs_fileinfo *fileinfo) { - // debug_printf("[fat32_stat]\n"); + // FAT32_DEBUG_PRINTF("[fat32_stat]"); assert(fileinfo != NULL); errval_t err; @@ -1306,7 +1451,7 @@ errval_t fat32_stat(struct fat32 *fat32, struct fat32_handle *handle, struct fs_ } static errval_t _fat32_readdir(struct fat32 *fat32, struct fat32_handle *dir_handle, char **name) { - // debug_printf("[fat32_readdir]\n"); + // FAT32_DEBUG_PRINTF("[fat32_readdir]"); errval_t err; if (dir_handle == NULL || !dir_handle->is_dir) { @@ -1357,7 +1502,7 @@ errval_t fat32_readdir(struct fat32 *fat32, struct fat32_handle *dir_handle, cha } static errval_t _fat32_rmdir(struct fat32 *fat32, const char *path) { - // debug_printf("[fat32_rmdir]\n"); + // FAT32_DEBUG_PRINTF("[fat32_rmdir]"); errval_t err; struct fat32_path_resolve_result path_resolve_result; @@ -1396,7 +1541,7 @@ errval_t fat32_rmdir(struct fat32 *fat32, const char *path) { } static errval_t _fat32_rm(struct fat32 *fat32, const char *path) { - // debug_printf("[fat32_rm]\n"); + // FAT32_DEBUG_PRINTF("[fat32_rm]"); errval_t err; struct fat32_path_resolve_result path_resolve_result; @@ -1430,7 +1575,7 @@ errval_t fat32_rm(struct fat32 *fat32, const char *path) { } static errval_t _fat32_fcreate(struct fat32 *fat32, const char *path, struct fat32_handle **file_handle) { - // debug_printf("[fat32_fcreate]\n"); + // FAT32_DEBUG_PRINTF("[fat32_fcreate]"); // resolve path to directory cluster errval_t err; @@ -1442,7 +1587,7 @@ static errval_t _fat32_fcreate(struct fat32 *fat32, const char *path, struct fat if (err_no(err) == FAT_ERR_PATH_EMPTY) return FS_ERR_NOTFILE; if (err_is_fail(err)) return err; - // debug_printf("[fat32_fcreate] basename: %s\n", basename); + // FAT32_DEBUG_PRINTF("basename: %s", basename); // resolve the parent path struct fat32_path_resolve_result parent_path_resolve_result; @@ -1488,13 +1633,13 @@ static errval_t _fat32_fcreate(struct fat32 *fat32, const char *path, struct fat err = fat32_alloc_cluster(fat32, &free_cluster_number); if (err_is_fail(err)) return err; - // debug_printf("[fat32_fcreate] Get time information\n"); + // FAT32_DEBUG_PRINTF("Get time information"); // get time information for directory entry creation uint16_t write_date, write_time; fat32_get_time_information(&write_date, &write_time); - // debug_printf("[fat32_fcreate] Create the directory entry\n"); + // FAT32_DEBUG_PRINTF("Create the directory entry"); // store the directory in the space in the parent directory we found assert(free_cluster_number > 1); @@ -1512,7 +1657,7 @@ static errval_t _fat32_fcreate(struct fat32 *fat32, const char *path, struct fat err = fat32->write_object_fn(free_path_resolve_result.directory_entry_ref.sector_number, free_path_resolve_result.directory_entry_ref.index_in_sector * sizeof(struct fat32_directory_entry), sizeof(struct fat32_directory_entry), &directory_entry); if (err_is_fail(err)) return err; - // debug_printf("[fat32_fcreate] done\n"); + // FAT32_DEBUG_PRINTF("done"); err = fat32_create_handle( fat32, @@ -1523,7 +1668,7 @@ static errval_t _fat32_fcreate(struct fat32 *fat32, const char *path, struct fat ); if (err_is_fail(err)) return err; - // debug_printf("[fat32_fcreate] first_cluster: %u\n", (*file_handle)->first_cluster); + // FAT32_DEBUG_PRINTF("first_cluster: %u", (*file_handle)->first_cluster); return SYS_ERR_OK; } @@ -1539,11 +1684,12 @@ errval_t fat32_fcreate(struct fat32 *fat32, const char *path, struct fat32_handl } static errval_t _fat32_fopen(struct fat32 *fat32, const char *path, struct fat32_handle **file_handle) { - // debug_printf("[fat32_fopen]\n"); assert(fat32 != NULL); assert(path != NULL); assert(file_handle != NULL); + FAT32_DEBUG_PRINT("start"); + errval_t err; struct fat32_path_resolve_result path_resolve_result; @@ -1578,13 +1724,13 @@ errval_t fat32_fopen(struct fat32 *fat32, const char *path, struct fat32_handle } static errval_t _fat32_fread(struct fat32 *fat32, struct fat32_handle *file_handle, void *buffer, size_t bytes, size_t *bytes_read) { - debug_printf("[fat32_fread] on %p: %lu bytes from offset %lu\n", file_handle, bytes, file_handle->byte_offset); + FAT32_DEBUG_PRINTF("on %p: %lu bytes from offset %lu", file_handle, bytes, file_handle->byte_offset); errval_t err; if (file_handle == NULL || file_handle->is_dir) return FS_ERR_INVALID_FH; struct fat32_directory_entry directory_entry; - // debug_printf("[fat32_fread] read directory entry\n"); + // FAT32_DEBUG_PRINTF("read directory entry"); err = fat32_read_directory_entry(fat32, file_handle->directory_entry_ref, &directory_entry); if (err_is_fail(err)) return err; @@ -1596,10 +1742,10 @@ static errval_t _fat32_fread(struct fat32 *fat32, struct fat32_handle *file_hand // calculate how much we can read until the end of the file size_t bytes_till_eof = directory_entry.file_size - file_handle->byte_offset; - // debug_printf("[fat32_fread] bytes_till_eof: %lu\n", bytes_till_eof); + // FAT32_DEBUG_PRINTF("bytes_till_eof: %lu", bytes_till_eof); size_t bytes_to_read = MIN(bytes, bytes_till_eof); // if (bytes_to_read < bytes) { - // debug_printf("[fat32_fread] attempted to read over end of file, reading only %lu/%lu\n", bytes_to_read, bytes); + // FAT32_DEBUG_PRINTF("attempted to read over end of file, reading only %lu/%lu", bytes_to_read, bytes); // } // make sure we have the correct current cluster @@ -1626,7 +1772,7 @@ static errval_t _fat32_fread(struct fat32 *fat32, struct fat32_handle *file_hand size_t offset_in_sector = file_handle->byte_offset % fat32->bytes_per_sector; size_t bytes_left_in_sector = FAT32_BLOCK_SIZE - offset_in_sector; size_t bytes_in_sector = MIN(bytes_left_in_sector, bytes_to_read - *bytes_read); - // debug_printf("[fat32_fread] reading %lu from sector %u due to offset %u\n", bytes_in_sector, current_sector, sector_offset); + // FAT32_DEBUG_PRINTF("reading %lu from sector %u due to offset %u", bytes_in_sector, current_sector, sector_offset); err = fat32->read_object_fn(current_sector, offset_in_sector, bytes_in_sector, (buffer + *bytes_read)); if (err_is_fail(err)) return err; @@ -1634,7 +1780,7 @@ static errval_t _fat32_fread(struct fat32 *fat32, struct fat32_handle *file_hand file_handle->byte_offset += bytes_in_sector; // cancel early if we already read enough if (*bytes_read == bytes_to_read) { - // debug_printf("[fat32_fread] file now at offset %lu\n", file_handle->byte_offset); + // FAT32_DEBUG_PRINTF("file now at offset %lu", file_handle->byte_offset); return SYS_ERR_OK; } } @@ -1653,7 +1799,7 @@ errval_t fat32_fread(struct fat32 *fat32, struct fat32_handle *file_handle, void } static errval_t _fat32_fwrite(struct fat32 *fat32, struct fat32_handle *file_handle, const void *buffer, size_t bytes, size_t *bytes_written) { - // debug_printf("[fat32_fwrite] %lu bytes\n", bytes); + // FAT32_DEBUG_PRINTF("%lu bytes", bytes); errval_t err; if (file_handle == NULL || file_handle->is_dir) return FS_ERR_INVALID_FH; @@ -1681,7 +1827,7 @@ static errval_t _fat32_fwrite(struct fat32 *fat32, struct fat32_handle *file_han *bytes_written = 0; while (*bytes_written < bytes) { // make sure we never try to look at the reserved clusters during traversal - // debug_printf("Write in cluster: %u\n", file_handle->current_cluster); + // FAT32_DEBUG_PRINTF("Write in cluster: %u", file_handle->current_cluster); assert(file_handle->current_cluster > 1); assert(!fat32_is_end_of_cluster_chain(file_handle->current_cluster)); @@ -1718,7 +1864,7 @@ static errval_t _fat32_fwrite(struct fat32 *fat32, struct fat32_handle *file_han // if we had to increase the file size write it in the directory if (directory_entry.file_size < file_handle->byte_offset) { directory_entry.file_size = file_handle->byte_offset; - // debug_printf("File got larger, is now: %lu\n", directory_entry.file_size); + // FAT32_DEBUG_PRINTF("File got larger, is now: %lu", directory_entry.file_size); } // update last write time @@ -1746,7 +1892,7 @@ errval_t fat32_fwrite(struct fat32 *fat32, struct fat32_handle *file_handle, con } static errval_t _fat32_fclose(struct fat32 *fat32, struct fat32_handle *file_handle) { - // debug_printf("[fat32_fclose]\n"); + // FAT32_DEBUG_PRINTF("[fat32_fclose]"); if (file_handle == NULL || file_handle->is_dir) return FS_ERR_INVALID_FH; @@ -1758,15 +1904,15 @@ errval_t fat32_fclose(struct fat32 *fat32, struct fat32_handle *file_handle) { } errval_t fat32_tell(struct fat32 *fat32, struct fat32_handle *file_handle, size_t *pos) { - // debug_printf("[fat32_tell]\n"); + // FAT32_DEBUG_PRINTF("[fat32_tell]"); // get the current position if it is a file and return 0 otherwise *pos = file_handle->is_dir ? 0 : file_handle->byte_offset; - // debug_printf("[fat32_tell] @%lu\n", file_handle->byte_offset); + // FAT32_DEBUG_PRINTF("@%lu", file_handle->byte_offset); return SYS_ERR_OK; } static errval_t _fat32_seek(struct fat32 *fat32, struct fat32_handle *file_handle, enum fs_seekpos whence, off_t offset) { - // debug_printf("[fat32_seek] whence: %ld@%d\n", offset, whence); + // FAT32_DEBUG_PRINTF("whence: %ld@%d", offset, whence); errval_t err; if (file_handle == NULL || file_handle->is_dir) return FS_ERR_INVALID_FH; diff --git a/lib/grading/test_spawn.c b/lib/grading/test_spawn.c index b5f37c7..4a78d57 100644 --- a/lib/grading/test_spawn.c +++ b/lib/grading/test_spawn.c @@ -12,7 +12,10 @@ void do_test_spawn(void) { domainid_t *pid = malloc(PROCESS_COUNT * sizeof(domainid_t)); for(uint i = 0; i < PROCESS_COUNT; ++i) { debug_printf("TEST_SPAWN: spawn %u\n", i); - CHECK_ERR(spawn_load_by_name("hello", &(si[i]), &(pid[i]))); + // char *argv = "filesystem_performance"; + // char *argv = "/sdcard/perf"; + char *argv = "hello"; + CHECK_ERR(spawn_load_argv(1, &argv, &(si[i]), &(pid[i]))); } // wait for 10 seconds but handle events in the mean time diff --git a/lib/spawn/spawn.c b/lib/spawn/spawn.c index d5677fa..35d09c1 100644 --- a/lib/spawn/spawn.c +++ b/lib/spawn/spawn.c @@ -98,7 +98,7 @@ static void handle_child_recv(void *arg) { switch(msg.words[0]){ case RPC_MTYPE_CHILD_ENDPOINT: - // debug_printf("SPAWN: Received child init_chan endpoint\n"); + // DEBUG_PRINTF("SPAWN: Received child init_chan endpoint\n"); si->init_chan.remote_cap = cap; err = lmp_chan_alloc_recv_slot(&si->init_chan); if (err_is_fail(err)) { @@ -166,7 +166,7 @@ static errval_t elf_allocate( if (flags & PF_R) paging_flags |= KPI_PAGING_FLAGS_READ; // Map into child address space - // debug_printf("SPAWN: allocate base:%"PRIxPTR", size: %"PRIxPTR", flags: %"PRIu32"\n", + // DEBUG_PRINTF("SPAWN: allocate base:%"PRIxPTR", size: %"PRIxPTR", flags: %"PRIu32"\n", // base, size, paging_flags); err = paging_map_fixed_attr( st->paging_state, sv, frame, @@ -342,7 +342,7 @@ static errval_t spawn_serialize_vspace(struct spawninfo *si, struct paging_state assert(curr_offset <= total_space); - // debug_printf("SPAWN: Passing vspace info at 0x%lx\n", vspace_buf_child); + // DEBUG_PRINTF("SPAWN: Passing vspace info at 0x%lx\n", vspace_buf_child); domain_params->vspace_buf = vspace_buf_child; domain_params->vspace_buf_len = total_space; @@ -351,7 +351,7 @@ static errval_t spawn_serialize_vspace(struct spawninfo *si, struct paging_state static errval_t spawn_load_elf_from_fs(char *path, char **elf_base, size_t *elf_bytes) { int res; - debug_printf("[spawn_load_elf_from_fs] %s\n", path); + DEBUG_PRINTF("[spawn_load_elf_from_fs] %s\n", path); // open the file FILE *f = fopen(path, "r"); @@ -370,7 +370,7 @@ static errval_t spawn_load_elf_from_fs(char *path, char **elf_base, size_t *elf_ if(*elf_base == NULL) return LIB_ERR_MALLOC_FAIL; // load the elf to memory - debug_printf("[spawn_load_elf_from_fs] reading elf file with %lu bytes\n", *elf_bytes); + DEBUG_PRINTF("[spawn_load_elf_from_fs] reading elf file with %lu bytes\n", *elf_bytes); size_t read_bytes = fread(*elf_base, 1, *elf_bytes, f); if (read_bytes != *elf_bytes) return FS_ERR_READ; @@ -437,7 +437,7 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, errval_t err; if(argc == 0) { - debug_printf("[spawn_load_argv] argc == 0 (no arguments)\n"); + DEBUG_PRINTF("[spawn_load_argv] argc == 0 (no arguments)\n"); return SPAWN_ERR_FIND_MODULE; } @@ -469,7 +469,7 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, // - Get the module from the multiboot image // and map it (take a look at multiboot.c) - // debug_printf("[spawn_load_argv]: argc: %d, argv: ", argc); + // DEBUG_PRINTF("[spawn_load_argv]: argc: %d, argv: ", argc); // for (int i = 0; i < argc; ++i) { // printf("\"%s\", ", argv[i]); // } @@ -589,9 +589,9 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, }; // char buf[256]; // debug_print_cap_at_capref(buf, 256, cap_io); - // debug_printf(buf); + // DEBUG_PRINTF(buf); // printf("\n"); - // debug_printf("offset=%x\n", arg0_base - IMX8X_START_DEV_RANGE); + // DEBUG_PRINTF("offset=%x\n", arg0_base - IMX8X_START_DEV_RANGE); err = cap_retype(arg0_cap, cap_io, (arg0_base - IMX8X_START_DEV_RANGE), ObjType_DevFrame, arg0_size, 1); if (err_is_fail(err)) return err_push(err, LIB_ERR_CAP_RETYPE); } @@ -641,7 +641,7 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, got_addr = got_shdr->sh_addr; } - // debug_printf("SPAWN: self paging state after loading:\n"); + // DEBUG_PRINTF("SPAWN: self paging state after loading:\n"); // pt_print_state(get_current_paging_state()); if (is_multiboot) { @@ -659,7 +659,7 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, free(tm); } - // debug_printf("SPAWN: self paging state after unmapping:\n"); + // DEBUG_PRINTF("SPAWN: self paging state after unmapping:\n"); // pt_print_state(get_current_paging_state()); // - Setup the dispatcher diff --git a/performance/performance_evaluation.py b/performance/performance_evaluation.py index 045c6fd..bbb2270 100644 --- a/performance/performance_evaluation.py +++ b/performance/performance_evaluation.py @@ -12,6 +12,7 @@ from numpy import std MEASUREMENT_TAG = "MEASUREMENT" # searches for a measurement with #1 name, #2 tag, #3 time MEASUREMENT_REGEX = r"^.* " + MEASUREMENT_TAG + r" ([a-zA-Z_:-]*) ([0-9]*)$" +FREQUENCY = 8000000 # TODO change this for the actual measurement # data_basedir = os.environ.get("BFBUILD_QEMU") @@ -38,7 +39,7 @@ def read_data(file): with open(file) as f: return f.readlines() -def build_dataseries(measurements, start_tag, end_tag): +def build_dataseries(measurements, start_tag, end_tag, divider=(FREQUENCY / 1000)): datapoints = [] measurements = list(filter(lambda m: start_tag == m["tag"] or end_tag == m["tag"], measurements)) @@ -51,7 +52,8 @@ def build_dataseries(measurements, start_tag, end_tag): print(f"[ERROR] Got end tag without start {end_tag}") else: if m["tag"] == end_tag: - datapoints.append(m["timestamp"] - started_at) + duration = (m["timestamp"] - started_at) / divider + datapoints.append(duration) started_at = None elif m["tag"] == start_tag: print(f"[ERROR] Invalid sequence, ignoring last start tag {start_tag}") @@ -67,69 +69,188 @@ def get_measurements_from_file(file): return measurements -def create_bar_chart(dataset, title, out_file): - # calculate stats for each data series +def create_metrics(dataset, unit="ms"): metrics = {} for key in dataset: d_mean = mean(dataset[key]) d_std = std(dataset[key]) d_median = median(dataset[key]) metrics[key] = (d_mean, d_std) + print(f"{key} - mean: {d_mean} {unit}, std: {d_std}") + + return metrics + +def create_timeline(dataset, title, file, unit="cycles", loc="center right"): + p.clf() + p.title(title) + p.xlabel("i-th measurement") + p.ylabel(f"duration ({unit})") + for key in dataset: + p.plot(range(len(dataset[key])), dataset[key], label=key) + + p.legend(loc=loc) + p.savefig(os.path.join(out_dir, file)) + +def create_bar_chart(metrics, title, out_file, figsize=(8,4), unit="ms"): + # calculate stats for each data series # create the plot p.clf() - fig, ax = p.subplots() #figsize=(12,5)) + fig, ax = p.subplots(figsize=figsize) p.title(title) - p.ylabel("median duration (cycles)") + p.ylabel(f"median duration ({unit})") p.bar( metrics.keys(), [x[0] for x in metrics.values()], yerr=[x[1] for x in metrics.values()], + capsize=5 ) ax.set_ylim(0) p.savefig(os.path.join(out_dir, out_file)) +def create_multi_bar_chart(metrics_groups, title, out_file, figsize=(8,4), width=0.4, unit="ms"): + # calculate stats for each data series + + labels = list(metrics_groups[list(metrics_groups.keys())[0]].keys()) + x = list(range(len(labels))) + + # create the plot + p.clf() + fig, ax = p.subplots(figsize=figsize) + p.title(title) + p.ylabel(f"median duration ({unit})") + for i, key in enumerate(metrics_groups.keys()): + offset = - width / 2 + 2 * i * (width / len(metrics_groups)) + b = ax.bar( + list(map(lambda a: a + offset, x)), + [x[0] for x in metrics_groups[key].values()], + width, + label=key, + yerr=[x[1] for x in metrics_groups[key].values()], + capsize=5 + ) + # ax.bar_label(b) + + #draw grouped bar chart + ax.set_xticks(x, labels) + ax.legend() + + fig.tight_layout() + p.savefig(os.path.join(out_dir, out_file)) + + def main(): - dataset = {} - - # dataset["performance"] = build_dataseries(measurements, "aos_performance:start", "aos_performance:done") + # dataset = {} + # measurements = get_measurements_from_file("perf/perf.log") + # dataset["measurements"] = build_dataseries(measurements, "aos_performance:start", "aos_performance:done", divider=1) + # create_timeline(dataset, "Performance Measurement System Latency", "perf/perf.jpg") # URPC - # title = "URPC Micro Benchmark" - # dataset["client_to_server"] = build_dataseries(measurements, "aos_urpc_nop:start", "aos_urpc_server:start") - # dataset["server_schedule_task"] = build_dataseries(measurements, "aos_urpc_server:start", "aos_urpc_server:triggered_closure") - # dataset["server_completed_task"] = build_dataseries(measurements, "aos_urpc_server:triggered_closure", "aos_urpc_server:done") - # dataset["server_to_client"] = build_dataseries(measurements, "aos_urpc_server:done", "aos_urpc_nop:done") + # dataset = {} + # yielded_measurements = get_measurements_from_file("urpc/yield.log") + # dataset["yield_to_server"] = build_dataseries(yielded_measurements, "aos_urpc_nop:start", "aos_urpc_server:start", divider=1) + # dataset["yield_to_client"] = build_dataseries(yielded_measurements, "aos_urpc_server:done", "aos_urpc_nop:done", divider=1) + # measurements = get_measurements_from_file("urpc/empty_loop.log") + # dataset["empty_to_server"] = build_dataseries(measurements, "aos_urpc_nop:start", "aos_urpc_server:start", divider=1) + # dataset["empty_to_client"] = build_dataseries(measurements, "aos_urpc_server:done", "aos_urpc_nop:done", divider=1) + # create_bar_chart(create_metrics(dataset, unit="cycles"), "URPC Yield vs Empty Loop", "urpc/performance.jpg", unit="cycles") + # dataset = {} + # dataset["client_to_server"] = build_dataseries(yielded_measurements, "aos_urpc_nop:start", "aos_urpc_server:start", divider=1) + # dataset["server_scheduled"] = build_dataseries(yielded_measurements, "aos_urpc_server:start", "aos_urpc_server:triggered_closure", divider=1) + # dataset["server_completed"] = build_dataseries(yielded_measurements, "aos_urpc_server:triggered_closure", "aos_urpc_server:done", divider=1) + # dataset["server_to_client"] = build_dataseries(yielded_measurements, "aos_urpc_server:done", "aos_urpc_nop:done", divider=1) + # create_bar_chart(create_metrics(dataset, unit="cycles"), "URPC Micro Benchmark", "urpc/micro.jpg", unit="cycles") # BLOCK DRIVER # measurements = get_measurements_from_file("block_driver/no_optimization.log") + # # disk latency without optimization # dataset = {} - # # we skip the first datapoint here because it is reliably very high compared to all others - # dataset["read_device"] = build_dataseries(measurements, "block_driver_read_object:start", "block_driver_read_object:memcpy")[1:] - # dataset["read_memcpy"] = build_dataseries(measurements, "block_driver_read_object:memcpy", "block_driver_read_object:done") - # dataset["write_read"] = build_dataseries(measurements, "block_driver_write_object:start", "block_driver_write_object:read") - # dataset["write_memcpy"] = build_dataseries(measurements, "block_driver_write_object:read", "block_driver_write_object:memcpy") - # dataset["write_device"] = build_dataseries(measurements, "block_driver_write_object:memcpy", "block_driver_write_object:done") - # create_bar_chart(dataset, "Block Driver Micro Benchmark", "block_driver/no_optimization.jpg") + # # we only take 200 measurements to not overload the plot and to have the same number of read and write measurements + # dataset["read unoptimized"] = build_dataseries(measurements, "block_driver_read_object:start", "block_driver_read_object:memcpy")[10:210] + # dataset["write unoptimized"] = build_dataseries(measurements, "block_driver_write_object:memcpy", "block_driver_write_object:done")[10:210] + # # disk latency with optimization # measurements = get_measurements_from_file("block_driver/no_sleep.log") - # dataset_compare = {} - # dataset_compare["read_unopt"] = dataset["read_device"] - # dataset_compare["write_unopt"] = dataset["write_device"] - # dataset_compare["read_nosleep"] = build_dataseries(measurements, "block_driver_read_object:start", "block_driver_read_object:memcpy")[1:] - # dataset_compare["write_nosleep"] = build_dataseries(measurements, "block_driver_write_object:memcpy", "block_driver_write_object:done") - # create_bar_chart(dataset_compare, "Block Driver Optimizations", "block_driver/optimizations.jpg") + # # we only take 200 measurements to not overload the plot and to have the same number of read and write measurements + # dataset["read optimized"] = build_dataseries(measurements, "block_driver_read_object:start", "block_driver_read_object:memcpy")[10:210] + # dataset["write optimized"] = build_dataseries(measurements, "block_driver_write_object:memcpy", "block_driver_write_object:done")[10:210] + # create_metrics(dataset) + # create_timeline(dataset, "Block Driver Disk Latency", "block_driver/disk_latency.jpg", unit="ms") - # create plots for data series - # for key in dataset: - # d = dataset[key] - # p.clf() - # p.title(key) - # p.xlabel("datapoint index") - # p.ylabel("duration (cycles)") - # p.plot(range(len(d)), d) - # p.savefig(os.path.join(out_dir, f"{key}.jpg")) + # FILESYSTEM + # throughput + # metrics = {} + # measurements = get_measurements_from_file("file_system/makro_no_optimization.log") + # dataset_unopt = {} + # dataset_unopt["read"] = list(map(lambda d: 10 * 4096 / d, build_dataseries(measurements, "measure_read_throughput:pre", "measure_read_throughput:post", divider=FREQUENCY)))[1:] + # dataset_unopt["write"] = list(map(lambda d: 10 * 4096 / d, build_dataseries(measurements, "measure_write_throughput:pre", "measure_write_throughput:post", divider=FREQUENCY)))[1:] + # metrics["unoptimized"] = create_metrics(dataset_unopt) + # measurements = get_measurements_from_file("file_system/makro_multi_cache.log") + # dataset_opt = {} + # dataset_opt["read"] = list(map(lambda d: 10 * 4096 / d, build_dataseries(measurements, "measure_read_throughput:pre", "measure_read_throughput:post", divider=FREQUENCY)))[1:] + # dataset_opt["write"] = list(map(lambda d: 10 * 4096 / d, build_dataseries(measurements, "measure_write_throughput:pre", "measure_write_throughput:post", divider=FREQUENCY)))[1:] + # metrics["optimized"] = create_metrics(dataset_opt) + # create_multi_bar_chart(metrics, "Filesystem Throughput", "file_system/throughput.jpg", unit="bytes/s") + # latencies of other functions + # metrics = {} + # dataset_noopt = {} + # measurements = get_measurements_from_file("file_system/makro_no_optimization.log") + # dataset_noopt["fopen"] = build_dataseries(measurements, "measure_fopen_fclose:pre_open", "measure_fopen_fclose:post_open") + # dataset_noopt["fclose"] = build_dataseries(measurements, "measure_fopen_fclose:pre_close", "measure_fopen_fclose:post_close") + # dataset_noopt["fcreate"] = build_dataseries(measurements, "measure_fcreate_and_rm_single:pre_create", "measure_fcreate_and_rm_single:post_create") + # dataset_noopt["rm"] = build_dataseries(measurements, "measure_fcreate_and_rm_single:pre_rm", "measure_fcreate_and_rm_single:post_rm") + # dataset_noopt["mkdir"] = build_dataseries(measurements, "measure_mkdir_and_rmdir_single:pre_mkdir", "measure_mkdir_and_rmdir_single:post_mkdir") + # dataset_noopt["rmdir"] = build_dataseries(measurements, "measure_mkdir_and_rmdir_single:pre_rmdir", "measure_mkdir_and_rmdir_single:post_rmdir") + # metrics["unoptimized"] = create_metrics(dataset_noopt) + # dataset_opt = {} + # measurements = get_measurements_from_file("file_system/makro_multi_cache.log") + # dataset_opt["fopen"] = build_dataseries(measurements, "measure_fopen_fclose:pre_open", "measure_fopen_fclose:post_open") + # dataset_opt["fclose"] = build_dataseries(measurements, "measure_fopen_fclose:pre_close", "measure_fopen_fclose:post_close") + # dataset_opt["fcreate"] = build_dataseries(measurements, "measure_fcreate_and_rm_single:pre_create", "measure_fcreate_and_rm_single:post_create") + # dataset_opt["rm"] = build_dataseries(measurements, "measure_fcreate_and_rm_single:pre_rm", "measure_fcreate_and_rm_single:post_rm") + # dataset_opt["mkdir"] = build_dataseries(measurements, "measure_mkdir_and_rmdir_single:pre_mkdir", "measure_mkdir_and_rmdir_single:post_mkdir") + # dataset_opt["rmdir"] = build_dataseries(measurements, "measure_mkdir_and_rmdir_single:pre_rmdir", "measure_mkdir_and_rmdir_single:post_rmdir") + # metrics["optimized"] = create_metrics(dataset_opt) + # create_multi_bar_chart(metrics, "Filesystem Operation Latency", "file_system/latency.jpg") + + # PAGING + # makro + # dataset = {} + # measurements = get_measurements_from_file("paging/no_optimization_core_1.log") + # dataset["core 1"] = build_dataseries(measurements, "pt_exception:start", "pt_exception:unlocked") + # measurements = get_measurements_from_file("paging/no_optimization_core_0.log") + # dataset["core 0"] = build_dataseries(measurements, "pt_exception:start", "pt_exception:unlocked") + # create_timeline(dataset, "Pagefault handling latency", "paging/paging_makro_latency.jpg", unit="ms") + # # micro + # dataset = {} + # metrics = {} + # measurements = get_measurements_from_file("paging/no_optimization_core_0.log") + # dataset["locking"] = build_dataseries(measurements, "pt_exception:start", "pt_exception:locked") + # dataset["resolve vaddr"] = build_dataseries(measurements, "pt_exception:locked", "pt_exception:vaddr") + # dataset["request memory"] = build_dataseries(measurements, "pt_exception:vaddr", "pt_exception:got_frame") + # dataset["mapping"] = build_dataseries(measurements, "pt_exception:got_frame", "pt_exception:mapped") + # dataset["unlocking"] = build_dataseries(measurements, "pt_exception:mapped", "pt_exception:unlocked") + # metrics["core 0"] = create_metrics(dataset) + # dataset = {} + # measurements = get_measurements_from_file("paging/no_optimization_core_1.log") + # dataset["locking"] = build_dataseries(measurements, "pt_exception:start", "pt_exception:locked") + # dataset["resolve vaddr"] = build_dataseries(measurements, "pt_exception:locked", "pt_exception:vaddr") + # dataset["request memory"] = build_dataseries(measurements, "pt_exception:vaddr", "pt_exception:got_frame") + # dataset["mapping"] = build_dataseries(measurements, "pt_exception:got_frame", "pt_exception:mapped") + # dataset["unlocking"] = build_dataseries(measurements, "pt_exception:mapped", "pt_exception:unlocked") + # metrics["core 1"] = create_metrics(dataset) + # create_multi_bar_chart(metrics, "Pagefault handling micro benchmark", "paging/paging_micro_latency.jpg") + + # UMP + # dataset = {} + # measurements = get_measurements_from_file("ump/different_cores.log") + # dataset["different cores"] = build_dataseries(measurements, "block_driver_client:dispatching", "block_driver_client:payload", 1)[10:] + # measurements = get_measurements_from_file("ump/same_core.log") + # dataset["same core"] = build_dataseries(measurements, "block_driver_client:dispatching", "block_driver_client:payload", 1)[10:] + # create_timeline(dataset, "UMP roundtrip latency", "ump/latency.jpg") + + pass if __name__ == "__main__": main() diff --git a/performance/plots/block_driver/disk_latency.jpg b/performance/plots/block_driver/disk_latency.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8c98b88c9ce094623bf66917c854340b691cd3d6 GIT binary patch literal 32840 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 delta 10499 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
#=jAs*TE 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�Db_~h;8SZ#vPnwk~;E*op-)94@Xj zX8K#Z;^gzI>LusWnkG-RaiNJ2awN{%2u);TT<9i&M%rG>j#+7qQ}446X?1 z!)GCE#j3-(^Fvc(TC56~x!&-`Ry$DBUpXtNWtxWgXh@QxXQtz<(t?(@n#N^@-r;^b zD%Ccnuw5st)~J>C6YL?Nyb6_;^~y!vh9+0#y1!wOd2SwVU8wxdb7X0X1sf&F9I4Z^ zK%-wA9ipQeOdH%f7d4@kdKECYD#dP-lHTh=+CE~vG%oTi;^ypG&tHo+i*QuK*(@!h zmB5+58f6dX^qQm84i8m?F%pW*U}QhhqWN%$o~|AZLbFx^dprfi7p>g{n$uEW_gdgs zby;TMs-rktPF~tBjuXW=0OGuqY#|%_(%4={tyq97IB_V#Tj8&BIAJj^v;#q#%U+Bt z!)m+|E9x4!w;S!{voO!%kS_P>Sj0zfnMGL^J%w=u?4Ms70&44R%C98FAv%HDuwNLD_d!wO3-lg3%uY* z!f5nU^1IpG38VM9?6?u$d%xfN1h)j;B=Eg-Gtx^QhHfp!!dD=yPDyFRyvL_!cnHqy^WgCQt29)yQO2FBpQ>r zmzcIWN;OSjm{>6Pa!wwXVWE3<%DsPd>pamMv=%J^qv;th4EHKpJ6Llv_oArQtZOud z-4?9oyk?jr!Em4zAu`N>C(o^lY7M%!FNN(j4ACs0GW$IDwYql>!kRoaDl3sPK_ezd z!8VbNTtn<&pnlH#;sc=_0dsH2v)hBDRd0(A9Fq=lK_GXCTls1gD|RqYiNGWk3tF)i z$KnW>Sy}H*tahNLzjEe%%j`Ark;%x5*!jZV7PKT)hFmyZ)aJ_j7IJM<3fncu+rrk` z$L;`Ccr+qFlf$Q&OegVixrO)D#}^v%Wf2ZK(becZxX!4=NzJ5iok*MRLupw7lV7@c z@#3c!$D$g(oiD4!`)Y9%ipdPO?M-H1eW?+ z@aT;Xfgmk3*PyhJn;9vaiE*!0=hF+Pg>ud7Xcs}au6z4re6AG9+RoiDP>G;j= z7Jr|BH970~3cD{jM#C+*Vj#ZOSp}uv4_oIkzUSj976?2Ugdv z3yUUlEmo9Edgy%Kgw|q}z}yPt-D34Q%^0zwlA-Kn!w{!^u%dDguPkDfz+4aGO{{hx z8KLPS`Cj5*bjZae<9@s3l1v45A8`W=nC}=DwPI9bQ+;47qrz@MiMBROM_^Z)e102#P%x?%>o>Mgg}_w zwJWa60%jqf9c+UIOth^5Kue&81qJTgOM2LdL)Rg+7=X6=@C6Dx^~znv0=m8}$+*2t z?27BMz{#;}uz-oS7YoqUtw@l)@Tn{13(#r@?U|i7M_SZ1zCdC7?Kq-YfU7MNG$`lE zgU149sAUJ+U;z_tKNb|I5O%*BwWTY?f;=cfWEgw#1qz!xd-DXMSdhoKr=TpDSsuIM zy1u}PQX4E_qVXPD&j>lXM<(d5z~ep-TC)J#ZKzN4>Sc^C$O${-S}bqWngvBtrnrHS zCl4MAn1)~n+h73`jrY)o1qCK=oT=nJH4j>`07s`%B*~fbktY54f`YJdT-_&kH4BP7PI1nd zhsBC{P{hweX0U+2 zg=7b7`vN{1PoT;d;Hi-$3AyzmJZQ}V^cK(Dt7lsL(!K!a6eYI*83FkX^qatOlg6(0 zZ*q6nSUu;>l8i!%#*oX89EuDX^fVoE* z?Uwq9&YvX!ZKokETim_1O|(&fL;>!Z@TfH&w*i!>{ocU7CvTC@_FyW8>kL`!w= z>??6t)T&uqpdik@+p9&i64+lm6xS6@bA-kj6dB6ooYzK8WFyuX2~%8~?7E_BLMz59 zVD3rAos9KrQ(CMsZk@yZ$UYTTixs`0aHiR(kI`b4z}$J!n^^5Y&BcJTf?6@P(GX5K zMDW&*Q9uits45U#fcU7Q@`+q4Utzn(F0D~(?IT}`+F<6W?Mjo+|0R`@kYVyk70*Tx&}5G>J*A zHe5!Dy(8!P#U^qsTNGDdm(Gu7PpU_A)Sp^XOEQ zGba}ww3I@Q_BSOm8@;$$jopKr#U=`FR`+(UheEEDDFP-7m}opzX?w*6585j_cYtpN zMv4VFb<)Kpt$j?k3Y%NG#uJG01v$zeuwlo5 z+_{=q6WPd?x(MLx5OYps4O)v<0W%4~5-siN8mbegr8PVGn*I@y7dbEReS-?f(J+x*)8RLj* z)W^;O+8*KftMk@R%U+EyP}t6^uNJmu0eTvfM1JR!Et=tl*b;J$kt~xf(i|}kE<0zu zn$S|T2AJt^>^9LcFz(Xc4%Rg=F4{f@hNni|m3uR(7FDGbke!C{W*IYh;SE|Fn8xO= zKY7@i1&~IGw!t0^j62gXS>ScvQf?M4cyYwd{ZaxO3((LQDQc!w@ibMlKw>*LNotK+ zu>chZA=+2`YpratLMjkr_&qD3d_hRp3cI)LXlcr@Kx2Dlm}UX2g6h#d`U2-5sX1?H z<3+nU?0h*l@@OL0vZaU*tW1xx zmsk^Y!zj2#y)5KftQi{b;ryp}CxCvw0QTlzxlX{YA33)e-n%|)Yoap5$GrhKG|G%A zwrZ#aEo~Kf5?qY#UWDI5u9Yvb{T73$DF9m@0dA>gx){6C8oo;IAvw(_O$O|P##5DM zL5z#z5N&%Um|_9WVr4bXnU~$ zR|J${koDjT=#EpAwY%outSnI2&TE1ewq^m^(1(%NRd>ovKiMg@!2%}Qek{mw0wKzo z^B@me`2t)Sg3@{Cn6RZO;|mlv*J632RxH4M9B328jg#z(>-YjLS?yq57I4vc53Oee zbf3h50lNAL4W^UZ9rfWnXw3rLRMyi~SZIJj*v=j{ZbNJ*}%>sq(b=1liWH}o1;$$Un)ON*neE~D*vV(2-0w&si zEP$pW>~`{=ng^|B1iGpnC#$`Nw1x!=n|p4bH)_QKoJhe zCzP$aZ$V2^VT%*@Jz=}ZQTHw6TKNjQhlMw!fp&%k(-qj2CZE4i&d-cq>|jj>^p=D} zhNQ$gllj#9umDxI0o4`t!2*emeIuXP$_L=g6w=4sq@-POT^2Co06W+Q3z%p;RcT*< z29dZ@Fztf{*ocX6D%Gc^j4vn@w%1WB7L+)N5*6HCNxR}YEZ}Z;+rhdl;G*rt0@Rq& zC55hYcFS+883C<`agl)E5^2K%jopJUKp#6gSL`#`cGerovlD8S8Ln;0owH_5|k93^Xm(>o5kS}6jJoCnnjA6y6rf3h-#Ux zCV|H8A*X@!2Xq#P8z|Zp*JXhdr8Zc=MBB&BmgtZfV|C;;Fp^Rzv4Mg=S-?fxj|I5EjvDm)42%>DLR{yHE{A=DT&QK2*#0M5 zoazap7>8+j@~|te;|rYiMtJSX7Q>86oKkjGTNBy%S=7X!y}YwuXhJIk)4)#iV@I^y zjUT(7x(3EY+snYhEJsO=^C`!cGn7&&kv7KN?#@-FE##U63Y)1bot01y}X6H ztYfmktH)9y7YI<|`bF+F6+C$=7DTww6L&8%9TpGSus~ybjXpFBGNk6%d0D&SI=+DG z4DDcDU%*A<3DmG4M{+OByjqoJ0q#Dat6h217H`ls3lw$_EQoP(4i^%FyH`J-on2gA z9Shl>d)+=;-EoelEJ^A2lJhai?fQ#u&<(Yq%OlPnIx1aCVt(^?+y#DYbdKmfpwb_Y z(8}-?Fn5J$x7ANH{H?5S3P4*bYTwEra4w^0BG;lt>1Kk;WB;O+z`uXd#&jJm_x3iH z(rVG7?g33tUHxlQYnrtZnD)OeC(}wSC%;y7hkb?yz*>#eP?A1p8b{Xm(Z3oGR&jJK z{mpAJpNZf@IUe5(f@2Y4wBqIgE>DaX^II_=kC)X-FoXKfXB#;Fjkwb_anO{qQDBO@ zD?kn-)K9IsYCxqj@4$lAqLsj0SIHBt z&neA_HlfSyxcjQC=dW3t;fN*@pWZz>uHXW2z3uMN$B^sc4VR}drq5!D)hG-Xkl;w3 z&v~*|Sec;i%DIro;${>u(=)I{>s-*=9HkL$i76O2S@0OZQkoGhu4u*;z0O&`=Af0E zQNUay?{2^eV_p8fJf>oYJgZl)|C*xZ<`k3iXo7RUe4T($J+8pH{A~)rh!zcHL-z|rn#i?i(ai_vYJ3`mW~~ISJ5hOzX6Q;$ zp8c{E)`y#cd&TCs^PZqhVQ?}5?pinQ+sBln6sCcFiMC!Y`xv3Ng942)@aTO^x5#(l zx<>A5oaGm_SQRjH%q+%wU5p#i;&f?82U%y zpaOcyc{hd{nMpI2aGeYOHXRL(Gs95@uZI=Z(#7RsS>bi>T-pOhEs;y+8j>enpCnMe z2IGuz@1%SC@uuR|(oNF@4e)%rNF!Z|Oeva9p_3d3s*qHj6N))QzhzFNYFe$TYr5(3 znw;F%PnM(MU@>}fH&|4&)sx!?dNn#)eOP_Na|aC7_j0j&h$Ii16DD5sT(#MZ?A5ibrHg|4Jm$8MVh!6!S0cOhlp>|o zcZ2rDUF3f~S6{59i^~o29-6Ge;v}+LxAc~D`{Hhi^9t_O)lKWIrArMiP=4xjF4Npq z$X>Guy?6#xwxAcib0aLfbQAPlbZ?Z}#5U5E$kZmao^r>7$@G3viR!~0YF(?5DmLy; zk-Fp%*4O@*%$W#qFlR=%rZ_lV*!mFM`mch&-|c}xfP*|*|(?pA&xOW zWX>l8ns!ioFw{^*1)7cV;=8@1E0MXag&5N9X?}>&zYs|Z=HiAWfwgqe38rAD7FpQZ zgW(V!kn6nCt{la1I$u_BEU)+Sc=&*Fc!>W}zYcG4`^7Ig5}biRA4s2*e@z^m0Z4Gq zEOU2#AL1xvZin#CXO;=-gHX88LryltI+5BrbL)8alCDJN?gf5E=^~Rs7yWp2`!#n_ z?VRDl44>;z?esJ1kZwYfTB%(nS#%wu$5>F1RR@* zxyP0FkgP`Lo_zDhSvyeEb2+oWW&WD}c-%P0#r0lS?vhv`vidmdhuiLaI@>h?B)D_C zg_cZ|ZQ-D9j9ei_?i=BCz5f;?G~w;P$?M3r?gmaLH$zl7OjhE@zdilqql5ngE%RNF diff --git a/performance/plots/block_driver/optimizations.jpg b/performance/plots/block_driver/optimizations.jpg index e6ff5df2402da54c9896f55a7e01bdb426c96f6c..032b4660bf21e0366d466285244948e41e81e442 100644 GIT binary patch delta 8543 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 M82f)4DPipY0cPjLg#Z8m diff --git a/performance/plots/file_system/latency.jpg b/performance/plots/file_system/latency.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c04100368c00120e7f3e82e561de893ed93228a2 GIT binary patch literal 25128 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�v!?kbEypBqpjx*wM$@4~)g;bCJA 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 T>D-e44>#Y*|K`tBzeoND=S&)n literal 0 HcmV?d00001 diff --git a/performance/plots/paging/paging_micro_latency.jpg b/performance/plots/paging/paging_micro_latency.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2c79f69f55dd54a2c9ed14d05d54bae6e08d7a26 GIT binary patch literal 24773 zcmeHv2Urwawr(LgOU^++g5;c&2ndLPH zK0X>IVR0cIF%Dino*x%MKu1T%!o(uQ#wO*tLwSeizx)UP3gDq3yho%(M4$t1;UOU6 zA;4P!8UR2*2JiOA4gd6qa0?L$83h#$9Rm|=P<|V@g@A~73keY!83_q&?F)VnAmJh7 z-{F=2vsGz8>p{b>3N^*6PZ3A!XRegTey4hqicWa+27VN|G%qef9}{{`ZWb$AtHbe4-pTL1kNs* zQ~fahVOuuG9=pqxc1?YCz|^d;r{#M(&e0@fKt)!@&fUS+j%qBURh#%Qbf^b2P@Xy^ z3@s-cNR4MJZXxJl&2vtTafkS&JXa8Z!@w&GL4q{hQ^NW}ElmHkds9vt>6tXuI>PZ2 z(LC$^Z6ZR8*f4-PGp(Z9|8Pn)UNq7MCF>M%H3c7V_5Wt-JIc|4qPKPdO zkvTo_^nTdFqfq~6DJMcm-`!CB7*lg9@-x#3`Y+$4wm32S+hBDQ3!?+{l>3twq+*BS zwkrUkn(TjU8iFKl;{kXOXF^6BBsI@467PfsZE=OB?~pcSDP%%5aMKW|jF}j`82@;C z<^frh&tocgmL@W)CM3K~=3BNu5AQt+yB@oyJLOdY&V-?a0ZiD%qYEFFKBM}J1jYUI z5VEc6Dk>t;)~W(nn4la)5zVm_NIR-t3Adh!|KdVFU+{l$FSfQAv=N?tuHYJP2FXgi zuOfnn_(;bSH#|a`DZzzEsfEQgbKWEJs>Ll!X&(+mp-!sn=(6v$rX&l<%3VaeT>%ei z0&NPd-9<8M7kbti-k6SX%z3_wB#TaUp?HS#SjV-4aGu=b#Zqe=#*|){V`&QnyZdf; zOn^E?z$7hYw9u*_SDoO}YTfwWalMS{5I=6|xAM!`^~0DDx{3+yC%rOQIa{6l$&e*u z(xwG{V?rv)hvcruMV?$Q_Ir??bbi+Dmon9?!FpP><WLW zNN7@W9nvhF!1HcFb5`?%Fn~(gxn|U>zVdZhA!aD#L4BFhmXbbaiLiHkhQdeNnw!z7 z+(>E3XD)q!YZC3jb<7-N{gAz@3eHCU(}>uNaVyr<+Jf)dpFezOAv0BBB3-P81Gl%P z!b6U6QH;OA0m}}m_KKn&to4zssoRPO-9^|WosUHlayr{wYXSpYgCz;(w?r^D1X**~ zptcpGub6f5+ydn_9drFO!Y2DvvOV0jMz^m8PXk8MYDUU68mfsGBI#b58)l<1Bqw?; z2{DCzKu~WbUoBoZ-!UQYc+I!1&%*j*k0g=vz}|4l)GBLEqF&fFJdAOSy^g}&&Iw

v0j+liv2OoJhWVd-x_&ls>4c(7JxN;p<8 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 literal 0 HcmV?d00001 diff --git a/performance/plots/perf/perf.jpg b/performance/plots/perf/perf.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7bb9bed15ab8754b46349a9229091bd45fd8403e GIT binary patch literal 39375 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�dTvzh@QkO~UbeEMK=K`*<`g!t?v(X@Tb- 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 mR5z>oOt7hAqynx#* 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 literal 0 HcmV?d00001 diff --git a/performance/plots/urpc/performance.jpg b/performance/plots/urpc/performance.jpg new file mode 100644 index 0000000000000000000000000000000000000000..49334208f1ba84f6582f771325b73403cdd6f8fd GIT binary patch literal 22173 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 literal 0 HcmV?d00001 diff --git a/performance/plots/urpc/yield.log b/performance/plots/urpc/yield.log new file mode 100644 index 0000000000000000000000000000000000000000..f5ba966fa324fd6d17332026571281515df2165c GIT binary patch literal 48154 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 literal 0 HcmV?d00001 diff --git a/platforms/Hakefile b/platforms/Hakefile index b7e1aba..2c867e5 100644 --- a/platforms/Hakefile +++ b/platforms/Hakefile @@ -12,7 +12,7 @@ let -- Default list of modules to build/install - modules_common = [ "/sbin/" ++ f | f <- [ "init", "hello", "mallocator", "stackoverflow", "echoserver", "enet", "shelly", "filereader", "block_driver_server", "netcat" + modules_common = [ "/sbin/" ++ f | f <- [ "init", "hello", "mallocator", "stackoverflow", "echoserver", "enet", "shelly", "filereader", "block_driver_server", "netcat", "filesystem_performance" ] ] in [ diff --git a/usr/drivers/block_driver_server/main.c b/usr/drivers/block_driver_server/main.c index 290a022..cf953c0 100644 --- a/usr/drivers/block_driver_server/main.c +++ b/usr/drivers/block_driver_server/main.c @@ -8,10 +8,10 @@ #include #include -// #define BLOCK_DRIVER_PERFORMANCE -#ifdef BLOCK_DRIVER_PERFORMANCE +// #define BLOCK_DRIVER_SERVER_PERFORMANCE +#ifdef BLOCK_DRIVER_SERVER_PERFORMANCE #include -struct performance_context pcontext; +static struct performance_context pcontext; #endif struct block_driver_state { @@ -42,11 +42,81 @@ struct handle *handle_list_head = NULL; struct handle *handle_list_tail = NULL; // very simple cache to keep the last block so it does not need to be reread all the time -#define BLOCK_DRIVER_CACHE -#ifdef BLOCK_DRIVER_CACHE +// #define BLOCK_DRIVER_SINGLE_CACHE + +#ifdef BLOCK_DRIVER_SINGLE_CACHE uint32_t current_block_in_buffer = UINT32_MAX; #endif +#define BLOCK_DRIVER_MULTI_CACHE +#ifdef BLOCK_DRIVER_MULTI_CACHE +#define BLOCK_DRIVER_CACHE_BLOCKS 2000 +struct cache_metadata { + uint32_t block_number; + size_t access_time; +}; +static char block_driver_cache[BLOCK_DRIVER_CACHE_BLOCKS * SDHC_BLOCK_SIZE]; +static struct cache_metadata block_driver_cache_metadata[BLOCK_DRIVER_CACHE_BLOCKS]; +static size_t block_driver_current_cache_time = 0; + +static void init_cache(void) { + for (size_t i = 0; i < BLOCK_DRIVER_CACHE_BLOCKS; ++i) { + block_driver_cache_metadata[i].access_time = 0; + block_driver_cache_metadata[i].block_number = UINT32_MAX; + } +} + +static void add_to_cache(uint32_t block_number) { + assert(block_number != UINT32_MAX); + // if it is already in the cache then update the access_time + // also keep track of the entry with the lowest access_time + size_t evict = 0; + size_t lowest_time = SIZE_T_MAX; + for (size_t i = 0; i < BLOCK_DRIVER_CACHE_BLOCKS; ++i) { + if (block_driver_cache_metadata[i].block_number == block_number) { + // debug_printf("Already in the cache %u at %lu\n", block_number, i); + // update the value in the cache + memcpy(&block_driver_cache[i * SDHC_BLOCK_SIZE], dma_buffer, SDHC_BLOCK_SIZE); + block_driver_cache_metadata[i].access_time = ++block_driver_current_cache_time; + return; + } + if (block_driver_cache_metadata[i].access_time < lowest_time) { + lowest_time = block_driver_cache_metadata[i].access_time; + evict = i; + } + } + + // debug_printf("Adding %u to cache at %lu\n", block_number, evict); + + // add it to the cache and evict an entry with the smallest access_time (oldest/LRU) + memcpy(&block_driver_cache[evict * SDHC_BLOCK_SIZE], dma_buffer, SDHC_BLOCK_SIZE); + block_driver_cache_metadata[evict].access_time = ++block_driver_current_cache_time; + block_driver_cache_metadata[evict].block_number = block_number; +} + +static bool load_from_cache(uint32_t block_number) { + assert(block_number != UINT32_MAX); + for (size_t i = 0; i < BLOCK_DRIVER_CACHE_BLOCKS; ++i) { + if (block_driver_cache_metadata[i].block_number == block_number) { + // debug_printf("HIT for %u at %lu\n", block_number, i); + block_driver_cache_metadata[i].access_time = ++block_driver_current_cache_time; + memcpy(dma_buffer, &block_driver_cache[i * SDHC_BLOCK_SIZE], SDHC_BLOCK_SIZE); + __asm volatile ( + "dmb sy\n" + ); + cpu_dcache_wbinv_range((genvaddr_t)dma_buffer, SDHC_BLOCK_SIZE); + return true; + } + } + // debug_printf("MISS!\n"); + return false; +} + +#endif + +// don't read a block during writing if the whole block gets overwritten +#define BLOCK_DRIVER_OPTIMIZE_FULL_WRITE + static errval_t read_buffer(int block_number) { assert(block_number != UINT32_MAX); @@ -54,30 +124,40 @@ static errval_t read_buffer(int block_number) { // debug_printf("[block_driver_server] read block %d\n", block_number); - #ifdef BLOCK_DRIVER_CACHE + #ifdef BLOCK_DRIVER_SINGLE_CACHE // very primitive cache for the last read block if(current_block_in_buffer == block_number) { return SYS_ERR_OK; } #endif + #ifdef BLOCK_DRIVER_MULTI_CACHE + if(load_from_cache(block_number)) { + return SYS_ERR_OK; + } + #endif + err = sdhc_read_block(sdhc, block_number, (lpaddr_t)dma_buffer_phys); if(err_is_fail(err)) { - #ifdef BLOCK_DRIVER_CACHE + #ifdef BLOCK_DRIVER_SINGLE_CACHE // maybe there was a partial modification so invalidate the cache current_block_in_buffer = UINT32_MAX; #endif + // debug_printf("[block_driver_server] err done\n"); return err; } - #ifdef BLOCK_DRIVER_CACHE - current_block_in_buffer = block_number; - #endif - __asm volatile ( "dmb sy\n" ); cpu_dcache_wbinv_range((genvaddr_t)dma_buffer, SDHC_BLOCK_SIZE); + #ifdef BLOCK_DRIVER_SINGLE_CACHE + current_block_in_buffer = block_number; + #endif + #ifdef BLOCK_DRIVER_MULTI_CACHE + add_to_cache(block_number); + #endif + return SYS_ERR_OK; } @@ -86,7 +166,7 @@ static errval_t write_buffer(int block_number) { errval_t err; - // debug_printf("[block_driver_server] write block %d\n", block_number); + debug_printf("[block_driver_server] write block %d\n", block_number); __asm volatile ( "dmb sy\n" @@ -96,6 +176,7 @@ static errval_t write_buffer(int block_number) { err = sdhc_write_block(sdhc, block_number, (lpaddr_t)dma_buffer_phys); if(err_is_fail(err)) return err; + // debug_printf("[block_driver_server] done\n"); return SYS_ERR_OK; } @@ -216,7 +297,7 @@ static errval_t read_object(uint32_t block_number, size_t offset, size_t size, v return BLOCK_ERR_OVERFLOW_BLOCK; } - #ifdef BLOCK_DRIVER_PERFORMANCE + #ifdef BLOCK_DRIVER_SERVER_PERFORMANCE perf_init(&pcontext, "block_driver_read_object"); perf_add_now(&pcontext, "start"); #endif @@ -224,15 +305,13 @@ static errval_t read_object(uint32_t block_number, size_t offset, size_t size, v err = read_buffer(block_number); if (err_is_fail(err)) return err; - #ifdef BLOCK_DRIVER_PERFORMANCE + #ifdef BLOCK_DRIVER_SERVER_PERFORMANCE perf_add_now(&pcontext, "memcpy"); #endif memcpy(dst, dma_buffer + offset, size); - // debug_printf("Read start: '%.5s'\n", dst); - - #ifdef BLOCK_DRIVER_PERFORMANCE + #ifdef BLOCK_DRIVER_SERVER_PERFORMANCE perf_add_now(&pcontext, "done"); perf_print(&pcontext); #endif @@ -258,37 +337,44 @@ static errval_t write_object(uint32_t block_number, size_t offset, size_t size, return BLOCK_ERR_WRITE_BOOTSECTOR; } - #ifdef BLOCK_DRIVER_PERFORMANCE + #ifdef BLOCK_DRIVER_SERVER_PERFORMANCE perf_init(&pcontext, "block_driver_write_object"); perf_add_now(&pcontext, "start"); #endif // if we are not writing the full block then we need to copy the current block + #ifdef BLOCK_DRIVER_OPTIMIZE_FULL_WRITE if (size < SDHC_BLOCK_SIZE) { + #endif err = read_buffer(block_number); if (err_is_fail(err)) return err; + #ifdef BLOCK_DRIVER_OPTIMIZE_FULL_WRITE } + #endif - #ifdef BLOCK_DRIVER_PERFORMANCE + #ifdef BLOCK_DRIVER_SERVER_PERFORMANCE perf_add_now(&pcontext, "read"); #endif // debug_printf("Write start: '%.5s'\n", src); memcpy(dma_buffer + offset, src, size); - - #ifdef BLOCK_DRIVER_CACHE + + #ifdef BLOCK_DRIVER_SINGLE_CACHE // update the cache metadata current_block_in_buffer = block_number; #endif + #ifdef BLOCK_DRIVER_MULTI_CACHE + add_to_cache(block_number); + #endif - #ifdef BLOCK_DRIVER_PERFORMANCE + #ifdef BLOCK_DRIVER_SERVER_PERFORMANCE perf_add_now(&pcontext, "memcpy"); #endif err = write_buffer(block_number); if (err_is_fail(err)) return err; - #ifdef BLOCK_DRIVER_PERFORMANCE + #ifdef BLOCK_DRIVER_SERVER_PERFORMANCE perf_add_now(&pcontext, "done"); perf_print(&pcontext); #endif @@ -343,15 +429,20 @@ static void handle_request(void *arg, size_t header_size, void *header, size_t p if (request->bytes > SDHC_BLOCK_SIZE) { send_error_response(state, ERR_INVALID_ARGS); } else if (request->action == BLOCK_DRIVER_ACTION_READ) { - // perform read directly - void *response_buffer = malloc(request->bytes); - if (response_buffer == NULL) USER_PANIC("Ran out of memory"); - - err = read_object(request->block_number, request->offset, request->bytes, response_buffer); - if (err_is_fail(err)) { - send_error_response(state, err); + // if no bytes were requested just return ok. This allows measuring performance of this UMP interface + if(request->bytes == 0) { + send_response(state, SYS_ERR_OK, 0, NULL); } else { - send_response(state, SYS_ERR_OK, request->bytes, response_buffer); + // perform read directly + void *response_buffer = malloc(request->bytes); + if (response_buffer == NULL) USER_PANIC("Ran out of memory"); + + err = read_object(request->block_number, request->offset, request->bytes, response_buffer); + if (err_is_fail(err)) { + send_error_response(state, err); + } else { + send_response(state, SYS_ERR_OK, request->bytes, response_buffer); + } } } else if (request->action == BLOCK_DRIVER_ACTION_WRITE) { if (request->bytes != payload_size) { @@ -505,6 +596,11 @@ int main(int argc, char *argv[]) { err = ump_binding_register(&server, UMP_SERVER_BLOCK_DRIVER, connect_callback, NULL); if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to register UMP server"); + #ifdef BLOCK_DRIVER_MULTI_CACHE + // initialize the cache + init_cache(); + #endif + // wait for connections to the server printf("[block_driver_server] ready\n"); struct waitset *default_ws = get_default_waitset(); diff --git a/usr/drivers/sdhc/main.c b/usr/drivers/sdhc/main.c index 616c750..6cfe4fb 100644 --- a/usr/drivers/sdhc/main.c +++ b/usr/drivers/sdhc/main.c @@ -284,7 +284,7 @@ static errval_t sdhc_send_cmd(struct sdhc_s * sd, struct cmd * cmd) { dump(sd); USER_PANIC("Command not Ackd?"); } - barrelfish_usleep(100); + barrelfish_usleep(10); if(tc || cc) break; } while (true); DEBUG("Command complete!\n"); diff --git a/usr/init/main.c b/usr/init/main.c index b691aab..24a6a4e 100644 --- a/usr/init/main.c +++ b/usr/init/main.c @@ -394,7 +394,8 @@ app_main(int argc, char *argv[]) { ram_alloc_set(ram_alloc_remote_core); -#ifdef PERFORMANCE_ENABLED +#ifdef PERFORMANCE_PERFORMANCE + // wait for other stuff to complete barrelfish_usleep(2000000); struct performance_context p; @@ -406,16 +407,25 @@ app_main(int argc, char *argv[]) { perf_print(&p); barrelfish_usleep(10000); } + abort(); +#endif +#ifdef URPC_PERFORMANCE + // wait for other stuff to complete + barrelfish_usleep(2000000); + + struct performance_context urpc_pcontext; // measure URPC performance for(size_t i = 0; i < 100; ++i) { - perf_init(&p, "aos_urpc_nop"); - perf_add_now(&p, "start"); + perf_init(&urpc_pcontext, "aos_urpc_nop"); + perf_add_now(&urpc_pcontext, "start"); do_aos_urpc(&urpc_to_bsp, RPC_MTYPE_NOP, NULL_CAP, 0, 0, 0, NULL, NULL, NULL, NULL); - perf_add_now(&p, "done"); - perf_print(&p); + perf_add_now(&urpc_pcontext, "done"); + perf_print(&urpc_pcontext); + // make sure we give the server some time to print measurements barrelfish_usleep(10000); } + abort(); #endif // Allocate all pages of the thread stack now. diff --git a/usr/test/filesystem_performance/Hakefile b/usr/test/filesystem_performance/Hakefile new file mode 100644 index 0000000..5980044 --- /dev/null +++ b/usr/test/filesystem_performance/Hakefile @@ -0,0 +1,19 @@ +-------------------------------------------------------------------------- +-- Copyright (c) 2020, ETH Zurich. +-- All rights reserved. +-- +-- This file is distributed under the terms in the attached LICENSE file. +-- If you do not find this file, copies can be found by writing to: +-- ETH Zurich D-INFK, Universitaetstr 6, CH-8092 Zurich. Attn: Systems Group. +-- +-- Hakefile for /usr/test/filereader +-- +-------------------------------------------------------------------------- + +[ build application { + target = "filesystem_performance", + cFiles = [ "main.c" ], + addLibraries = [ "fs" ], + architectures = allArchitectures + } +] diff --git a/usr/test/filesystem_performance/main.c b/usr/test/filesystem_performance/main.c new file mode 100644 index 0000000..744f1ae --- /dev/null +++ b/usr/test/filesystem_performance/main.c @@ -0,0 +1,291 @@ +/** + * \file + * \brief file system test application + */ + +/* + * Copyright (c) 2016 ETH Zurich. + * All rights reserved. + * + * This file is distributed under the terms in the attached LICENSE file. + * If you do not find this file, copies can be found by writing to: + * ETH Zurich D=INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich, + * Attn: Systems Group. + */ + + +#include + +#include +#include +#include +#include +#include + +#define MOUNTPOINT "/sdcard" +#define FILENAME "/test.txt" +#define DIRNAME "/tdir" + +#define ITERATIONS 100 +#define THROUGHPUT_MEASUREMENT_BYTES (10 * PAGE_SIZE) + +#define MEASUREMENT_PREAMBLE \ + debug_printf("\n-------------------------------\n"); \ + debug_printf("Measuring: %s\n", __FUNCTION__); + +// #define MEASUREMENT_ENABLED +#ifdef MEASUREMENT_ENABLED +#include +static struct performance_context perf_context; +#define PERF_INIT {perf_init(&perf_context, __FUNCTION__);} +#define PERF_PRINT {perf_print(&perf_context);} +#define PERF_ADD(tag) {perf_add_now(&perf_context, tag);} +#else +#define PERF_INIT +#define PERF_PRINT +#define PERF_ADD(tag) +#endif + +__attribute__((__used__)) +static void measure_fopen_fclose(void) { + MEASUREMENT_PREAMBLE + + char *file = MOUNTPOINT FILENAME; + FILE *f; + int res; + + // first we open because it might need to be created + f = fopen(file, "w"); + assert(f != NULL); + res = fclose(f); + assert(res == 0); + + // measure latency to open multiple times + PERF_INIT + for(size_t i = 0; i < ITERATIONS; ++i) { + PERF_ADD("pre_open") + f = fopen(file, "r"); + PERF_ADD("post_open") + assert(f != NULL); + PERF_ADD("pre_close") + res = fclose(f); + PERF_ADD("post_close") + assert(res == 0); + } + PERF_PRINT +} + +__attribute__((__used__)) +static void measure_fcreate_and_rm_single(void) { + MEASUREMENT_PREAMBLE + + char *file = MOUNTPOINT FILENAME; + FILE *f; + int res; + errval_t err; + + // make sure the file does not exist + rm(file); + + // create and delete a file many times + PERF_INIT + for(size_t i = 0; i < ITERATIONS; ++i) { + PERF_ADD("pre_create") + f = fopen(file, "w"); + PERF_ADD("post_create") + assert(f != NULL); + res = fclose(f); + assert(res == 0); + + PERF_ADD("pre_rm") + err = rm(file); + PERF_ADD("post_rm") + assert(err_is_ok(err)); + } + PERF_PRINT +} + +__attribute__((__used__)) +static void measure_fcreate_and_rm_many(void) { + MEASUREMENT_PREAMBLE + + FILE *f; + int res; + errval_t err; + char name[256] = {0}; + + // create many files + PERF_INIT + for(size_t i = 0; i < ITERATIONS; ++i) { + snprintf(name, 256, MOUNTPOINT "/%lu.txt", i); + PERF_ADD("pre_create") + f = fopen(name, "w"); + PERF_ADD("post_create") + assert(f != NULL); + res = fclose(f); + assert(res == 0);; + } + PERF_PRINT + + // delete many files + PERF_INIT + for(size_t i = 0; i < ITERATIONS; ++i) { + snprintf(name, 256, MOUNTPOINT "/%lu.txt", i); + PERF_ADD("pre_rm") + err = rm(name); + PERF_ADD("post_rm") + assert(err_is_ok(err)); + } + PERF_PRINT +} + + +__attribute__((__used__)) +static void measure_mkdir_and_rmdir_single(void) { + MEASUREMENT_PREAMBLE + + char *dir = MOUNTPOINT DIRNAME; + errval_t err; + + // make sure the directory does not exist + rmdir(dir); + + // create and delete a directory many times + PERF_INIT + for(size_t i = 0; i < ITERATIONS; ++i) { + PERF_ADD("pre_mkdir") + err = mkdir(dir); + PERF_ADD("post_mkdir") + assert(err_is_ok(err)); + + PERF_ADD("pre_rmdir") + err = rmdir(dir); + PERF_ADD("post_rmdir") + assert(err_is_ok(err)); + } + PERF_PRINT +} + +char *much_data[THROUGHPUT_MEASUREMENT_BYTES]; + +__attribute__((__used__)) +static void measure_write_throughput(void) { + MEASUREMENT_PREAMBLE + + char *file = MOUNTPOINT FILENAME; + FILE *f; + int res; + + // make sure the file does not yet exist + rm(file); + + PERF_INIT + for (size_t i = 0; i < ITERATIONS; ++i) { + // we want to create a new file and write a lot of data to it + f = fopen(file, "w"); + assert(f != NULL); + + PERF_ADD("pre") + size_t written_bytes = fwrite(much_data, 1, THROUGHPUT_MEASUREMENT_BYTES, f); + PERF_ADD("post") + + assert(written_bytes == THROUGHPUT_MEASUREMENT_BYTES); + res = fclose(f); + assert(res == 0); + } + PERF_PRINT +} + +__attribute__((__used__)) +static void measure_read_throughput(void) { + MEASUREMENT_PREAMBLE + + char *file = MOUNTPOINT FILENAME; + FILE *f; + + // make sure the file exists and contains enough data + f = fopen(file, "w"); + assert(f != NULL); + size_t written_bytes = fwrite(much_data, 1, THROUGHPUT_MEASUREMENT_BYTES, f); + assert(written_bytes == THROUGHPUT_MEASUREMENT_BYTES); + assert(fclose(f) == 0); + + f = fopen(file, "r"); + assert(f != NULL); + PERF_INIT + for (size_t i = 0; i < ITERATIONS; ++i) { + rewind(f); + + PERF_ADD("pre") + size_t read_bytes = fread(much_data, 1, THROUGHPUT_MEASUREMENT_BYTES, f); + PERF_ADD("post") + + assert(read_bytes == THROUGHPUT_MEASUREMENT_BYTES); + } + assert(fclose(f) == 0); + + PERF_PRINT +} + +__attribute__((__used__)) +static void measure_block_driver_ump(void) { + MEASUREMENT_PREAMBLE + errval_t err; + + // measurements are done inside block_driver.c for additional details + for(size_t i = 0; i < ITERATIONS; ++i) { + err = block_driver_read_object(0, 0, 0, NULL); + assert(err_is_ok(err)); + } +} + +__attribute__((__used__)) +static void measure_pagefault_latency(void) { + MEASUREMENT_PREAMBLE + + size_t test_count = 100; + uint8_t *buf = malloc(test_count * PAGE_SIZE); + + for (size_t i = 0; i < test_count; ++i) { + // make the memory mapped + buf[i * PAGE_SIZE] = 1; + } + + debug_printf("=============================\nDONE\n"); +} + +int main(int argc, char *argv[]) +{ + errval_t err; + + barrelfish_usleep(5000000); + + err = filesystem_init(); + assert(err_is_ok(err)); + + // RUN file opening and closing performance + // measure_fopen_fclose(); + + // RUN file creation and deletion performance + // measure_fcreate_and_rm_single(); + + // RUN directory creation and deletion performance + // measure_mkdir_and_rmdir_single(); + + // RUN write throughput + // measure_write_throughput(); + + // RUN read throughput + // measure_read_throughput(); + + // RUN file creation performance as the file system fills up + // measure_fcreate_and_rm_many(); + + // RUN block driver client exercise + measure_block_driver_ump(); + + // RUN page fault latency measurements + // measure_pagefault_latency(); + + return EXIT_SUCCESS; +}