diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index be66fcd9..0aa62818 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -1404,16 +1404,17 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst, #define DO_CHECKPOINT() \ do { \ + wasm_print_checkpoint_latency(); \ SYNC_ALL_TO_FRAME(); \ uint8 *dummy_ip; \ uint32 *dummy_sp; \ dummy_ip = frame_ip; \ dummy_sp = frame_sp; \ - int rc = wasm_dump(exec_env, module, memory, \ + int err = wasm_dump(exec_env, module, memory, \ globals, global_data, global_addr, cur_func, \ frame, dummy_ip, dummy_sp, frame_csp, \ frame_ip_end, else_addr, end_addr, maddr, done_flag); \ - if (rc < 0) { \ + if (err < 0) { \ perror("failed to dump\n"); \ exit(1); \ } \ @@ -1421,8 +1422,48 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst, exit(0); \ } while(0) -#define CHECK_DUMP() \ - if (wasm_get_checkpoint()) { \ + +int get_env_int(const char *env_var, int default_value) { + char *env_val = getenv(env_var); + if (!env_val) { + return default_value; // 環境変数が未設定ならデフォルト値 + } + + char *endptr; + errno = 0; // errno をリセット + long val = strtol(env_val, &endptr, 10); + + // 変換エラー(未変換部分がある or 範囲外) + if (errno == ERANGE || val > INT_MAX || val < INT_MIN || *endptr != '\0') { + return default_value; + } + + return (int)val; +} + +inline int64_t get_nsec (struct timespec *ts) { + return ts->tv_sec * 1e9 + ts->tv_nsec; +} + +static struct timespec dispatch_timestamp[10]; +#define TIMESTAMP() \ +do { \ + clock_gettime(CLOCK_MONOTONIC, &dispatch_timestamp[dispatch_count%10]); \ +} while(0); \ + +#define PRINT_TIMESTAMPS() \ +do { \ + for (int j = 0; j < 10; j++) \ + printf("%ld\n", get_nsec(&dispatch_timestamp[(dispatch_count+j)%10])); \ +} while(0); \ + +static int dispatch_count = 0; +int ckpt_point; +#define CHECK_DUMP() \ + dispatch_count++; \ + TIMESTAMP(); \ + if (wasm_get_checkpoint() || dispatch_count == ckpt_point) { \ + PRINT_TIMESTAMPS(); \ DO_CHECKPOINT(); \ } @@ -1542,6 +1583,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, uint32 local_idx, local_offset, global_idx; uint8 local_type, *global_addr; uint32 cache_index, type_index, param_cell_num, cell_num; + // TODO: option引数から設定できるようにする + ckpt_point = get_env_int("CKPT_POINT", INT32_MAX); #if WASM_ENABLE_EXCE_HANDLING != 0 int32_t exception_tag_index; #endif @@ -1598,13 +1641,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #if BH_PLATFORM_LINUX == 1 // Clear soft-dirty bit - clear_refs(); + // clear_refs(); #endif // リストアの初期化時間の計測(終了) struct timespec ts1; - clock_gettime(CLOCK_MONOTONIC, &ts1); - fprintf(stderr, "boot_end, %lu\n", (uint64_t)(ts1.tv_sec*1e9) + ts1.tv_nsec); + // clock_gettime(CLOCK_MONOTONIC, &ts1); + // fprintf(stderr, "boot_end, %lu\n", (uint64_t)(ts1.tv_sec*1e9) + ts1.tv_nsec); if (get_restore_flag()) { // bool done_flag; @@ -1668,7 +1711,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, goto got_exception; } - HANDLE_OP(WASM_OP_NOP) { HANDLE_OP_END(); } + HANDLE_OP(WASM_OP_NOP) { + HANDLE_OP_END(); + } #if WASM_ENABLE_EXCE_HANDLING != 0 HANDLE_OP(WASM_OP_RETHROW) diff --git a/core/iwasm/migration/wasm_dump.c b/core/iwasm/migration/wasm_dump.c index 8a45cba7..5c1a2185 100644 --- a/core/iwasm/migration/wasm_dump.c +++ b/core/iwasm/migration/wasm_dump.c @@ -38,16 +38,28 @@ int debug_memories(WASMModuleInstance *module) { // bytes_per_page for (int i = 0; i < module->memory_count; i++) { WASMMemoryInstance *memory = (WASMMemoryInstance *)(module->memories[i]); - printf("%d) bytes_per_page: %d\n", i, memory->num_bytes_per_page); - printf("%d) cur_page_count: %d\n", i, memory->cur_page_count); - printf("%d) max_page_count: %d\n", i, memory->max_page_count); - printf("\n"); + print_memory_status(memory); + // printf("%d) bytes_per_page: %d\n", i, memory->num_bytes_per_page); + // printf("%d) cur_page_count: %d\n", i, memory->cur_page_count); + // printf("%d) max_page_count: %d\n", i, memory->max_page_count); + // printf("\n"); } printf("=== debug memories ===\n"); return 0; } +void print_memory_status(WASMMemoryInstance *memory) { + if (!memory) { + fprintf(stderr, "[ERROR] Invalid memory instance\n"); + return; + } + printf("[INFO] bytes_per_page: %d\n", memory->num_bytes_per_page); + printf("[INFO] cur_page_count: %d\n", memory->cur_page_count); + printf("[INFO] max_page_count: %d\n", memory->max_page_count); + printf("\n"); +} + // 積まれてるframe stackを出力する void debug_frame_info(WASMExecEnv* exec_env, WASMInterpFrame *frame) { WASMModuleInstance *module = exec_env->module_inst; @@ -371,21 +383,21 @@ int dump_dirty_memory(WASMMemoryInstance *memory) { } int wasm_dump_memory(WASMMemoryInstance *memory) { - FILE *mem_size_fp = open_image("mem_page_count.img", "wb"); - - dump_dirty_memory(memory); - + // print memroy info for debugging + // print_memory_status(memory); + FILE *mem_size_fp = open_image("mem_page_count.img", "wb"); printf("page_count: %d\n", memory->cur_page_count); fwrite(&(memory->cur_page_count), sizeof(uint32), 1, mem_size_fp); - fclose(mem_size_fp); + // dump_dirty_memory(memory); + // デバッグのために、すべてのメモリも保存 - // FILE *all_memory_fp = open_image("all_memory.img", "wb"); - // fwrite(memory->memory_data, sizeof(uint8), - // memory->num_bytes_per_page * memory->cur_page_count, all_memory_fp); - // fclose(all_memory_fp); + FILE *all_memory_fp = open_image("all_memory.img", "wb"); + fwrite(memory->memory_data, sizeof(uint8), + memory->num_bytes_per_page * memory->cur_page_count, all_memory_fp); + fclose(all_memory_fp); return 0; } @@ -516,12 +528,20 @@ static bool sig_flag = false; // wasm_set_checkpoint(true); // } +struct timespec ckpt_request_time, ckpt_exec_time; +inline +void wasm_print_checkpoint_latency() { + clock_gettime(CLOCK_MONOTONIC, &ckpt_exec_time); + fprintf(stderr, "checkpoint latency: %lu [ns]\n", get_time(ckpt_request_time, ckpt_exec_time)); +} + inline void wasm_set_checkpoint(bool f) { + clock_gettime(CLOCK_MONOTONIC, &ckpt_request_time); sig_flag = f; } inline bool wasm_get_checkpoint() { return sig_flag; -} \ No newline at end of file +} diff --git a/core/iwasm/migration/wasm_dump.h b/core/iwasm/migration/wasm_dump.h index 3265fbc9..582015e4 100644 --- a/core/iwasm/migration/wasm_dump.h +++ b/core/iwasm/migration/wasm_dump.h @@ -5,6 +5,7 @@ #include "../interpreter/wasm_interp.h" void wasm_set_checkpoint(bool f); +void wasm_print_checkpoint_latency(); bool wasm_get_checkpoint(); int wasm_dump(WASMExecEnv *exec_env, diff --git a/core/iwasm/migration/wasm_restore.c b/core/iwasm/migration/wasm_restore.c index e31873a4..b6245d68 100644 --- a/core/iwasm/migration/wasm_restore.c +++ b/core/iwasm/migration/wasm_restore.c @@ -197,7 +197,6 @@ void restore_dirty_memory(WASMMemoryInstance **memory, FILE* memory_fp) { } int wasm_restore_memory(WASMModuleInstance *module, WASMMemoryInstance **memory, uint8** maddr) { - FILE* memory_fp = open_image("memory.img", "rb"); FILE* mem_size_fp = open_image("mem_page_count.img", "rb"); // restore page_count @@ -205,14 +204,16 @@ int wasm_restore_memory(WASMModuleInstance *module, WASMMemoryInstance **memory, fread(&page_count, sizeof(uint32), 1, mem_size_fp); wasm_enlarge_memory(module, page_count- (*memory)->cur_page_count); *maddr = page_count * (*memory)->num_bytes_per_page; + fclose(mem_size_fp); + + // FILE* memory_fp = open_image("memory.img", "rb"); + // restore_dirty_memory(memory, memory_fp); - restore_dirty_memory(memory, memory_fp); - // restore memory_data - // fread((*memory)->memory_data, sizeof(uint8), - // (*memory)->num_bytes_per_page * (*memory)->cur_page_count, memory_fp); + FILE* memory_fp = open_image("all_memory.img", "rb"); + fread((*memory)->memory_data, sizeof(uint8), + (*memory)->num_bytes_per_page * (*memory)->cur_page_count, memory_fp); fclose(memory_fp); - fclose(mem_size_fp); return 0; }