void profile_quit() { int bucknum; function_t *func; char linebuf[512]; frefid_t profref; strid_t profstr; while (current_frame) { profile_out(); } profref = glk_fileref_create_by_name(fileusage_BinaryMode|fileusage_Data, "profile-raw", 0); if (!profref) fatal_error("Profiler: unable to create profile-raw file"); profstr = glk_stream_open_file(profref, filemode_Write, 0); glk_put_string_stream(profstr, "<profile>\n"); for (bucknum=0; bucknum<FUNC_HASH_SIZE; bucknum++) { char total_buf[20], self_buf[20]; for (func = functions[bucknum]; func; func=func->hash_next) { /* ### sprintf(linebuf, "function %lx called %ld times, total ops %ld, total time %s, self ops %ld, self time %s\n", func->addr, func->call_count, func->total_ops, timeprint(&func->total_time, total_buf), func->self_ops, timeprint(&func->self_time, self_buf)); ### */ sprintf(linebuf, " <function addr=\"%lx\" call_count=\"%ld\" accel_count=\"%ld\" total_ops=\"%ld\" total_time=\"%s\" self_ops=\"%ld\" self_time=\"%s\" />\n", func->addr, func->call_count, func->accel_count, func->total_ops, timeprint(&func->total_time, total_buf), func->self_ops, timeprint(&func->self_time, self_buf)); glk_put_string_stream(profstr, linebuf); } } glk_put_string_stream(profstr, "</profile>\n"); glk_stream_close(profstr, NULL); glulx_free(functions); functions = NULL; }
void profile_quit() { int bucknum; function_t *func; char linebuf[512]; strid_t profstr; if (!profiling_active) return; while (current_frame) { profile_out(0); } if (profiling_stream) { profstr = profiling_stream; } else if (profiling_filename) { frefid_t profref = glk_fileref_create_by_name(fileusage_BinaryMode|fileusage_Data, profiling_filename, 0); if (!profref) fatal_error_2("Profiler: unable to create profile output fileref", profiling_filename); profstr = glk_stream_open_file(profref, filemode_Write, 0); } else { fatal_error("Profiler: no profile output handle!"); } glk_put_string_stream(profstr, "<profile>\n"); for (bucknum=0; bucknum<FUNC_HASH_SIZE; bucknum++) { char total_buf[20], self_buf[20]; callcount_t *cc; for (func = functions[bucknum]; func; func=func->hash_next) { /* ### sprintf(linebuf, "function %lx called %ld times, total ops %ld, total time %s, self ops %ld, self time %s\n", func->addr, func->call_count, func->total_ops, timeprint(&func->total_time, total_buf), func->self_ops, timeprint(&func->self_time, self_buf)); ### */ sprintf(linebuf, " <function addr=\"%lx\" call_count=\"%ld\" accel_count=\"%ld\" total_ops=\"%ld\" total_time=\"%s\" self_ops=\"%ld\" self_time=\"%s\" max_depth=\"%ld\" max_stack_use=\"%ld\" />\n", (unsigned long)func->addr, (long)func->call_count, (long)func->accel_count, (long)func->total_ops, timeprint(&func->total_time, total_buf), (long)func->self_ops, timeprint(&func->self_time, self_buf), (long)func->max_depth, (long)func->max_stack_use); glk_put_string_stream(profstr, linebuf); for (cc = func->outcalls; cc; cc = cc->next) { sprintf(linebuf, " <calls fromaddr=\"%lx\" toaddr=\"%lx\" count=\"%ld\" />\n", (unsigned long)func->addr, (unsigned long)cc->toaddr, (long)cc->count); glk_put_string_stream(profstr, linebuf); } } } glk_put_string_stream(profstr, "</profile>\n"); glk_stream_close(profstr, NULL); /* ### Ought to free the function structures, not just the hash array. */ glulx_free(functions); functions = NULL; }