diff options
-rw-r--r-- | scripts/automation/trex_control_plane/stl/console/trex_tui.py | 80 | ||||
-rwxr-xr-x | src/bp_sim.cpp | 3 | ||||
-rw-r--r-- | src/main_dpdk.cpp | 18 | ||||
-rwxr-xr-x | src/os_time.h | 13 | ||||
-rwxr-xr-x | src/utl_cpuu.cpp | 7 | ||||
-rwxr-xr-x | src/utl_cpuu.h | 8 |
6 files changed, 92 insertions, 37 deletions
diff --git a/scripts/automation/trex_control_plane/stl/console/trex_tui.py b/scripts/automation/trex_control_plane/stl/console/trex_tui.py index 6dff0a6f..e769b9b2 100644 --- a/scripts/automation/trex_control_plane/stl/console/trex_tui.py +++ b/scripts/automation/trex_control_plane/stl/console/trex_tui.py @@ -515,9 +515,31 @@ class ScreenBuffer(): self.redraw_cb(buffer) with self.lock: - self.snapshot = buffer.getvalue() + self.snapshot = buffer self.update_flag = False +# a policer class to make sure no too-fast redraws +# occurs - it filters fast bursts of redraws +class RedrawPolicer(): + def __init__ (self, rate): + self.ts = 0 + self.marked = False + self.rate = rate + self.force = False + + def mark_for_redraw (self, force = False): + self.marked = True + if force: + self.force = True + + def should_redraw (self): + dt = time.time() - self.ts + return self.force or (self.marked and (dt > self.rate)) + + def reset (self, restart = False): + self.ts = time.time() + self.marked = restart + self.force = False # shows a textual top style window @@ -531,6 +553,7 @@ class TrexTUI(): MIN_ROWS = 50 MIN_COLS = 111 + class ScreenSizeException(Exception): def __init__ (self, cols, rows): msg = "TUI requires console screen size of at least {0}x{1}, current is {2}x{3}".format(TrexTUI.MIN_COLS, @@ -585,7 +608,12 @@ class TrexTUI(): self.pm.init(show_log, locked) self.state = self.STATE_ACTIVE - self.last_redraw_ts = 0 + + # create print policers + self.full_redraw = RedrawPolicer(0.5) + self.keys_redraw = RedrawPolicer(0.05) + self.full_redraw.mark_for_redraw() + try: self.sb.start() @@ -594,11 +622,10 @@ class TrexTUI(): # draw and handle user input status = self.async_keys.tick(self.pm) - self.draw_screen(status) - - # speedup for keys, slower for no keys - if status == AsyncKeys.STATUS_NONE: - time.sleep(0.001) + # prepare the next frame + self.prepare(status) + time.sleep(0.01) + self.draw_screen() with self.tui_global_lock: self.handle_state_machine() @@ -611,6 +638,7 @@ class TrexTUI(): print("") + # handle state machine def handle_state_machine (self): @@ -641,34 +669,44 @@ class TrexTUI(): self.state = self.STATE_LOST_CONT - # draw once - def draw_screen (self, status): + # logic before printing + def prepare (self, status): + if status == AsyncKeys.STATUS_REDRAW_ALL: + self.full_redraw.mark_for_redraw(force = True) - t = time.time() - self.last_redraw_ts - redraw = (t >= 0.5) or (status == AsyncKeys.STATUS_REDRAW_ALL) - if redraw: + elif status == AsyncKeys.STATUS_REDRAW_KEYS: + self.keys_redraw.mark_for_redraw() + + if self.full_redraw.should_redraw(): self.sb.update() - self.last_redraw_ts = time.time() - + self.full_redraw.reset(restart = True) + return + + + # draw once + def draw_screen (self): + + # check for screen buffer's new screen x = self.sb.get() # we have a new screen to draw if x: self.clear_screen() - - sys.stdout.write(x) - self.async_keys.draw(sys.stdout) + + self.async_keys.draw(x) + sys.stdout.write(x.getvalue()) sys.stdout.flush() - # we only need to redraw the keys - elif status == AsyncKeys.STATUS_REDRAW_KEYS: + # maybe we need to redraw the keys + elif self.keys_redraw.should_redraw(): sys.stdout.write("\x1b[4A") - self.async_keys.draw(sys.stdout) sys.stdout.flush() - return + # reset the policer for next time + self.keys_redraw.reset() + diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp index 2d1d020b..773e82fc 100755 --- a/src/bp_sim.cpp +++ b/src/bp_sim.cpp @@ -4615,8 +4615,7 @@ double CFlowGenList::GetCpuUtilRaw(){ void CFlowGenList::UpdateFast(){ - int i; - for (i=0; i<(int)m_threads_info.size(); i++) { + for (int i=0; i<(int)m_threads_info.size(); i++) { CFlowGenListPerThread * lp=m_threads_info[i]; lp->Update(); } diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 6beb4e3e..0ef83c02 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -4126,15 +4126,21 @@ void CGlobalTRex::handle_fast_path() { /* check from messages from DP */ check_for_dp_messages(); - // update CPU% - m_fl.UpdateFast(); - if (get_is_stateless()) { - m_rx_sl.update_cpu_util(); - }else{ - m_mg.update_fast(); + /* measure CPU utilization by sampling (we sample 1000 to get an accurate sampling) */ + for (int i = 0; i < 1000; i++) { + m_fl.UpdateFast(); + + if (get_is_stateless()) { + m_rx_sl.update_cpu_util(); + }else{ + m_mg.update_fast(); + } + + rte_pause(); } + if ( is_all_cores_finished() ) { mark_for_shutdown(SHUTDOWN_TEST_ENDED); } diff --git a/src/os_time.h b/src/os_time.h index b1d44c03..4f10e2b5 100755 --- a/src/os_time.h +++ b/src/os_time.h @@ -165,6 +165,17 @@ void delay(int msec){ nanosleep(&time1,&remain); } - +/** + * more accurate sleep by doing spin + * + */ +static inline +void delay_spin(double sec) { + double target = now_sec() + sec; + + while (now_sec() < target) { + rte_pause(); + } +} #endif diff --git a/src/utl_cpuu.cpp b/src/utl_cpuu.cpp index 47c78c8e..c01326d6 100755 --- a/src/utl_cpuu.cpp +++ b/src/utl_cpuu.cpp @@ -42,10 +42,11 @@ void CCpuUtlCp::Update(){ if ( m_dpcpu->sample_data() ) { m_work++; } - if (m_ticks==100) { + if (m_ticks==100000) { /* LPF*/ - m_cpu_util_lpf = (m_cpu_util_lpf*0.75)+((double)m_work*0.25); - AppendHistory(m_work); + double work = (m_work / double(m_ticks)) * 100; + m_cpu_util_lpf = (m_cpu_util_lpf*0.75)+(work*0.25); + AppendHistory(work); m_ticks=0; m_work=0; } diff --git a/src/utl_cpuu.h b/src/utl_cpuu.h index b0a76fce..690eb200 100755 --- a/src/utl_cpuu.h +++ b/src/utl_cpuu.h @@ -47,7 +47,7 @@ public: private: - uint8_t m_data; + volatile uint8_t m_data; } __rte_cache_aligned; class CCpuUtlCp { @@ -62,9 +62,9 @@ public: void GetHistory(cpu_vct_st &cpu_vct); private: void AppendHistory(uint8_t); - CCpuUtlDp * m_dpcpu; - uint8_t m_ticks; - uint8_t m_work; + CCpuUtlDp * m_dpcpu; + uint32_t m_ticks; + uint32_t m_work; static const int m_history_size=20; uint8_t m_cpu_util[m_history_size]; // history as cyclic array |