1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
13 * Szabo, Janos Zoltan – initial implementation
15 ******************************************************************************/
20 #include "Snapshot.hh"
22 TIMER
*TIMER::list_head
= NULL
, *TIMER::list_tail
= NULL
,
23 *TIMER::backup_head
= NULL
, *TIMER::backup_tail
= NULL
;
24 boolean
TIMER::control_timers_saved
= FALSE
;
26 void TIMER::add_to_list()
28 // do nothing if already a member of list
29 if (this == list_head
|| list_prev
!= NULL
) return;
30 if (list_head
== NULL
) list_head
= this;
31 else if (list_tail
!= NULL
) list_tail
->list_next
= this;
32 list_prev
= list_tail
;
37 void TIMER::remove_from_list()
39 if (list_prev
!= NULL
) list_prev
->list_next
= list_next
;
40 else if (list_head
== this) list_head
= list_next
;
41 if (list_next
!= NULL
) list_next
->list_prev
= list_prev
;
42 else if (list_tail
== this) list_tail
= list_prev
;
47 TIMER::TIMER(const char *par_timer_name
)
49 timer_name
= par_timer_name
!= NULL
? par_timer_name
: "<unknown>";
56 TIMER::TIMER(const char *par_timer_name
, double def_val
)
58 if (par_timer_name
== NULL
)
59 TTCN_error("Internal error: Creating a timer with an invalid name.");
60 timer_name
= par_timer_name
;
61 set_default_duration(def_val
);
67 TIMER::TIMER(const char *par_timer_name
, const FLOAT
& def_val
)
69 if (par_timer_name
== NULL
)
70 TTCN_error("Internal error: Creating a timer with an invalid name.");
71 timer_name
= par_timer_name
;
72 def_val
.must_bound("Initializing a timer duration with an unbound "
74 set_default_duration(def_val
.float_value
);
82 if (is_started
) remove_from_list();
85 void TIMER::set_name(const char * name
)
87 if (name
== NULL
) TTCN_error("Internal error: Setting an "
88 "invalid name for a single element of a timer array.");
92 void TIMER::set_default_duration(double def_val
)
95 TTCN_error("Setting the default duration of timer %s "
96 "to a negative float value (%g).", timer_name
, def_val
);
97 } else if (FLOAT::is_special(def_val
)) {
98 TTCN_error("Setting the default duration of timer %s "
99 "to a non-numeric float value (%g).", timer_name
, def_val
);
102 default_val
= def_val
;
105 void TIMER::set_default_duration(const FLOAT
& def_val
)
107 if (!def_val
.is_bound()) TTCN_error("Setting the default duration of "
108 "timer %s to an unbound float value.", timer_name
);
109 set_default_duration(def_val
.float_value
);
115 TTCN_error("Timer %s does not have default duration. "
116 "It can only be started with a given duration.", timer_name
);
120 void TIMER::start(double start_val
)
122 if (this != &testcase_timer
) {
124 TTCN_error("Starting timer %s with a negative duration (%g).",
125 timer_name
, start_val
);
127 TTCN_warning("Re-starting timer %s, which is already active (running "
128 "or expired).", timer_name
);
133 TTCN_Logger::log_timer_start(timer_name
, start_val
);
137 TTCN_error("Using a negative duration (%g) for the guard timer of the "
138 "test case.", start_val
);
140 TTCN_Logger::log_timer_guard(start_val
);
142 t_started
= TTCN_Snapshot::time_now();
143 t_expires
= t_started
+ start_val
;
146 void TIMER::start(const FLOAT
& start_val
)
148 if (!start_val
.is_bound())
149 TTCN_error("Starting timer %s with an unbound float value as duration.",
151 start(start_val
.float_value
);
156 if (this != &testcase_timer
) {
159 TTCN_Logger::log_timer_stop(timer_name
, t_expires
- t_started
);
161 } else TTCN_warning("Stopping inactive timer %s.", timer_name
);
162 } else is_started
= FALSE
;
165 double TIMER::read() const
167 // the time is not frozen (i.e. time_now() is used)
170 double current_time
= TTCN_Snapshot::time_now();
171 if (current_time
>= t_expires
) ret_val
= 0.0;
172 else ret_val
= current_time
- t_started
;
176 TTCN_Logger::log_timer_read(timer_name
, ret_val
);
180 boolean
TIMER::running() const
182 // the time is not frozen (i.e. time_now() is used)
183 return is_started
&& TTCN_Snapshot::time_now() < t_expires
;
186 alt_status
TIMER::timeout()
188 // the time is frozen (i.e. get_alt_begin() is used)
190 if (TTCN_Snapshot::get_alt_begin() < t_expires
) return ALT_MAYBE
;
192 if (this != &testcase_timer
) {
193 TTCN_Logger::log_timer_timeout(timer_name
, t_expires
- t_started
);
198 if (this != &testcase_timer
) {
199 TTCN_Logger::log_matching_timeout(timer_name
);
205 void TIMER::log() const
207 // the time is not frozen (i.e. time_now() is used)
208 TTCN_Logger::log_event("timer: { name: %s, default duration: ", timer_name
);
209 if (has_default
) TTCN_Logger::log_event("%g s", default_val
);
210 else TTCN_Logger::log_event_str("none");
211 TTCN_Logger::log_event_str(", state: ");
213 double current_time
= TTCN_Snapshot::time_now();
214 if (current_time
< t_expires
) TTCN_Logger::log_event_str("running");
215 else TTCN_Logger::log_event_str("expired");
216 TTCN_Logger::log_event(", actual duration: %g s, "
217 "elapsed time: %g s", t_expires
- t_started
,
218 current_time
- t_started
);
219 } else TTCN_Logger::log_event_str("inactive");
220 TTCN_Logger::log_event_str(" }");
223 void TIMER::all_stop()
225 while (list_head
!= NULL
) list_head
->stop(); // also removes from list
228 boolean
TIMER::any_running()
230 for (TIMER
*list_iter
= list_head
; list_iter
!= NULL
;
231 list_iter
= list_iter
->list_next
) {
232 if (list_iter
->running()) return TRUE
;
237 alt_status
TIMER::any_timeout()
239 alt_status ret_val
= ALT_NO
;
240 for (TIMER
*list_iter
= list_head
; list_iter
!= NULL
;
241 list_iter
= list_iter
->list_next
) {
242 switch (list_iter
->timeout()) {
244 TTCN_Logger::log_timer_any_timeout();
250 TTCN_error("Internal error: Timer %s returned unexpected status "
251 "code while evaluating `any timer.timeout'.",
252 list_iter
->timer_name
);
255 if (ret_val
== ALT_NO
) {
256 TTCN_Logger::log_matching_timeout(NULL
);
261 boolean
TIMER::get_min_expiration(double& min_val
)
263 boolean min_flag
= FALSE
;
264 double alt_begin
= TTCN_Snapshot::get_alt_begin();
265 if (testcase_timer
.is_started
&& testcase_timer
.t_expires
>= alt_begin
) {
266 min_val
= testcase_timer
.t_expires
;
269 for (TIMER
*list_iter
= list_head
; list_iter
!= NULL
;
270 list_iter
= list_iter
->list_next
) {
271 // timers that are expired before the previous snapshot are ignored
272 if (list_iter
->t_expires
< alt_begin
) continue;
273 else if (!min_flag
|| list_iter
->t_expires
< min_val
) {
274 min_val
= list_iter
->t_expires
;
281 void TIMER::save_control_timers()
283 if (control_timers_saved
)
284 TTCN_error("Internal error: Control part timers are already saved.");
285 // put the list of control part timers into the backup
286 backup_head
= list_head
;
288 backup_tail
= list_tail
;
290 control_timers_saved
= TRUE
;
293 void TIMER::restore_control_timers()
295 if (!control_timers_saved
)
296 TTCN_error("Internal error: Control part timers are not saved.");
297 if (list_head
!= NULL
)
298 TTCN_error("Internal error: There are active timers. "
299 "Control part timers cannot be restored.");
300 // restore the list of control part timers from the backup
301 list_head
= backup_head
;
303 list_tail
= backup_tail
;
305 control_timers_saved
= FALSE
;
308 TIMER
testcase_timer("<testcase guard timer>");
This page took 0.046115 seconds and 5 git commands to generate.