From 1a734c05809a47a62e39b3029d98452cb994ac01 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sat, 18 Jun 2022 21:49:00 +0300 Subject: [PATCH 43/43] Name timers See osdn #44860 Signed-off-by: Marko Lindqvist --- ai/default/aihand.c | 4 +-- client/agents/agents.c | 3 ++- client/agents/cma_core.c | 3 ++- client/client_main.c | 6 +++-- client/control.c | 6 +++-- client/mapview_common.c | 31 ++++++++++++--------- common/aicore/cm.c | 6 +++-- common/mapimg.c | 6 ++--- common/networking/connection.c | 3 ++- server/advisors/autosettlers.c | 3 ++- server/civserver.c | 3 ++- server/meta.c | 4 +-- server/savegame/savegame3.c | 2 +- server/savegame/savemain.c | 8 +++--- server/sernet.c | 15 +++++++---- server/settings.c | 4 ++- server/srv_log.c | 8 ++++-- server/srv_main.c | 13 ++++++--- server/stdinhand.c | 4 +-- utility/timing.c | 49 ++++++++++++++++++++++++++++++---- utility/timing.h | 5 ++-- 21 files changed, 129 insertions(+), 57 deletions(-) diff --git a/ai/default/aihand.c b/ai/default/aihand.c index a6abecf7df..e4401afae2 100644 --- a/ai/default/aihand.c +++ b/ai/default/aihand.c @@ -248,9 +248,9 @@ static void dai_manage_taxes(struct ai_type *ait, struct player *pplayer) } #ifdef DEBUG_TIMERS - taxtimer = timer_new(TIMER_CPU, TIMER_DEBUG); + taxtimer = timer_new(TIMER_CPU, TIMER_DEBUG, "AI tax"); timer_start(taxtimer); -#endif +#endif /* DEBUG_TIMERS */ /* City parameters needed for celebrations. */ cm_init_parameter(&cmp); diff --git a/client/agents/agents.c b/client/agents/agents.c index ff2294a5dc..19d9f4c941 100644 --- a/client/agents/agents.c +++ b/client/agents/agents.c @@ -387,7 +387,8 @@ void register_agent(const struct agent *agent) priv_agent->first_outstanding_request_id = 0; priv_agent->last_outstanding_request_id = 0; - priv_agent->stats.network_wall_timer = timer_new(TIMER_USER, TIMER_ACTIVE); + priv_agent->stats.network_wall_timer = timer_new(TIMER_USER, TIMER_ACTIVE, + "agent: network"); priv_agent->stats.wait_at_network = 0; priv_agent->stats.wait_at_network_requests = 0; diff --git a/client/agents/cma_core.c b/client/agents/cma_core.c index 1b20b5e6b5..0f7fa4872d 100644 --- a/client/agents/cma_core.c +++ b/client/agents/cma_core.c @@ -489,7 +489,8 @@ void cma_init(void) /* We used to just use timer_new here, but apparently cma_init can be * called multiple times per client invocation so that lead to memory * leaks. */ - stats.wall_timer = timer_renew(timer, TIMER_USER, TIMER_ACTIVE); + stats.wall_timer = timer_renew(timer, TIMER_USER, TIMER_ACTIVE, + timer != NULL ? NULL : "agent: stats"); memset(&self, 0, sizeof(self)); strcpy(self.name, "CMA"); diff --git a/client/client_main.c b/client/client_main.c index 118c18b1bf..3a03af5271 100644 --- a/client/client_main.c +++ b/client/client_main.c @@ -1081,7 +1081,8 @@ void set_seconds_to_turndone(double seconds) { if (current_turn_timeout() > 0) { seconds_to_turndone = seconds; - turndone_timer = timer_renew(turndone_timer, TIMER_USER, TIMER_ACTIVE); + turndone_timer = timer_renew(turndone_timer, TIMER_USER, TIMER_ACTIVE, + turndone_timer != NULL ? NULL : "turndone"); timer_start(turndone_timer); /* Maybe we should do an update_timeout_label here, but it doesn't @@ -1104,7 +1105,8 @@ bool is_waiting_turn_change(void) void start_turn_change_wait(void) { seconds_shown_to_new_turn = ceil(game.tinfo.last_turn_change_time) + 0.1; - between_turns = timer_renew(between_turns, TIMER_USER, TIMER_ACTIVE); + between_turns = timer_renew(between_turns, TIMER_USER, TIMER_ACTIVE, + between_turns != NULL ? NULL : "between turns"); timer_start(between_turns); waiting_turn_change = TRUE; diff --git a/client/control.c b/client/control.c index ea30ea7d14..f53c0f1151 100644 --- a/client/control.c +++ b/client/control.c @@ -882,7 +882,8 @@ double blink_active_unit(void) /* If we lag, we don't try to catch up. Instead we just start a * new blink_time on every update. */ - blink_timer = timer_renew(blink_timer, TIMER_USER, TIMER_ACTIVE); + blink_timer = timer_renew(blink_timer, TIMER_USER, TIMER_ACTIVE, + blink_timer != NULL ? NULL : "blink"); timer_start(blink_timer); unit_list_iterate(get_units_in_focus(), punit) { @@ -938,7 +939,8 @@ double blink_turn_done_button(void) if (is_moving == 1 && is_waiting > 0) { update_turn_done_button(FALSE); /* stress the slow player! */ } - blink_timer = timer_renew(blink_timer, TIMER_USER, TIMER_ACTIVE); + blink_timer = timer_renew(blink_timer, TIMER_USER, TIMER_ACTIVE, + blink_timer != NULL ? NULL : "blink"); timer_start(blink_timer); } return blink_time - timer_read_seconds(blink_timer); diff --git a/client/mapview_common.c b/client/mapview_common.c index d317764f8c..b1c7477ea4 100644 --- a/client/mapview_common.c +++ b/client/mapview_common.c @@ -102,9 +102,10 @@ enum tile_update_type { TILE_UPDATE_TILE_LABEL, TILE_UPDATE_COUNT }; + static void queue_mapview_update(enum update_type update); static void queue_mapview_tile_update(struct tile *ptile, - enum tile_update_type type); + enum tile_update_type type); /* Helper struct for drawing trade routes. */ struct trade_route_line { @@ -181,14 +182,23 @@ void animations_free(void) } } +/************************************************************************//** + Start or renew animation timer. +****************************************************************************/ +static void anim_timer_renew(void) +{ + anim_timer = timer_renew(anim_timer, TIMER_USER, TIMER_ACTIVE, + anim_timer != NULL ? NULL : "anim"); + timer_start(anim_timer); +} + /************************************************************************//** Add new animation to the queue ****************************************************************************/ static void animation_add(struct animation *anim) { if (animation_list_size(animations) == 0) { - anim_timer = timer_renew(anim_timer, TIMER_USER, TIMER_ACTIVE); - timer_start(anim_timer); + anim_timer_renew(); } anim->finished = FALSE; @@ -410,8 +420,7 @@ void update_animation(void) if (animation_list_size(animations) > 0) { /* Start next */ - anim_timer = timer_renew(anim_timer, TIMER_USER, TIMER_ACTIVE); - timer_start(anim_timer); + anim_timer_renew(); } } else { double time_gone = timer_read_seconds(anim_timer); @@ -989,8 +998,7 @@ void set_mapview_origin(float gui_x0, float gui_y0) gui_distance_vector(tileset, &diff_x, &diff_y, start_x, start_y, gui_x0, gui_y0); - anim_timer = timer_renew(anim_timer, TIMER_USER, TIMER_ACTIVE); - timer_start(anim_timer); + anim_timer_renew(); unqueue_mapview_updates(TRUE); @@ -2563,8 +2571,7 @@ void decrease_unit_hp_smooth(struct unit *punit0, int hp0, while (punit0->hp > hp0 || punit1->hp > hp1) { const int diff0 = punit0->hp - hp0, diff1 = punit1->hp - hp1; - anim_timer = timer_renew(anim_timer, TIMER_USER, TIMER_ACTIVE); - timer_start(anim_timer); + anim_timer_renew(); if (fc_rand(diff0 + diff1) < diff0) { punit0->hp--; @@ -2596,8 +2603,7 @@ void decrease_unit_hp_smooth(struct unit *punit0, int hp0, struct sprite *sprite = *sprite_vector_get(anim, i); get_sprite_dimensions(sprite, &w, &h); - anim_timer = timer_renew(anim_timer, TIMER_USER, TIMER_ACTIVE); - timer_start(anim_timer); + anim_timer_renew(); /* We first draw the explosion onto the unit and draw draw the * complete thing onto the map canvas window. This avoids @@ -2696,8 +2702,7 @@ void move_unit_map_canvas(struct unit *punit, } else { /* Start the timer (AFTER the unqueue above). */ - anim_timer = timer_renew(anim_timer, TIMER_USER, TIMER_ACTIVE); - timer_start(anim_timer); + anim_timer_renew(); do { int new_x, new_y; diff --git a/common/aicore/cm.c b/common/aicore/cm.c index 7711a3995c..ea37a1f816 100644 --- a/common/aicore/cm.c +++ b/common/aicore/cm.c @@ -296,10 +296,12 @@ void cm_init(void) #ifdef GATHER_TIME_STATS memset(&performance, 0, sizeof(performance)); - performance.greedy.wall_timer = timer_new(TIMER_USER, TIMER_ACTIVE); + performance.greedy.wall_timer = timer_new(TIMER_USER, TIMER_ACTIVE, + "cm.greedy"); performance.greedy.name = "greedy"; - performance.opt.wall_timer = timer_new(TIMER_USER, TIMER_ACTIVE); + performance.opt.wall_timer = timer_new(TIMER_USER, TIMER_ACTIVE, + "cm.opt"); performance.opt.name = "opt"; #endif /* GATHER_TIME_STATS */ } diff --git a/common/mapimg.c b/common/mapimg.c index 2740cfba36..6c615638e3 100644 --- a/common/mapimg.c +++ b/common/mapimg.c @@ -1358,13 +1358,13 @@ bool mapimg_create(struct mapdef *pmapdef, bool force, const char *savename, } #ifdef FREECIV_DEBUG - timer_cpu = timer_new(TIMER_CPU, TIMER_ACTIVE); + timer_cpu = timer_new(TIMER_CPU, TIMER_ACTIVE, "mapimg cpu"); timer_start(timer_cpu); - timer_user = timer_new(TIMER_USER, TIMER_ACTIVE); + timer_user = timer_new(TIMER_USER, TIMER_ACTIVE, "mapimg user"); timer_start(timer_user); #endif /* FREECIV_DEBUG */ - /* create map */ + /* Create map */ switch (pmapdef->player.show) { case SHOW_PLRNAME: /* display player given by name */ case SHOW_PLRID: /* display player given by id */ diff --git a/common/networking/connection.c b/common/networking/connection.c index 1b8b7f049a..c13f206d15 100644 --- a/common/networking/connection.c +++ b/common/networking/connection.c @@ -216,7 +216,8 @@ static int write_socket_data(struct connection *pc, if (start > 0) { buf->ndata -= start; memmove(buf->data, buf->data+start, buf->ndata); - pc->last_write = timer_renew(pc->last_write, TIMER_USER, TIMER_ACTIVE); + pc->last_write = timer_renew(pc->last_write, TIMER_USER, TIMER_ACTIVE, + pc->last_write != NULL ? NULL : "socket write"); timer_start(pc->last_write); } diff --git a/server/advisors/autosettlers.c b/server/advisors/autosettlers.c index b0eca1ce0c..82b3358eed 100644 --- a/server/advisors/autosettlers.c +++ b/server/advisors/autosettlers.c @@ -1148,7 +1148,8 @@ void auto_settlers_player(struct player *pplayer) state = fc_calloc(MAP_INDEX_SIZE, sizeof(*state)); - as_timer = timer_renew(as_timer, TIMER_CPU, TIMER_DEBUG); + as_timer = timer_renew(as_timer, TIMER_CPU, TIMER_DEBUG, + as_timer != NULL ? NULL : "autosettlers"); timer_start(as_timer); if (is_ai(pplayer)) { diff --git a/server/civserver.c b/server/civserver.c index 7a6679bd42..30b0d19e34 100644 --- a/server/civserver.c +++ b/server/civserver.c @@ -97,7 +97,8 @@ static void signal_handler(int sig) "within one second to make it exit.")); } } - timer = timer_renew(timer, TIMER_USER, TIMER_ACTIVE); + timer = timer_renew(timer, TIMER_USER, TIMER_ACTIVE, + timer != NULL ? NULL : "ctrlc"); timer_start(timer); break; diff --git a/server/meta.c b/server/meta.c index 603bb22dbe..fc1935af5f 100644 --- a/server/meta.c +++ b/server/meta.c @@ -531,9 +531,9 @@ bool send_server_info_to_metaserver(enum meta_flag flag) return FALSE; } - /* start a new timer if we haven't already */ + /* Start a new timer if we haven't already */ if (!last_send_timer) { - last_send_timer = timer_new(TIMER_USER, TIMER_ACTIVE); + last_send_timer = timer_new(TIMER_USER, TIMER_ACTIVE, "meta"); } timer_clear(last_send_timer); diff --git a/server/savegame/savegame3.c b/server/savegame/savegame3.c index e8b4a6cd51..9fe2319600 100644 --- a/server/savegame/savegame3.c +++ b/server/savegame/savegame3.c @@ -423,7 +423,7 @@ void savegame3_save(struct section_file *sfile, const char *save_reason, fc_assert_ret(sfile != NULL); #ifdef DEBUG_TIMERS - struct timer *savetimer = timer_new(TIMER_CPU, TIMER_DEBUG); + struct timer *savetimer = timer_new(TIMER_CPU, TIMER_DEBUG, "save"); timer_start(savetimer); #endif diff --git a/server/savegame/savemain.c b/server/savegame/savemain.c index aef9f8a224..8eda2ed9b6 100644 --- a/server/savegame/savemain.c +++ b/server/savegame/savemain.c @@ -47,9 +47,9 @@ void savegame_load(struct section_file *sfile) fc_assert_ret(sfile != NULL); #ifdef DEBUG_TIMERS - struct timer *loadtimer = timer_new(TIMER_CPU, TIMER_DEBUG); + struct timer *loadtimer = timer_new(TIMER_CPU, TIMER_DEBUG, "load"); timer_start(loadtimer); -#endif +#endif /* DEBUG_TIMERS */ savefile_options = secfile_lookup_str(sfile, "savefile.options"); @@ -189,9 +189,9 @@ void save_game(const char *orig_filename, const char *save_reason, sizeof(stdata->filepath) + stdata->filepath - filename, "manual"); } - timer_cpu = timer_new(TIMER_CPU, TIMER_ACTIVE); + timer_cpu = timer_new(TIMER_CPU, TIMER_ACTIVE, "save cpu"); + timer_user = timer_new(TIMER_USER, TIMER_ACTIVE, "save user"); timer_start(timer_cpu); - timer_user = timer_new(TIMER_USER, TIMER_ACTIVE); timer_start(timer_user); /* Allowing duplicates shouldn't be allowed. However, it takes very too diff --git a/server/sernet.c b/server/sernet.c index 33c294d81b..a344a7a856 100644 --- a/server/sernet.c +++ b/server/sernet.c @@ -448,7 +448,8 @@ static void incoming_client_packets(struct connection *pconn) #if PROCESSING_TIME_STATISTICS int request_id; - request_time = timer_renew(request_time, TIMER_USER, TIMER_ACTIVE); + request_time = timer_renew(request_time, TIMER_USER, TIMER_ACTIVE, + request_time != NULL ? NULL : "request"); timer_start(request_time); #endif /* PROCESSING_TIME_STATISTICS */ @@ -719,7 +720,9 @@ enum server_events server_sniff_all_input(void) >= game.server.save_frequency * 60)) { save_game_auto("Timer", AS_TIMER); game.server.save_timer = timer_renew(game.server.save_timer, - TIMER_USER, TIMER_ACTIVE); + TIMER_USER, TIMER_ACTIVE, + game.server.save_timer != NULL + ? NULL : "save interval"); timer_start(game.server.save_timer); } @@ -910,7 +913,9 @@ enum server_events server_sniff_all_input(void) >= game.server.save_frequency * 60)) { save_game_auto("Timer", AS_TIMER); game.server.save_timer = timer_renew(game.server.save_timer, - TIMER_USER, TIMER_ACTIVE); + TIMER_USER, TIMER_ACTIVE, + game.server.save_timer != NULL + ? NULL : "save interval"); timer_start(game.server.save_timer); } @@ -1081,7 +1086,7 @@ int server_make_connection(int new_sock, const char *client_addr, /* Give a ping timeout to send the PACKET_SERVER_JOIN_REQ, or close * the mute connection. This timer will be canceled into * connecthand.c:handle_login_request(). */ - timer = timer_new(TIMER_USER, TIMER_ACTIVE); + timer = timer_new(TIMER_USER, TIMER_ACTIVE, "ping timer"); timer_start(timer); timer_list_append(pconn->server.ping_timers, timer); @@ -1394,7 +1399,7 @@ static void finish_processing_request(struct connection *pconn) *****************************************************************************/ static void connection_ping(struct connection *pconn) { - struct timer *timer = timer_new(TIMER_USER, TIMER_ACTIVE); + struct timer *timer = timer_new(TIMER_USER, TIMER_ACTIVE, "connection ping"); log_debug("sending ping to %s (open=%d)", conn_description(pconn), timer_list_size(pconn->server.ping_timers)); diff --git a/server/settings.c b/server/settings.c index 77792f2261..3607b43d72 100644 --- a/server/settings.c +++ b/server/settings.c @@ -942,7 +942,9 @@ static bool autosaves_callback(unsigned value, struct connection *caller, if ((value & (1 << AS_TIMER)) && !(game.server.autosaves & (1 << AS_TIMER))) { game.server.save_timer = timer_renew(game.server.save_timer, - TIMER_USER, TIMER_ACTIVE); + TIMER_USER, TIMER_ACTIVE, + game.server.save_timer != NULL + ? NULL : "save interval"); timer_start(game.server.save_timer); } else if (!(value & (1 << AS_TIMER)) && (game.server.autosaves & (1 << AS_TIMER))) { diff --git a/server/srv_log.c b/server/srv_log.c index 38a07e622c..2f81d64236 100644 --- a/server/srv_log.c +++ b/server/srv_log.c @@ -219,8 +219,12 @@ void timing_log_init(void) int i; for (i = 0; i < AIT_LAST; i++) { - aitimer[i][0] = timer_new(TIMER_CPU, TIMER_ACTIVE); - aitimer[i][1] = timer_new(TIMER_CPU, TIMER_ACTIVE); + char buf[60]; + + fc_snprintf(buf, sizeof(buf), "AI type %d turn", i); + aitimer[i][0] = timer_new(TIMER_CPU, TIMER_ACTIVE, buf); + fc_snprintf(buf, sizeof(buf), "AI type %d game", i); + aitimer[i][1] = timer_new(TIMER_CPU, TIMER_ACTIVE, buf); recursion[i] = 0; } } diff --git a/server/srv_main.c b/server/srv_main.c index f79caf65e5..11b217bcd5 100644 --- a/server/srv_main.c +++ b/server/srv_main.c @@ -1326,7 +1326,9 @@ static void begin_phase(bool is_new_phase) game.tinfo.last_turn_change_time = (float)game.server.turn_change_time; game.tinfo.seconds_to_phasedone = (double)current_turn_timeout(); game.server.phase_timer = timer_renew(game.server.phase_timer, - TIMER_USER, TIMER_ACTIVE); + TIMER_USER, TIMER_ACTIVE, + game.server.phase_timer != NULL + ? NULL : "phase"); timer_start(game.server.phase_timer); send_game_info(NULL); @@ -2793,7 +2795,9 @@ static void srv_running(void) if (game.server.autosaves & (1 << AS_TIMER)) { game.server.save_timer = timer_renew(game.server.save_timer, - TIMER_USER, TIMER_ACTIVE); + TIMER_USER, TIMER_ACTIVE, + game.server.save_timer != NULL + ? NULL : "save interval"); timer_start(game.server.save_timer); } @@ -2892,7 +2896,8 @@ static void srv_running(void) /* nothing */ } - between_turns = timer_renew(between_turns, TIMER_USER, TIMER_ACTIVE); + between_turns = timer_renew(between_turns, TIMER_USER, TIMER_ACTIVE, + between_turns != NULL ? NULL : "between turns"); timer_start(between_turns); /* After sniff, re-zero the timer: (read-out above on next loop) */ @@ -3051,7 +3056,7 @@ static void srv_prepare(void) } } - eot_timer = timer_new(TIMER_CPU, TIMER_ACTIVE); + eot_timer = timer_new(TIMER_CPU, TIMER_ACTIVE, "end-of-turn"); } /**********************************************************************//** diff --git a/server/stdinhand.c b/server/stdinhand.c index f830c9c487..34cfd65aa0 100644 --- a/server/stdinhand.c +++ b/server/stdinhand.c @@ -3826,9 +3826,9 @@ bool load_command(struct connection *caller, const char *filename, bool check, * or to initialize new value itself. */ server_game_init(TRUE); - loadtimer = timer_new(TIMER_CPU, TIMER_ACTIVE); + loadtimer = timer_new(TIMER_CPU, TIMER_ACTIVE, "load cpu"); timer_start(loadtimer); - uloadtimer = timer_new(TIMER_USER, TIMER_ACTIVE); + uloadtimer = timer_new(TIMER_USER, TIMER_ACTIVE, "load user"); timer_start(uloadtimer); sz_strlcpy(srvarg.load_filename, arg); diff --git a/utility/timing.c b/utility/timing.c index fc7792af46..7975b4c216 100644 --- a/utility/timing.c +++ b/utility/timing.c @@ -84,6 +84,10 @@ struct timer { enum timer_use use; enum timer_state state; +#ifdef FREECIV_DEBUG + char *name; +#endif + /* this is accumulated time for previous timings: */ double sec; long usec; /* not always used, in which case zero, @@ -153,9 +157,10 @@ static void report_time_failed(struct timer *t) Allocate a new timer with specified "type" and "use". The timer is created as cleared, and stopped. ***********************************************************************/ -struct timer *timer_new(enum timer_timetype type, enum timer_use use) +struct timer *timer_new(enum timer_timetype type, enum timer_use use, + const char *name) { - return timer_renew(NULL, type, use); + return timer_renew(NULL, type, use, name); } /*******************************************************************//** @@ -173,14 +178,25 @@ struct timer *timer_new(enum timer_timetype type, enum timer_use use) } ***********************************************************************/ struct timer *timer_renew(struct timer *t, enum timer_timetype type, - enum timer_use use) + enum timer_use use, const char *name) { if (t == NULL) { t = (struct timer *)fc_malloc(sizeof(struct timer)); +#ifdef FREECIV_DEBUG + t->name = NULL; +#endif } t->type = type; t->use = use; +#ifdef FREECIV_DEBUG + if (name != NULL) { + if (t->name != NULL) { + free(t->name); + } + t->name = fc_strdup(name); + } +#endif timer_clear(t); return t; @@ -192,10 +208,33 @@ struct timer *timer_renew(struct timer *t, enum timer_timetype type, void timer_destroy(struct timer *t) { if (t != NULL) { + +#ifdef FREECIV_DEBUG + if (t->name != NULL) { + free(t->name); + } +#endif /* FREECIV_DEBUG */ + free(t); } } +/*******************************************************************//** + Return name of the timer, or some placeholder string (never NULL) +***********************************************************************/ +static char *timer_name(struct timer *t) +{ +#ifdef FREECIV_DEBUG + if (t->name != NULL) { + return t->name; + } else { + return "Nameless"; + } +#endif /* FREECIV_DEBUG */ + + return "-"; +} + /*******************************************************************//** Return whether timer is in use. t may be NULL, in which case returns 0 @@ -230,7 +269,7 @@ void timer_start(struct timer *t) return; } if (t->state == TIMER_STARTED) { - log_error("tried to start already started timer"); + log_error("Tried to start already started timer: %s", timer_name(t)); return; } if (t->type == TIMER_CPU) { @@ -274,7 +313,7 @@ void timer_stop(struct timer *t) return; } if (t->state == TIMER_STOPPED) { - log_error("tried to stop already stopped timer"); + log_error("Tried to stop already stopped timer: %s", timer_name(t)); return; } if (t->type == TIMER_CPU) { diff --git a/utility/timing.h b/utility/timing.h index 60f4b151ff..80de9f0fdd 100644 --- a/utility/timing.h +++ b/utility/timing.h @@ -71,9 +71,10 @@ struct timer; /* opaque type; see comments in timing.c */ #define timer_list_iterate_end LIST_ITERATE_END -struct timer *timer_new(enum timer_timetype type, enum timer_use use); +struct timer *timer_new(enum timer_timetype type, enum timer_use use, + const char *name); struct timer *timer_renew(struct timer *t, enum timer_timetype type, - enum timer_use use); + enum timer_use use, const char *name); void timer_destroy(struct timer *t); bool timer_in_use(struct timer *t); -- 2.35.1