From c8d64f0dd187d945fd7504fd4b6559e15be066f6 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 21 Jul 2025 15:04:07 +0200 Subject: [PATCH 01/10] nr rlc: add an API function to retrieve the occupancy of TX list --- openair2/LAYER2/nr_rlc/nr_rlc_entity.c | 3 +++ openair2/LAYER2/nr_rlc/nr_rlc_entity.h | 1 + openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c | 5 +++++ openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h | 1 + openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c | 6 ++++++ openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h | 1 + openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c | 6 ++++++ openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h | 1 + openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 19 +++++++++++++++++++ openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h | 2 ++ 10 files changed, 45 insertions(+) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c index 6103a7011a..e452981357 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c @@ -125,6 +125,7 @@ nr_rlc_entity_t *new_nr_rlc_entity_am( ret->common.reestablishment = nr_rlc_entity_am_reestablishment; ret->common.delete_entity = nr_rlc_entity_am_delete; ret->common.available_tx_space = nr_rlc_entity_am_available_tx_space; + ret->common.tx_list_occupancy = nr_rlc_entity_am_tx_list_occupancy; ret->common.get_stats = nr_rlc_entity_get_stats; ret->common.deliver_sdu = deliver_sdu; @@ -186,6 +187,7 @@ nr_rlc_entity_t *new_nr_rlc_entity_um( ret->common.reestablishment = nr_rlc_entity_um_reestablishment; ret->common.delete_entity = nr_rlc_entity_um_delete; ret->common.available_tx_space = nr_rlc_entity_um_available_tx_space; + ret->common.tx_list_occupancy = nr_rlc_entity_um_tx_list_occupancy; ret->common.get_stats = nr_rlc_entity_get_stats; ret->common.deliver_sdu = deliver_sdu; @@ -226,6 +228,7 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm( ret->common.reestablishment = nr_rlc_entity_tm_reestablishment; ret->common.delete_entity = nr_rlc_entity_tm_delete; ret->common.available_tx_space = nr_rlc_entity_tm_available_tx_space; + ret->common.tx_list_occupancy = nr_rlc_entity_tm_tx_list_occupancy; ret->common.get_stats = nr_rlc_entity_get_stats; ret->common.deliver_sdu = deliver_sdu; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h index dc0bf4907c..459e9f59a5 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h @@ -116,6 +116,7 @@ typedef struct nr_rlc_entity_t { void (*delete_entity)(struct nr_rlc_entity_t *entity); int (*available_tx_space)(struct nr_rlc_entity_t *entity); + int (*tx_list_occupancy)(struct nr_rlc_entity_t *entity); void (*get_stats)(struct nr_rlc_entity_t *entity, nr_rlc_statistics_t *out); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c index a66ebe82e5..b1f87a7a05 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c @@ -2116,3 +2116,8 @@ int nr_rlc_entity_am_available_tx_space(nr_rlc_entity_t *_entity) return entity->tx_maxsize - entity->tx_size; } +int nr_rlc_entity_am_tx_list_occupancy(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + return entity->tx_size; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h index 6b61e84a2f..3ffcab6176 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h @@ -101,5 +101,6 @@ void nr_rlc_entity_am_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); void nr_rlc_entity_am_reestablishment(nr_rlc_entity_t *_entity); void nr_rlc_entity_am_delete(nr_rlc_entity_t *entity); int nr_rlc_entity_am_available_tx_space(nr_rlc_entity_t *entity); +int nr_rlc_entity_am_tx_list_occupancy(nr_rlc_entity_t *_entity); #endif /* _NR_RLC_ENTITY_AM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c index 7b541c02ff..be20d574c1 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c @@ -221,3 +221,9 @@ int nr_rlc_entity_tm_available_tx_space(nr_rlc_entity_t *_entity) nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; return entity->tx_maxsize - entity->tx_size; } + +int nr_rlc_entity_tm_tx_list_occupancy(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + return entity->tx_size; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h index 716b35d14d..2792017c34 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h @@ -56,5 +56,6 @@ void nr_rlc_entity_tm_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); void nr_rlc_entity_tm_reestablishment(nr_rlc_entity_t *_entity); void nr_rlc_entity_tm_delete(nr_rlc_entity_t *entity); int nr_rlc_entity_tm_available_tx_space(nr_rlc_entity_t *entity); +int nr_rlc_entity_tm_tx_list_occupancy(nr_rlc_entity_t *_entity); #endif /* _NR_RLC_ENTITY_TM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c index 75e407328b..4edee0ddab 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c @@ -765,3 +765,9 @@ int nr_rlc_entity_um_available_tx_space(nr_rlc_entity_t *_entity) nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; return entity->tx_maxsize - entity->tx_size; } + +int nr_rlc_entity_um_tx_list_occupancy(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + return entity->tx_size; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h index 6395bfd47e..c32c5aaedf 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h @@ -80,5 +80,6 @@ void nr_rlc_entity_um_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); void nr_rlc_entity_um_reestablishment(nr_rlc_entity_t *_entity); void nr_rlc_entity_um_delete(nr_rlc_entity_t *entity); int nr_rlc_entity_um_available_tx_space(nr_rlc_entity_t *entity); +int nr_rlc_entity_um_tx_list_occupancy(nr_rlc_entity_t *_entity); #endif /* _NR_RLC_ENTITY_UM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 88c8d5d377..e187541fd5 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -320,6 +320,25 @@ int nr_rlc_get_available_tx_space(const int ue_id, const logical_chan_id_t chann return ret; } +int nr_rlc_tx_list_occupancy(int ue_id, logical_chan_id_t lcid) +{ + int ret; + + nr_rlc_manager_lock(nr_rlc_ue_manager); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); + nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, lcid); + + if (rb != NULL) { + ret = rb->tx_list_occupancy(rb); + } else { + ret = 0; + } + + nr_rlc_manager_unlock(nr_rlc_ue_manager); + + return ret; +} + int nr_rlc_module_init(nr_rlc_op_mode_t mode) { static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h index fec65796d9..454a59b928 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h @@ -80,6 +80,8 @@ void nr_rlc_reconfigure_entity(int ue_id, int lc_id, NR_RLC_Config_t *rlc_Config int nr_rlc_get_available_tx_space(const int ue_id, const logical_chan_id_t channel_idP); +int nr_rlc_tx_list_occupancy(int ue_id, logical_chan_id_t lcid); + void nr_rlc_activate_avg_time_to_tx(const int ue_id, const logical_chan_id_t channel_id, const bool is_on); void nr_rlc_srb_recv_sdu(const int ue_id, const logical_chan_id_t channel_id, unsigned char *buf, int size); From ee2668b7c38014ee2291656254af1b79bdfd2856 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 21 Jul 2025 15:08:55 +0200 Subject: [PATCH 02/10] T GUI: add a get_range() API function for xy_plot --- common/utils/T/tracer/gui/gui.h | 2 ++ common/utils/T/tracer/gui/xy_plot.c | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index 0fb96db325..b2fce32cff 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -54,6 +54,8 @@ void container_set_child_growable(gui *_gui, widget *_this, int xy_plot_new_plot(gui *gui, widget *this, int color); void xy_plot_set_range(gui *gui, widget *this, float xmin, float xmax, float ymin, float ymax); +void xy_plot_get_range(gui *gui, widget *this, + float *xmin, float *xmax, float *ymin, float *ymax); void xy_plot_set_points(gui *gui, widget *this, int plot, int npoints, float *x, float *y); void xy_plot_get_dimensions(gui *gui, widget *this, int *width, int *height); diff --git a/common/utils/T/tracer/gui/xy_plot.c b/common/utils/T/tracer/gui/xy_plot.c index c10b76c6ee..cc198475c2 100644 --- a/common/utils/T/tracer/gui/xy_plot.c +++ b/common/utils/T/tracer/gui/xy_plot.c @@ -280,6 +280,22 @@ void xy_plot_set_range(gui *_gui, widget *_this, gunlock(g); } +void xy_plot_get_range(gui *_gui, widget *_this, + float *xmin, float *xmax, float *ymin, float *ymax) +{ + struct gui *g = _gui; + struct xy_plot_widget *this = _this; + + glock(g); + + *xmin = this->xmin; + *xmax = this->xmax; + *ymin = this->ymin; + *ymax = this->ymax; + + gunlock(g); +} + void xy_plot_set_points(gui *_gui, widget *_this, int plot, int npoints, float *x, float *y) { From 645393f4647fdab12a90d4969724ae9de895c070 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 21 Jul 2025 15:30:00 +0200 Subject: [PATCH 03/10] T: throughputlog: handle tick discontinuities Think: TDD. --- common/utils/T/tracer/logger/throughputlog.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/common/utils/T/tracer/logger/throughputlog.c b/common/utils/T/tracer/logger/throughputlog.c index 8a2d46da91..8faa942533 100644 --- a/common/utils/T/tracer/logger/throughputlog.c +++ b/common/utils/T/tracer/logger/throughputlog.c @@ -73,12 +73,18 @@ static void _tick_event(void *p, event e) for (i = 0; i < l->common.vsize; i++) l->common.v[i]->append(l->common.v[i], frame, subframe, (double)l->total); - l->insert_point = (l->insert_point + 1) % 1000; - l->total -= l->bits[l->insert_point]; - l->bits[l->insert_point] = 0; + while (l->last_tick_frame != frame || l->last_tick_subframe != subframe) { + l->insert_point = (l->insert_point + 1) % 1000; + l->total -= l->bits[l->insert_point]; + l->bits[l->insert_point] = 0; + l->last_tick_subframe++; + if (l->last_tick_subframe == 10) { + l->last_tick_subframe = 0; + l->last_tick_frame++; + l->last_tick_frame %= 1024; + } + } - l->last_tick_frame = frame; - l->last_tick_subframe = subframe; } logger *new_throughputlog(event_handler *h, void *database, From 595e650f9fff7f3cba8dcf796bfa4577c485a13e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 21 Jul 2025 15:46:15 +0200 Subject: [PATCH 04/10] T: scrolltti: handle tick discontinuities For TDD. --- common/utils/T/tracer/view/scrolltti.c | 30 ++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/common/utils/T/tracer/view/scrolltti.c b/common/utils/T/tracer/view/scrolltti.c index ad83cbc756..3dde5daecc 100644 --- a/common/utils/T/tracer/view/scrolltti.c +++ b/common/utils/T/tracer/view/scrolltti.c @@ -20,6 +20,8 @@ struct scrolltti { float xout[1000]; float yout[1000]; int insert_point; + int next_tick_frame; + int next_tick_subframe; }; /* this array is used to get Y range 1000, 2000, 5000, 10000, ... */ @@ -65,15 +67,35 @@ static void clear(view *this) /* TODO */ } +static void insert(struct scrolltti *this, double value) +{ + this->total -= this->data[this->insert_point]; + this->data[this->insert_point] = value; + this->total += this->data[this->insert_point]; + this->insert_point = (this->insert_point + 1) % 1000; +} + +static void next_subframe(struct scrolltti *this) +{ + this->next_tick_subframe++; + if (this->next_tick_subframe == 10) { + this->next_tick_subframe = 0; + this->next_tick_frame++; + this->next_tick_frame %= 1024; + } +} + static void append(view *_this, int frame, int subframe, double value) { struct scrolltti *this = (struct scrolltti *)_this; if (pthread_mutex_lock(&this->lock)) abort(); - this->total -= this->data[this->insert_point]; - this->data[this->insert_point] = value; - this->total += this->data[this->insert_point]; - this->insert_point = (this->insert_point + 1) % 1000; + while (this->next_tick_frame != frame || this->next_tick_subframe != subframe) { + insert(this, 0); + next_subframe(this); + } + insert(this, value); + next_subframe(this); if (pthread_mutex_unlock(&this->lock)) abort(); } From 138886ad5e05baba37cec5c9dd037deeb9971822 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 21 Jul 2025 16:05:02 +0200 Subject: [PATCH 05/10] T: tti view: add automax ability Also, update a cmake file because compilation of the tracer 'ue' fails otherwise. --- common/utils/T/tracer/CMakeLists.txt | 4 ++-- common/utils/T/tracer/view/tti.c | 25 +++++++++++++++++++++++++ common/utils/T/tracer/view/view.h | 1 + 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/CMakeLists.txt b/common/utils/T/tracer/CMakeLists.txt index e1c79ffdf6..60266b5fa9 100644 --- a/common/utils/T/tracer/CMakeLists.txt +++ b/common/utils/T/tracer/CMakeLists.txt @@ -63,8 +63,8 @@ if(T_TRACER_GUI) target_link_libraries(gnb PRIVATE png) add_executable(ue ue.c) - target_link_libraries(ue PRIVATE tracer_utils tracer_filter tracer_gui - tracer_logger tracer_view tracer_events) + target_link_libraries(ue PRIVATE tracer_utils tracer_view tracer_gui + tracer_logger tracer_filter tracer_events) target_link_libraries(ue PRIVATE png) add_executable(vcd vcd.c) diff --git a/common/utils/T/tracer/view/tti.c b/common/utils/T/tracer/view/tti.c index ebf9fc657c..38a7a70777 100644 --- a/common/utils/T/tracer/view/tti.c +++ b/common/utils/T/tracer/view/tti.c @@ -5,11 +5,14 @@ #include #include #include +#include struct tti { view common; gui *g; widget *w; + int automax; + widget *w2; int plot; float refresh_rate; pthread_mutex_t lock; @@ -48,6 +51,7 @@ static void *tti_thread(void *_this) if (pthread_mutex_lock(&this->lock)) abort(); xy_plot_get_dimensions(this->g, this->w, &plot_width, &plot_height); length = 0; + double max = 0; /* TODO: optimize */ for (i = 0; i < 1024*10; i++) /* do not take points too close after last insertion point */ @@ -55,8 +59,22 @@ static void *tti_thread(void *_this) far_enough(i, this->last_insert_point, plot_width)) { this->xout[length] = i; this->yout[length] = this->data[i]; + if (this->data[i] > max) max = this->data[i]; length++; } + if (this->automax) { + char o[128]; + sprintf(o, "%d", (int)max); + textarea_set_text(this->g, this->w2, o); + /* for Y range we want 10, 20, 50, 100, 200, 500, etc. */ + if (max < 10) max = 10; + double mlog = pow(10, floor(log10(max))); + static int tolog[11] = { -1, 1, 2, 5, 5, 5, 10, 10, 10, 10, 10 }; + max = tolog[(int)ceil(max/mlog)] * mlog; + float xmin, xmax, ymin, ymax; + xy_plot_get_range(this->g, this->w, &xmin, &xmax, &ymin, &ymax); + xy_plot_set_range(this->g, this->w, xmin, xmax, 0, max); + } xy_plot_set_points(this->g, this->w, this->plot, length, this->xout, this->yout); if (pthread_mutex_unlock(&this->lock)) abort(); @@ -119,3 +137,10 @@ view *new_view_tti(float refresh_rate, gui *g, widget *w, int color) return (view *)ret; } + +void view_tti_enable_automax(view *_tti, widget *w2) +{ + struct tti *tti = (struct tti *)_tti; + tti->automax = 1; + tti->w2 = w2; +} diff --git a/common/utils/T/tracer/view/view.h b/common/utils/T/tracer/view/view.h index 8167a00ccd..3dec6d3bff 100644 --- a/common/utils/T/tracer/view/view.h +++ b/common/utils/T/tracer/view/view.h @@ -27,5 +27,6 @@ view *new_subview_time(view *time, int line, int color, int size); view *new_view_ticktime(float refresh_rate, gui *g, widget *w); view *new_subview_ticktime(view *ticktime, int line, int color, int size); void ticktime_set_tick(view *ticktime, void *logger); +void view_tti_enable_automax(view *tti, widget *w2); #endif /* _VIEW_H_ */ From c4acec706deebdca240ab3ed6e2607f5df754e3d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 21 Jul 2025 16:13:14 +0200 Subject: [PATCH 06/10] T: make number of subframes per frame a configurable item Think: NR with different number of slots per frame depending on mu. The name 'subframes_per_frame' is a bit ambiguous. It is valid for LTE, but for NR it should be 'slots_per_frame'. For example, for sub-carrier spacing of 30KHz, we have 20 slots per frame, so in this case subframes_per_frame = 20. In reality whatever the numerology, there is always 10 subframes per frame in NR. But how to name this variable which is used both for LTE and NR cases? 'subframes_or_slots_per_frame'? It's a bit long and also ambiguous. Conclusion: no big deal I think. 'subframes_per_frame' and so be it. --- common/utils/T/tracer/enb.c | 16 ++++---- common/utils/T/tracer/logger/logger.h | 2 +- common/utils/T/tracer/logger/throughputlog.c | 13 +++++-- common/utils/T/tracer/ue.c | 34 ++++++++--------- common/utils/T/tracer/view/scrolltti.c | 33 ++++++++++------ common/utils/T/tracer/view/tti.c | 40 +++++++++++++------- common/utils/T/tracer/view/view.h | 6 +-- 7 files changed, 86 insertions(+), 58 deletions(-) diff --git a/common/utils/T/tracer/enb.c b/common/utils/T/tracer/enb.c index 5bb1cb87e2..f48f8e7dd7 100644 --- a/common/utils/T/tracer/enb.c +++ b/common/utils/T/tracer/enb.c @@ -340,12 +340,12 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database, xy_plot_set_range(g, w, 0, 1024*10, -10, 80); l = new_ttilog(h, database, "ENB_PHY_PUCCH_1_ENERGY", "frame", "subframe", "threshold", 0); - v = new_view_tti(10, g, w, new_color(g, "#ff0000")); + v = new_view_tti(10, g, w, new_color(g, "#ff0000"), 10); logger_add_view(l, v); e->pucch1_energy_ue_threshold_logger = l; l = new_ttilog(h, database, "ENB_PHY_PUCCH_1_ENERGY", "frame", "subframe", "energy", 1); - v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10); logger_add_view(l, v); e->pucch1_energy_ue_energy_logger = l; @@ -368,7 +368,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database, widget_add_child(g, line, w, -1); l = new_ticked_ttilog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe", "ENB_PHY_DLSCH_UE_DCI", "mcs", 0, -1); - v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10); logger_add_view(l, v); e->dl_mcs_logger = l; @@ -379,7 +379,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database, widget_add_child(g, line, w, -1); l = new_ticked_ttilog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe", "ENB_PHY_ULSCH_UE_DCI", "mcs", 0, -1); - v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10); logger_add_view(l, v); e->ul_mcs_logger = l; @@ -394,8 +394,8 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database, widget_add_child(g, col, w, -1); container_set_child_growable(g, col, w, 1); l = new_throughputlog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe", - "ENB_PHY_DLSCH_UE_DCI", "TBS"); - v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2); + "ENB_PHY_DLSCH_UE_DCI", "TBS", 10); + v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2, 10); logger_add_view(l, v); /* UE x UL PHY (truly: DCI) throughput */ @@ -409,8 +409,8 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database, widget_add_child(g, col, w, -1); container_set_child_growable(g, col, w, 1); l = new_throughputlog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe", - "ENB_PHY_ULSCH_UE_DCI", "TBS"); - v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2); + "ENB_PHY_ULSCH_UE_DCI", "TBS", 10); + v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2, 10); logger_add_view(l, v); /* downlink/uplink UE DCIs */ diff --git a/common/utils/T/tracer/logger/logger.h b/common/utils/T/tracer/logger/logger.h index d746161e70..8508032ec0 100644 --- a/common/utils/T/tracer/logger/logger.h +++ b/common/utils/T/tracer/logger/logger.h @@ -16,7 +16,7 @@ logger *new_ticked_ttilog(void *event_handler, void *database, int convert_to_dB, float empty_value); logger *new_throughputlog(void *event_handler, void *database, char *tick_event_name, char *frame_varname, char *subframe_varname, - char *event_name, char *data_varname); + char *event_name, char *data_varname, int subframes_per_frame); logger *new_timelog(void *event_handler, void *database, char *event_name); logger *new_ticklog(void *event_handler, void *database, char *event_name, char *frame_name, char *subframe_name); diff --git a/common/utils/T/tracer/logger/throughputlog.c b/common/utils/T/tracer/logger/throughputlog.c index 8faa942533..e7b48f6e2f 100644 --- a/common/utils/T/tracer/logger/throughputlog.c +++ b/common/utils/T/tracer/logger/throughputlog.c @@ -19,7 +19,8 @@ struct throughputlog { int data_arg; int last_tick_frame; int last_tick_subframe; - unsigned long bits[1000]; + int subframes_per_frame; + unsigned long *bits; unsigned long total; int insert_point; char *tick_event_name; @@ -74,11 +75,11 @@ static void _tick_event(void *p, event e) l->common.v[i]->append(l->common.v[i], frame, subframe, (double)l->total); while (l->last_tick_frame != frame || l->last_tick_subframe != subframe) { - l->insert_point = (l->insert_point + 1) % 1000; + l->insert_point = (l->insert_point + 1) % (100 * l->subframes_per_frame); l->total -= l->bits[l->insert_point]; l->bits[l->insert_point] = 0; l->last_tick_subframe++; - if (l->last_tick_subframe == 10) { + if (l->last_tick_subframe == l->subframes_per_frame) { l->last_tick_subframe = 0; l->last_tick_frame++; l->last_tick_frame %= 1024; @@ -89,7 +90,7 @@ static void _tick_event(void *p, event e) logger *new_throughputlog(event_handler *h, void *database, char *tick_event_name, char *frame_varname, char *subframe_varname, - char *event_name, char *data_varname) + char *event_name, char *data_varname, int subframes_per_frame) { struct throughputlog *ret; int event_id; @@ -189,6 +190,10 @@ logger *new_throughputlog(event_handler *h, void *database, abort(); } + ret->subframes_per_frame = subframes_per_frame; + ret->bits = calloc(100 * subframes_per_frame, sizeof(unsigned long)); + if (ret->bits == NULL) abort(); + return ret; } diff --git a/common/utils/T/tracer/ue.c b/common/utils/T/tracer/ue.c index b28f83b0f2..f4ea38f980 100644 --- a/common/utils/T/tracer/ue.c +++ b/common/utils/T/tracer/ue.c @@ -250,15 +250,15 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, widget_add_child(g, line, w, -1); xy_plot_set_range(g, w, 0, 1024*10, -130, 35); /*l = new_ticked_ttilog(h, database,"UE_PHY_DL_TICK", "frame", "subframe","UE_PHY_MEAS", "rssi", 0, -1); - v = new_view_tti(10, g, w, new_color(g, "#720c0c")); + v = new_view_tti(10, g, w, new_color(g, "#720c0c"), 10); logger_add_view(l, v); e->phy_meas_logger = l;*/ l = new_ticked_ttilog(h, database,"UE_PHY_DL_TICK", "frame", "subframe","UE_PHY_MEAS", "rsrp", 0, -1); - v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10); logger_add_view(l, v); e->phy_meas_logger = l; l = new_ticked_ttilog(h, database,"UE_PHY_DL_TICK", "frame", "subframe","UE_PHY_MEAS", "snr", 0, -1); - v = new_view_tti(10, g, w, new_color(g, "#0c720c")); + v = new_view_tti(10, g, w, new_color(g, "#0c720c"), 10); logger_add_view(l, v); e->phy_meas_logger = l; @@ -277,7 +277,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, widget_add_child(g, line, w, -1); l = new_ticked_ttilog(h, database, "UE_PHY_DL_TICK", "frame", "subframe", "UE_PHY_DLSCH_UE_DCI", "mcs", 0, -1); - v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10); logger_add_view(l, v); e->dl_mcs_logger = l; @@ -288,7 +288,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, widget_add_child(g, line, w, -1); l = new_ticked_ttilog(h, database, "UE_PHY_DL_TICK", "frame", "subframe", "UE_PHY_ULSCH_UE_DCI", "mcs", 0, -1); - v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10); logger_add_view(l, v); e->ul_mcs_logger = l; @@ -301,12 +301,12 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, xy_plot_set_range(g, w, 0, 1024*10, -30, 50); l = new_ttilog(h, database, "UE_PHY_PUSCH_TX_POWER", "frame", "subframe", "p0_pusch", 0); - v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10); logger_add_view(l, v); e->pusch_power_logger = l; l = new_ttilog(h, database, "UE_PHY_PUSCH_TX_POWER", "frame", "subframe", "ampl", 1); - v = new_view_tti(10, g, w, new_color(g, "#720c0c")); + v = new_view_tti(10, g, w, new_color(g, "#720c0c"), 10); logger_add_view(l, v); e->pusch_ampl_logger = l; @@ -319,12 +319,12 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, xy_plot_set_range(g, w, 0, 1024*10, -30, 50); l = new_ttilog(h, database, "UE_PHY_PUCCH_TX_POWER", "frame", "subframe", "p0_pucch", 0); - v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 10); logger_add_view(l, v); e->pucch_power_logger = l; l = new_ttilog(h, database, "UE_PHY_PUCCH_TX_POWER", "frame", "subframe", "ampl", 1); - v = new_view_tti(10, g, w, new_color(g, "#720c0c")); + v = new_view_tti(10, g, w, new_color(g, "#720c0c"), 10); logger_add_view(l, v); e->pucch_ampl_logger = l; @@ -335,22 +335,22 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, xy_plot_set_range(g, w, 0, 1024*10, -10, 80); l = new_ttilog(h, database, "UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level00", 1); - v = new_view_tti(10, g, w, new_color(g, "#ff0000")); + v = new_view_tti(10, g, w, new_color(g, "#ff0000"), 10); logger_add_view(l, v); e->pdsch_energy_logger = l; l = new_ttilog(h, database, "UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level01", 1); - v = new_view_tti(10, g, w, new_color(g, "#00ff00")); + v = new_view_tti(10, g, w, new_color(g, "#00ff00"), 10); logger_add_view(l, v); e->pdsch_energy_logger = l; l = new_ttilog(h, database, "UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level10", 1); - v = new_view_tti(10, g, w, new_color(g, "#0f0f0f")); + v = new_view_tti(10, g, w, new_color(g, "#0f0f0f"), 10); logger_add_view(l, v); e->pdsch_energy_logger = l; l = new_ttilog(h, database, "UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level11", 1); - v = new_view_tti(10, g, w, new_color(g, "#0000ff")); + v = new_view_tti(10, g, w, new_color(g, "#0000ff"), 10); logger_add_view(l, v); e->pdsch_energy_logger = l; @@ -361,22 +361,22 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, xy_plot_set_range(g, w, 0, 1024*10, -10, 80); l = new_ttilog(h, database, "UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level00", 1); - v = new_view_tti(10, g, w, new_color(g, "#ff0000")); + v = new_view_tti(10, g, w, new_color(g, "#ff0000"), 10); logger_add_view(l, v); e->pdcch_energy_logger = l; l = new_ttilog(h, database, "UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level01", 1); - v = new_view_tti(10, g, w, new_color(g, "#00ff00")); + v = new_view_tti(10, g, w, new_color(g, "#00ff00"), 10); logger_add_view(l, v); e->pdcch_energy_logger = l; l = new_ttilog(h, database, "UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level10", 1); - v = new_view_tti(10, g, w, new_color(g, "#0f0f0f")); + v = new_view_tti(10, g, w, new_color(g, "#0f0f0f"), 10); logger_add_view(l, v); e->pdcch_energy_logger = l; l = new_ttilog(h, database, "UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level11", 1); - v = new_view_tti(10, g, w, new_color(g, "#0000ff")); + v = new_view_tti(10, g, w, new_color(g, "#0000ff"), 10); logger_add_view(l, v); e->pdcch_energy_logger = l; diff --git a/common/utils/T/tracer/view/scrolltti.c b/common/utils/T/tracer/view/scrolltti.c index 3dde5daecc..66fe0b3f02 100644 --- a/common/utils/T/tracer/view/scrolltti.c +++ b/common/utils/T/tracer/view/scrolltti.c @@ -15,10 +15,11 @@ struct scrolltti { int plot; float refresh_rate; pthread_mutex_t lock; - unsigned long data[1000]; - unsigned long total; /* sum data[0..999] to have smoother value printed */ - float xout[1000]; - float yout[1000]; + int subframes_per_frame; + unsigned long *data; + unsigned long total; /* sum data[0..n] to have smoother value printed */ + float *xout; + float *yout; int insert_point; int next_tick_frame; int next_tick_subframe; @@ -40,21 +41,21 @@ static void *scrolltti_thread(void *_this) /* TODO: optimize */ p = this->insert_point; max = 0; - for (i = 0; i < 1000; i++) { + for (i = 0; i < this->subframes_per_frame * 100; i++) { this->xout[i] = i; this->yout[i] = this->data[p]; if (this->data[p] > max) max = this->data[p]; - p = (p + 1) % 1000; + p = (p + 1) % (this->subframes_per_frame * 100); } - bps(o, this->total/1000., "b/s"); + bps(o, this->total/(this->subframes_per_frame * 100.), "b/s"); textarea_set_text(this->g, this->throughput_textarea, o); /* for Y range we want 1000, 2000, 5000, 10000, 20000, 50000, etc. */ if (max < 1000) max = 1000; mlog = pow(10, floor(log10(max))); max = tolog[(int)ceil(max/mlog)] * mlog; - xy_plot_set_range(this->g, this->w, 0, 1000, 0, max); + xy_plot_set_range(this->g, this->w, 0, this->subframes_per_frame * 100, 0, max); xy_plot_set_points(this->g, this->w, this->plot, - 1000, this->xout, this->yout); + this->subframes_per_frame * 100, this->xout, this->yout); if (pthread_mutex_unlock(&this->lock)) abort(); sleepms(1000/this->refresh_rate); } @@ -72,13 +73,13 @@ static void insert(struct scrolltti *this, double value) this->total -= this->data[this->insert_point]; this->data[this->insert_point] = value; this->total += this->data[this->insert_point]; - this->insert_point = (this->insert_point + 1) % 1000; + this->insert_point = (this->insert_point + 1) % (this->subframes_per_frame * 100); } static void next_subframe(struct scrolltti *this) { this->next_tick_subframe++; - if (this->next_tick_subframe == 10) { + if (this->next_tick_subframe == this->subframes_per_frame) { this->next_tick_subframe = 0; this->next_tick_frame++; this->next_tick_frame %= 1024; @@ -100,7 +101,7 @@ static void append(view *_this, int frame, int subframe, double value) } view *new_view_scrolltti(float refresh_rate, gui *g, widget *w, int color, - widget *throughput_textarea) + widget *throughput_textarea, int subframes_per_frame) { struct scrolltti *ret = calloc(1, sizeof(struct scrolltti)); if (ret == NULL) abort(); @@ -114,6 +115,14 @@ view *new_view_scrolltti(float refresh_rate, gui *g, widget *w, int color, ret->throughput_textarea = throughput_textarea; ret->plot = xy_plot_new_plot(g, w, color); + ret->subframes_per_frame = subframes_per_frame; + ret->data = calloc(subframes_per_frame * 100, sizeof(unsigned long)); + if (ret->data == NULL) abort(); + ret->xout = calloc(subframes_per_frame * 100, sizeof(float)); + if (ret->xout == NULL) abort(); + ret->yout = calloc(subframes_per_frame * 100, sizeof(float)); + if (ret->yout == NULL) abort(); + if (pthread_mutex_init(&ret->lock, NULL)) abort(); new_thread(scrolltti_thread, ret); diff --git a/common/utils/T/tracer/view/tti.c b/common/utils/T/tracer/view/tti.c index 38a7a70777..6c352d08d5 100644 --- a/common/utils/T/tracer/view/tti.c +++ b/common/utils/T/tracer/view/tti.c @@ -16,23 +16,25 @@ struct tti { int plot; float refresh_rate; pthread_mutex_t lock; - float data[1024*10]; - int valid[1024*10]; - float xout[1024*10]; - float yout[1024*10]; + float *data; + int *valid; + float *xout; + float *yout; int last_insert_point; + int subframes_per_frame; }; -static int far_enough(int i, int last_insert, int plot_width) +static int far_enough(int i, int last_insert, int plot_width, + int subframes_per_frame) { int p1; int p2; int hole_size_px; int hole_size_tti; hole_size_px = 10; - hole_size_tti = 10240 * hole_size_px / plot_width; + hole_size_tti = 1024 * subframes_per_frame * hole_size_px / plot_width; p1 = last_insert; - p2 = (last_insert + hole_size_tti) % (1024*10); + p2 = (last_insert + hole_size_tti) % (1024 * subframes_per_frame); if (p1 < p2) { return !(i > p1 && i < p2); } @@ -53,10 +55,11 @@ static void *tti_thread(void *_this) length = 0; double max = 0; /* TODO: optimize */ - for (i = 0; i < 1024*10; i++) + for (i = 0; i < 1024 * this->subframes_per_frame; i++) /* do not take points too close after last insertion point */ if (this->valid[i] && - far_enough(i, this->last_insert_point, plot_width)) { + far_enough(i, this->last_insert_point, plot_width, + this->subframes_per_frame)) { this->xout[length] = i; this->yout[length] = this->data[i]; if (this->data[i] > max) max = this->data[i]; @@ -93,7 +96,7 @@ static void append(view *_this, int frame, int subframe, double value) { struct tti *this = (struct tti *)_this; int i; - int index = frame * 10 + subframe; + int index = frame * this->subframes_per_frame + subframe; if (pthread_mutex_lock(&this->lock)) abort(); @@ -102,10 +105,10 @@ static void append(view *_this, int frame, int subframe, double value) * this may be wrong if delay between two append is * greater than 1024 frames (something like that) */ - i = (this->last_insert_point + 1) % (1024*10); + i = (this->last_insert_point + 1) % (1024 * this->subframes_per_frame); while (i != index) { this->valid[i] = 0; - i = (i + 1) % (1024*10); + i = (i + 1) % (1024 * this->subframes_per_frame); } this->data[index] = value; @@ -116,7 +119,8 @@ static void append(view *_this, int frame, int subframe, double value) if (pthread_mutex_unlock(&this->lock)) abort(); } -view *new_view_tti(float refresh_rate, gui *g, widget *w, int color) +view *new_view_tti(float refresh_rate, gui *g, widget *w, int color, + int subframes_per_frame) { struct tti *ret = calloc(1, sizeof(struct tti)); if (ret == NULL) abort(); @@ -133,6 +137,16 @@ view *new_view_tti(float refresh_rate, gui *g, widget *w, int color) if (pthread_mutex_init(&ret->lock, NULL)) abort(); + ret->subframes_per_frame = subframes_per_frame; + ret->data = calloc(subframes_per_frame * 1024, sizeof(float)); + if (ret->data == NULL) abort(); + ret->valid = calloc(subframes_per_frame * 1024, sizeof(int)); + if (ret->valid == NULL) abort(); + ret->xout = calloc(subframes_per_frame * 1024, sizeof(float)); + if (ret->xout == NULL) abort(); + ret->yout = calloc(subframes_per_frame * 1024, sizeof(float)); + if (ret->yout == NULL) abort(); + new_thread(tti_thread, ret); return (view *)ret; diff --git a/common/utils/T/tracer/view/view.h b/common/utils/T/tracer/view/view.h index 3dec6d3bff..7f131efbb5 100644 --- a/common/utils/T/tracer/view/view.h +++ b/common/utils/T/tracer/view/view.h @@ -17,10 +17,10 @@ view *new_view_stdout(void); view *new_view_textlist(int maxsize, float refresh_rate, gui *g, widget *w); view *new_view_xy(int length, float refresh_rate, gui *g, widget *w, int color, enum xy_mode mode); -view *new_view_tti(float refresh_rate, gui *g, widget *w, - int color); +view *new_view_tti(float refresh_rate, gui *g, widget *w, int color, + int subframes_per_frame); view *new_view_scrolltti(float refresh_rate, gui *g, widget *w, - int color, widget *throughput_label); + int color, widget *throughput_label, int subframes_per_frame); view *new_view_time(int number_of_seconds, float refresh_rate, gui *g, widget *w); view *new_subview_time(view *time, int line, int color, int size); From cc87c72ac3942e01716ba94b647e883f69ec0baf Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 21 Jul 2025 16:20:52 +0200 Subject: [PATCH 07/10] T: fix a typo --- common/utils/T/T_messages.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 813226ec14..b45b0fc68d 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -92,9 +92,9 @@ ID = UE_PHY_INITIATE_RA_PROCEDURE GROUP = ALL:PHY:UE:WIRESHARK FORMAT = int,frame : int,subframe_or_slot : int,preamble : int,power ID = GNB_PHY_DL_TICK - DESC = gNodeB downlink tick - one tick per ms at start of downlink processing + DESC = gNodeB downlink tick - one tick per slot at start of downlink processing GROUP = ALL:PHY:GRAPHIC:GNB - FORMAT = int,gNB_ID : int,frame : int,subframe + FORMAT = int,gNB_ID : int,frame : int,slot ID = ENB_PHY_MIB DESC = MIB data GROUP = ALL:PHY:ENB:WIRESHARK From c4562df2e7707beeb8239359c9c56d5e1e3f0fc2 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 21 Jul 2025 16:25:12 +0200 Subject: [PATCH 08/10] T: add some traces To be used by next commit. --- common/utils/T/T_messages.txt | 20 +++++++++++++++++++ executables/nr-gnb.c | 2 ++ .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 2 ++ .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 4 ++++ 4 files changed, 28 insertions(+) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index b45b0fc68d..8dd5052714 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -95,6 +95,10 @@ ID = GNB_PHY_DL_TICK DESC = gNodeB downlink tick - one tick per slot at start of downlink processing GROUP = ALL:PHY:GRAPHIC:GNB FORMAT = int,gNB_ID : int,frame : int,slot +ID = GNB_PHY_UL_TICK + DESC = gNodeB uplink tick - one tick per slot at start of uplink processing + GROUP = ALL:PHY:GRAPHIC:GNB + FORMAT = int,gNB_ID : int,frame : int,slot ID = ENB_PHY_MIB DESC = MIB data GROUP = ALL:PHY:ENB:WIRESHARK @@ -221,6 +225,22 @@ ID = NRUE_MAC_DL_RAR_PDU_WITH_DATA DESC = NR MAC downlink PDU for RAR GROUP = ALL:MAC:UE:WIRESHARK FORMAT = int,rnti : int,frame : int,slot : buffer,data +ID = GNB_MAC_DL + DESC = NR MAC downlink scheduler decision for an UE + GROUP = ALL:MAC:GNB + FORMAT = int,rnti : int,frame : int,slot : int,mcs : int,tbs +ID = GNB_MAC_LCID_DL + DESC = NR MAC downlink scheduler decision for an UE for a specific LCID + GROUP = ALL:MAC:GNB + FORMAT = int,rnti : int,frame : int,slot : int,lcid : int,data_size : int,tx_list_occupancy +ID = GNB_MAC_UL + DESC = NR MAC uplink scheduler decision for an UE + GROUP = ALL:MAC:GNB + FORMAT = int,rnti : int,frame : int,slot : int,mcs : int,tbs +ID = GNB_MAC_LCID_UL + DESC = NR MAC uplink traffic received for an UE for a specific LCID + GROUP = ALL:MAC:GNB + FORMAT = int,rnti : int,frame : int,slot : int,lcid : int,data_size #RLC logs ID = ENB_RLC_DL diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 345b58df7e..5ba70dc32b 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -174,6 +174,8 @@ static void rx_func(processingData_L1_t *info) int slot_rx = info->slot_rx; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; + T(T_GNB_PHY_UL_TICK, T_INT(gNB->Mod_id), T_INT(frame_rx), T_INT(slot_rx)); + // RX processing int rx_slot_type = nr_slot_select(cfg, frame_rx, slot_rx); if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 44d4affb08..c47b8ceb33 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -1307,6 +1307,7 @@ void nr_schedule_ue_spec(module_id_t module_id, if (len == 0) break; + T(T_GNB_MAC_LCID_DL, T_INT(rnti), T_INT(frame), T_INT(slot), T_INT(lcid), T_INT(len * 8), T_INT(nr_rlc_tx_list_occupancy(rnti, lcid))); header->R = 0; header->F = 1; header->LCID = lcid; @@ -1380,6 +1381,7 @@ void nr_schedule_ue_spec(module_id_t module_id, T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti), T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock.buf, TBS)); + T(T_GNB_MAC_DL, T_INT(rnti), T_INT(frame), T_INT(slot), T_INT(sched_pdsch->mcs), T_INT(TBS)); } const int ntx_req = TX_req->Number_of_PDUs; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 4486be536d..c177a791b9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -485,6 +485,7 @@ static int nr_process_mac_pdu(instance_t module_idP, UE->mac_stats.ul.total_sdu_bytes += mac_len; UE->mac_stats.ul.lc_bytes[lcid] += mac_len; } + T(T_GNB_MAC_LCID_UL, T_INT(UE->rnti), T_INT(frameP), T_INT(slot), T_INT(lcid), T_INT(mac_len * 8)); break; case UL_SCH_LCID_DTCH ...(UL_SCH_LCID_DTCH + 28): @@ -512,6 +513,7 @@ static int nr_process_mac_pdu(instance_t module_idP, else sched_ctrl->estimated_ul_buffer = 0; } + T(T_GNB_MAC_LCID_UL, T_INT(UE->rnti), T_INT(frameP), T_INT(slot), T_INT(lcid), T_INT(mac_len * 8)); break; case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY: @@ -2467,6 +2469,8 @@ void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes, sched_ctrl->tpc0); + T(T_GNB_MAC_UL, T_INT(UE->rnti), T_INT(frame), T_INT(slot), T_INT(sched_pusch->mcs), T_INT(sched_pusch->tb_size)); + /* PUSCH in a later slot, but corresponding DCI now! */ const int index = ul_buffer_index(sched_pusch->frame, sched_pusch->slot, From fcd001398165dd47494b375749321a0ce031f449 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 21 Jul 2025 16:28:09 +0200 Subject: [PATCH 09/10] T: add a tracer 'gnb_mac' To see MAC scheduling decisions. May be useful for debugging. --- common/utils/T/.gitignore | 1 + common/utils/T/tracer/CMakeLists.txt | 6 +- common/utils/T/tracer/Makefile | 17 +- common/utils/T/tracer/gnb_mac.c | 332 +++++++++++++++++++++++++++ 4 files changed, 349 insertions(+), 7 deletions(-) create mode 100644 common/utils/T/tracer/gnb_mac.c diff --git a/common/utils/T/.gitignore b/common/utils/T/.gitignore index 60264a9c4a..7ac6cc75bd 100644 --- a/common/utils/T/.gitignore +++ b/common/utils/T/.gitignore @@ -3,6 +3,7 @@ genids tracer/enb tracer/gnb +tracer/gnb_mac tracer/extract_config tracer/record tracer/replay diff --git a/common/utils/T/tracer/CMakeLists.txt b/common/utils/T/tracer/CMakeLists.txt index 60266b5fa9..56568c905e 100644 --- a/common/utils/T/tracer/CMakeLists.txt +++ b/common/utils/T/tracer/CMakeLists.txt @@ -62,6 +62,10 @@ if(T_TRACER_GUI) tracer_logger tracer_view tracer_events) target_link_libraries(gnb PRIVATE png) + add_executable(gnb_mac gnb_mac.c) + target_link_libraries(gnb_mac PRIVATE tracer_utils tracer_filter tracer_gui + tracer_logger tracer_view tracer_events) + add_executable(ue ue.c) target_link_libraries(ue PRIVATE tracer_utils tracer_view tracer_gui tracer_logger tracer_filter tracer_events) @@ -77,5 +81,5 @@ if(T_TRACER_GUI) add_subdirectory(gui) - add_dependencies(T_tools enb gnb ue vcd to_vcd) + add_dependencies(T_tools enb gnb gnb_mac ue vcd to_vcd) endif() diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index 6777be7152..ce99eabbe8 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -8,7 +8,7 @@ XLIBS=-lX11 -lpng -lXft all: record replay extract_config textlog enb ue vcd macpdu2wireshark \ extract_input_subframe extract_output_subframe to_vcd extract multi \ - gnb t_tracer_app_gnb t_tracer_app_ue + gnb t_tracer_app_gnb t_tracer_app_ue gnb_mac record: utils.o record.o database.o configuration.o $(CC) $(CFLAGS) -o record $^ $(LIBS) @@ -65,14 +65,18 @@ gnb: utils.o gnb.o database.o event.o handler.o configuration.o \ filter/filter.a $(CC) $(CFLAGS) -o gnb $^ $(LIBS) $(XLIBS) -t_tracer_app_gnb: utils.o t_tracer_app_gnb.o database.o event.o handler.o configuration.o \ - logger/logger.a filter/filter.a +t_tracer_app_gnb: utils.o t_tracer_app_gnb.o database.o event.o handler.o \ + configuration.o logger/logger.a filter/filter.a $(CC) $(CFLAGS) -o t_tracer_app_gnb $^ $(LIBS) $(XLIBS) -t_tracer_app_ue: utils.o t_tracer_app_ue.o database.o event.o handler.o configuration.o \ - logger/logger.a filter/filter.a +t_tracer_app_ue: utils.o t_tracer_app_ue.o database.o event.o handler.o \ + configuration.o logger/logger.a filter/filter.a $(CC) $(CFLAGS) -o t_tracer_app_ue $^ $(LIBS) $(XLIBS) +gnb_mac: gnb_mac.o gui/gui.a view/view.a logger/logger.a filter/filter.a \ + utils.o database.o configuration.o handler.o event.o + $(CC) $(CFLAGS) -o gnb_mac $^ $(LIBS) $(XLIBS) + multi.o: ../incgen/T_IDs.h ../incgen/T_IDs.h: ../T_messages.txt @@ -98,7 +102,8 @@ filter/filter.a: clean: rm -f *.o core tracer_remote textlog enb ue vcd record replay rm -f extract_config macpdu2wireshark extract_input_subframe - rm -f extract_output_subframe to_vcd extract multi gnb t_tracer_app_gnb t_tracer_app_ue + rm -f extract_output_subframe to_vcd extract multi gnb + rm -f t_tracer_app_gnb t_tracer_app_ue gnb_mac cd gui && $(MAKE) clean cd view && $(MAKE) clean cd logger && $(MAKE) clean diff --git a/common/utils/T/tracer/gnb_mac.c b/common/utils/T/tracer/gnb_mac.c new file mode 100644 index 0000000000..84f29b8f82 --- /dev/null +++ b/common/utils/T/tracer/gnb_mac.c @@ -0,0 +1,332 @@ +#include +#include +#include +#include + +#include "utils.h" +#include "gui/gui.h" +#include "view/view.h" +#include "logger/logger.h" +#include "filter/filter.h" +#include "database.h" +#include "configuration.h" +#include "handler.h" + +typedef struct { + int used; +} ue_list_item; + +typedef struct { + widget *container; +} gnb_gui; + +typedef struct { + int socket; + gui *g; + gnb_gui *gg; + event_handler *h; + void *database; + ue_list_item ues[65536]; + int rnti_arg; +} gnb_data; + +void *gui_thread(void *_g) +{ + gui *g = _g; + gui_loop(g); + return 0; +} + +void add_ue(gnb_data *gd, int rnti, int lcid) +{ + event_handler *h = gd->h; + void *database = gd->database; + gnb_gui *gg = gd->gg; + gui *g = gd->g; + widget *line; + widget *w, *w2, *col; + view *v; + logger *l; + + gd->ues[rnti].used = 1; + + line = new_container(g, HORIZONTAL); + widget_add_child(g, gg->container, line, -1); + + /* label */ + char s[512]; + sprintf(s, "UE %d", rnti); + widget *label = new_label(g, s); + widget_add_child(g, line, label, -1); + + /* DL MCS */ + w = new_xy_plot(g, 128, 55, "DL mcs", 20); + xy_plot_set_range(g, w, 0, 1024*20, -2, 30); + widget_add_child(g, line, w, -1); + l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot", + "GNB_MAC_DL", "mcs", 0, -1); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20); + logger_add_view(l, v); + logger_set_filter(l, + filter_eq( + filter_evarg(database, "GNB_MAC_DL", "rnti"), + filter_int(rnti))); + + /* DL TBS */ + col = new_container(g, VERTICAL); + widget_add_child(g, line, col, -1); + w = new_xy_plot(g, 70, 10, "DL tbs", 35); + w2 = new_textarea(g, 70, 11, 64); + xy_plot_set_range(g, w, 0, 1024*20, 0, 1000); + xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK); + widget_add_child(g, col, w2, -1); + widget_add_child(g, col, w, -1); + container_set_child_growable(g, col, w, 1); + l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot", + "GNB_MAC_DL", "tbs", 0, -1); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20); + view_tti_enable_automax(v, w2); + logger_add_view(l, v); + logger_set_filter(l, + filter_eq( + filter_evarg(database, "GNB_MAC_DL", "rnti"), + filter_int(rnti))); + + /* DL lcid throughput */ + col = new_container(g, VERTICAL); + widget_add_child(g, line, col, -1); + sprintf(s, "DL lcid %d", lcid); + w = new_xy_plot(g, 70, 10, s, 35); + w2 = new_textarea(g, 70, 11, 64); + xy_plot_set_range(g, w, 0, 1000, 0, 100000); + xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK); + widget_add_child(g, col, w2, -1); + widget_add_child(g, col, w, -1); + container_set_child_growable(g, col, w, 1); + l = new_throughputlog(h, database, "GNB_PHY_DL_TICK", "frame", "slot", + "GNB_MAC_LCID_DL", "data_size", 20); + v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2, 20); + logger_add_view(l, v); + logger_set_filter(l, + filter_and( + filter_eq( + filter_evarg(database, "GNB_MAC_LCID_DL", "rnti"), + filter_int(rnti)), + filter_eq( + filter_evarg(database, "GNB_MAC_LCID_DL", "lcid"), + filter_int(lcid)))); + + /* UL MCS */ + w = new_xy_plot(g, 128, 55, "UL mcs", 20); + xy_plot_set_range(g, w, 0, 1024*20, -2, 30); + widget_add_child(g, line, w, -1); + /* GNB_PHY_DL_TICK (and not UL) because GNB_MAC_UL is from DCI */ + l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot", + "GNB_MAC_UL", "mcs", 0, -1); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20); + logger_add_view(l, v); + logger_set_filter(l, + filter_eq( + filter_evarg(database, "GNB_MAC_UL", "rnti"), + filter_int(rnti))); + + /* UL TBS */ + col = new_container(g, VERTICAL); + widget_add_child(g, line, col, -1); + w = new_xy_plot(g, 70, 10, "UL tbs", 35); + w2 = new_textarea(g, 70, 11, 64); + xy_plot_set_range(g, w, 0, 1024*20, 0, 1000); + xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK); + widget_add_child(g, col, w2, -1); + widget_add_child(g, col, w, -1); + container_set_child_growable(g, col, w, 1); + /* GNB_PHY_DL_TICK (and not UL) because GNB_MAC_UL is from DCI */ + l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot", + "GNB_MAC_UL", "tbs", 0, -1); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20); + view_tti_enable_automax(v, w2); + logger_add_view(l, v); + logger_set_filter(l, + filter_eq( + filter_evarg(database, "GNB_MAC_UL", "rnti"), + filter_int(rnti))); + + /* UL lcid throughput */ + col = new_container(g, VERTICAL); + widget_add_child(g, line, col, -1); + sprintf(s, "UL lcid %d", lcid); + w = new_xy_plot(g, 70, 10, s, 35); + w2 = new_textarea(g, 70, 11, 64); + xy_plot_set_range(g, w, 0, 1000, 0, 100000); + xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK); + widget_add_child(g, col, w2, -1); + widget_add_child(g, col, w, -1); + container_set_child_growable(g, col, w, 1); + l = new_throughputlog(h, database, "GNB_PHY_UL_TICK", "frame", "slot", + "GNB_MAC_LCID_UL", "data_size", 20); + v = new_view_scrolltti(10, g, w, new_color(g, "#0c0c72"), w2, 20); + logger_add_view(l, v); + logger_set_filter(l, + filter_and( + filter_eq( + filter_evarg(database, "GNB_MAC_LCID_UL", "rnti"), + filter_int(rnti)), + filter_eq( + filter_evarg(database, "GNB_MAC_LCID_UL", "lcid"), + filter_int(lcid)))); + + /* lcid RLC tx buffer occupancy */ + col = new_container(g, VERTICAL); + widget_add_child(g, line, col, -1); + sprintf(s, "rlc tx %d", lcid); + w = new_xy_plot(g, 70, 10, s, 35); + w2 = new_textarea(g, 70, 11, 64); + xy_plot_set_range(g, w, 0, 1024*20, 0, 1000); + xy_plot_set_tick_type(g, w, XY_PLOT_SCROLL_TICK); + widget_add_child(g, col, w2, -1); + widget_add_child(g, col, w, -1); + container_set_child_growable(g, col, w, 1); + l = new_ticked_ttilog(h, database, "GNB_PHY_DL_TICK", "frame", "slot", + "GNB_MAC_LCID_DL", "tx_list_occupancy", 0, -1); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72"), 20); + view_tti_enable_automax(v, w2); + logger_add_view(l, v); + logger_set_filter(l, + filter_and( + filter_eq( + filter_evarg(database, "GNB_MAC_LCID_DL", "rnti"), + filter_int(rnti)), + filter_eq( + filter_evarg(database, "GNB_MAC_LCID_DL", "lcid"), + filter_int(lcid)))); +} + +void build_gui(gnb_gui *gg, gui *g) +{ + widget *main_window; + + main_window = new_toplevel_window(g, 900, 1000, "gNB MAC tracer"); + gg->container = new_container(g, VERTICAL); + widget_add_child(g, main_window, gg->container, -1); +} + +void usage(void) +{ + printf( +"options:\n" +" -d this option is mandatory\n" +" -ip connect to given IP address (default %s)\n" +" -p connect to given port (default %d)\n", + DEFAULT_REMOTE_IP, + DEFAULT_REMOTE_PORT + ); + exit(1); +} + +void check_new_ue(void *_gd, event e) +{ + gnb_data *gd = _gd; + int rnti = e.e[gd->rnti_arg].i; + if (!gd->ues[rnti].used) + add_ue(gd, rnti, 4); +} + +int main(int n, char **v) +{ + gui *g; + gnb_gui gg; + gnb_data *gd; + char *database_filename = NULL; + void *database; + char *ip = DEFAULT_REMOTE_IP; + int port = DEFAULT_REMOTE_PORT; + event_handler *h; + int *is_on; + int number_of_events; + int i; + + for (i = 1; i < n; i++) { + if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); + if (!strcmp(v[i], "-d")) { if (i > n-2) usage(); database_filename = v[++i]; continue; } + if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; } + if (!strcmp(v[i], "-p")) { if (i > n-2) usage(); port = atoi(v[++i]); continue; } + usage(); + } + + if (database_filename == NULL) { + printf("ERROR: provide a database file (-d)\n"); + exit(1); + } + + database = parse_database(database_filename); + + load_config_file(database_filename); + + number_of_events = number_of_ids(database); + is_on = calloc(number_of_events, sizeof(int)); + if (is_on == NULL) abort(); + + on_off(database, "GNB_PHY_DL_TICK", is_on, 1); + on_off(database, "GNB_MAC_DL", is_on, 1); + on_off(database, "GNB_MAC_LCID_DL", is_on, 1); + on_off(database, "GNB_PHY_UL_TICK", is_on, 1); + on_off(database, "GNB_MAC_UL", is_on, 1); + on_off(database, "GNB_MAC_LCID_UL", is_on, 1); + + gd = calloc(1, sizeof(*gd)); if (!gd) abort(); + + h = new_handler(database); + + g = gui_init(); + new_thread(gui_thread, g); + + build_gui(&gg, g); + + gd->g = g; + gd->gg = ≫ + gd->h = h; + gd->database = database; + + /* get rnti_arg from event GNB_MAC_DL */ + int event_id = event_id_from_name(database, "GNB_MAC_DL"); + database_event_format f = get_format(database, event_id); + gd->rnti_arg = -1; + for (i = 0; i < f.count; i++) { + if (!strcmp(f.name[i], "rnti")) gd->rnti_arg = i; + } + if (gd->rnti_arg == -1) { + printf("fatal: event 'GNB_MAC_DL' does not have argument 'rnti'\n"); + exit(1); + } + if (strcmp(f.type[gd->rnti_arg], "int") != 0) { + printf("fatal: argument 'rnti' of event 'GNB_MAC_DL' is not 'int'\n"); + exit(1); + } + + register_handler_function(h, event_id, check_new_ue, gd); + + OBUF ebuf = {.osize = 0, .omaxsize = 0, .obuf = NULL}; + + gd->socket = -1; + +restart: + clear_remote_config(); + if (gd->socket != -1) close(gd->socket); + gd->socket = connect_to(ip, port); + + /* send the first message - activate selected traces */ + int t = 1; + if (socket_send(gd->socket, &t, 1) == -1 || + socket_send(gd->socket, &number_of_events, sizeof(int)) == -1 || + socket_send(gd->socket, is_on, number_of_events * sizeof(int)) == -1) + goto restart; + + while (1) { + event e; + e = get_event(gd->socket, &ebuf, database); + if (e.type == -1) goto restart; + handle_event(h, e); + } + + return 0; +} From c8aea1b97021f45372ac1fa33b71dee599e6047f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 18 Aug 2025 11:21:31 +0200 Subject: [PATCH 10/10] T: replace 'subframe' by 'tick' Some code in T tracers is used by both LTE and NR. In LTE, we expect 10 subframes per frame, and the logging is done with this assumption. We have one tick per subframe. In NR, we deal with slots, not subframes. And we have n ticks per frame (depending on mu). As of today, only n=20 is tested (corresponding to mu=1). A previous commit introduced 'subframes_per_frame' which had the correct meaning for LTE but was truly 'slots per frame' for NR. This creates confusion. Let's replace 'subframe' by 'tick' to reduce confusion. --- common/utils/T/tracer/logger/logger.h | 4 +- common/utils/T/tracer/logger/throughputlog.c | 70 ++++++++++---------- common/utils/T/tracer/view/scrolltti.c | 42 ++++++------ common/utils/T/tracer/view/tti.c | 32 ++++----- common/utils/T/tracer/view/view.h | 4 +- 5 files changed, 76 insertions(+), 76 deletions(-) diff --git a/common/utils/T/tracer/logger/logger.h b/common/utils/T/tracer/logger/logger.h index 8508032ec0..b78fa1b359 100644 --- a/common/utils/T/tracer/logger/logger.h +++ b/common/utils/T/tracer/logger/logger.h @@ -15,8 +15,8 @@ logger *new_ticked_ttilog(void *event_handler, void *database, char *event_name, char *data_varname, int convert_to_dB, float empty_value); logger *new_throughputlog(void *event_handler, void *database, - char *tick_event_name, char *frame_varname, char *subframe_varname, - char *event_name, char *data_varname, int subframes_per_frame); + char *tick_event_name, char *frame_varname, char *tick_varname, + char *event_name, char *data_varname, int ticks_per_frame); logger *new_timelog(void *event_handler, void *database, char *event_name); logger *new_ticklog(void *event_handler, void *database, char *event_name, char *frame_name, char *subframe_name); diff --git a/common/utils/T/tracer/logger/throughputlog.c b/common/utils/T/tracer/logger/throughputlog.c index e7b48f6e2f..5f066df343 100644 --- a/common/utils/T/tracer/logger/throughputlog.c +++ b/common/utils/T/tracer/logger/throughputlog.c @@ -13,13 +13,13 @@ struct throughputlog { struct logger common; void *database; int tick_frame_arg; - int tick_subframe_arg; + int tick_tick_arg; int data_frame_arg; - int data_subframe_arg; + int data_tick_arg; int data_arg; int last_tick_frame; - int last_tick_subframe; - int subframes_per_frame; + int last_tick_tick; + int ticks_per_frame; unsigned long *bits; unsigned long total; int insert_point; @@ -33,16 +33,16 @@ static void _event(void *p, event e) { struct throughputlog *l = p; int frame; - int subframe; + int tick; unsigned long value; if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0) return; frame = e.e[l->data_frame_arg].i; - subframe = e.e[l->data_subframe_arg].i; + tick = e.e[l->data_tick_arg].i; - if (frame != l->last_tick_frame || subframe != l->last_tick_subframe) { + if (frame != l->last_tick_frame || tick != l->last_tick_tick) { printf("WARNING: %s:%d: data comes without previous tick!\n", __FILE__, __LINE__); return; @@ -63,24 +63,24 @@ static void _tick_event(void *p, event e) struct throughputlog *l = p; int i; int frame; - int subframe; + int tick; if (l->tick_filter != NULL && filter_eval(l->tick_filter, e) == 0) return; frame = e.e[l->tick_frame_arg].i; - subframe = e.e[l->tick_subframe_arg].i; + tick = e.e[l->tick_tick_arg].i; for (i = 0; i < l->common.vsize; i++) - l->common.v[i]->append(l->common.v[i], frame, subframe, (double)l->total); + l->common.v[i]->append(l->common.v[i], frame, tick, (double)l->total); - while (l->last_tick_frame != frame || l->last_tick_subframe != subframe) { - l->insert_point = (l->insert_point + 1) % (100 * l->subframes_per_frame); + while (l->last_tick_frame != frame || l->last_tick_tick != tick) { + l->insert_point = (l->insert_point + 1) % (100 * l->ticks_per_frame); l->total -= l->bits[l->insert_point]; l->bits[l->insert_point] = 0; - l->last_tick_subframe++; - if (l->last_tick_subframe == l->subframes_per_frame) { - l->last_tick_subframe = 0; + l->last_tick_tick++; + if (l->last_tick_tick == l->ticks_per_frame) { + l->last_tick_tick = 0; l->last_tick_frame++; l->last_tick_frame %= 1024; } @@ -89,8 +89,8 @@ static void _tick_event(void *p, event e) } logger *new_throughputlog(event_handler *h, void *database, - char *tick_event_name, char *frame_varname, char *subframe_varname, - char *event_name, char *data_varname, int subframes_per_frame) + char *tick_event_name, char *frame_varname, char *tick_varname, + char *event_name, char *data_varname, int ticks_per_frame) { struct throughputlog *ret; int event_id; @@ -113,21 +113,21 @@ logger *new_throughputlog(event_handler *h, void *database, f = get_format(database, event_id); - /* look for frame and subframe */ + /* look for frame and tick */ ret->tick_frame_arg = -1; - ret->tick_subframe_arg = -1; + ret->tick_tick_arg = -1; for (i = 0; i < f.count; i++) { if (!strcmp(f.name[i], frame_varname)) ret->tick_frame_arg = i; - if (!strcmp(f.name[i], subframe_varname)) ret->tick_subframe_arg = i; + if (!strcmp(f.name[i], tick_varname)) ret->tick_tick_arg = i; } if (ret->tick_frame_arg == -1) { printf("%s:%d: frame argument '%s' not found in event '%s'\n", __FILE__, __LINE__, frame_varname, event_name); abort(); } - if (ret->tick_subframe_arg == -1) { - printf("%s:%d: subframe argument '%s' not found in event '%s'\n", - __FILE__, __LINE__, subframe_varname, event_name); + if (ret->tick_tick_arg == -1) { + printf("%s:%d: tick argument '%s' not found in event '%s'\n", + __FILE__, __LINE__, tick_varname, event_name); abort(); } if (strcmp(f.type[ret->tick_frame_arg], "int") != 0) { @@ -135,9 +135,9 @@ logger *new_throughputlog(event_handler *h, void *database, __FILE__, __LINE__, frame_varname); abort(); } - if (strcmp(f.type[ret->tick_subframe_arg], "int") != 0) { + if (strcmp(f.type[ret->tick_tick_arg], "int") != 0) { printf("%s:%d: argument '%s' has wrong type (should be 'int')\n", - __FILE__, __LINE__, subframe_varname); + __FILE__, __LINE__, tick_varname); abort(); } @@ -148,13 +148,13 @@ logger *new_throughputlog(event_handler *h, void *database, f = get_format(database, event_id); - /* look for frame, subframe and data args */ + /* look for frame, tick and data args */ ret->data_frame_arg = -1; - ret->data_subframe_arg = -1; + ret->data_tick_arg = -1; ret->data_arg = -1; for (i = 0; i < f.count; i++) { if (!strcmp(f.name[i], frame_varname)) ret->data_frame_arg = i; - if (!strcmp(f.name[i], subframe_varname)) ret->data_subframe_arg = i; + if (!strcmp(f.name[i], tick_varname)) ret->data_tick_arg = i; if (!strcmp(f.name[i], data_varname)) ret->data_arg = i; } if (ret->data_frame_arg == -1) { @@ -162,9 +162,9 @@ logger *new_throughputlog(event_handler *h, void *database, __FILE__, __LINE__, frame_varname, event_name); abort(); } - if (ret->data_subframe_arg == -1) { - printf("%s:%d: subframe argument '%s' not found in event '%s'\n", - __FILE__, __LINE__, subframe_varname, event_name); + if (ret->data_tick_arg == -1) { + printf("%s:%d: tick argument '%s' not found in event '%s'\n", + __FILE__, __LINE__, tick_varname, event_name); abort(); } if (ret->data_arg == -1) { @@ -177,9 +177,9 @@ logger *new_throughputlog(event_handler *h, void *database, __FILE__, __LINE__, frame_varname); abort(); } - if (strcmp(f.type[ret->data_subframe_arg], "int") != 0) { + if (strcmp(f.type[ret->data_tick_arg], "int") != 0) { printf("%s:%d: argument '%s' has wrong type (should be 'int')\n", - __FILE__, __LINE__, subframe_varname); + __FILE__, __LINE__, tick_varname); abort(); } if (strcmp(f.type[ret->data_arg], "int") != 0 && @@ -190,8 +190,8 @@ logger *new_throughputlog(event_handler *h, void *database, abort(); } - ret->subframes_per_frame = subframes_per_frame; - ret->bits = calloc(100 * subframes_per_frame, sizeof(unsigned long)); + ret->ticks_per_frame = ticks_per_frame; + ret->bits = calloc(100 * ticks_per_frame, sizeof(unsigned long)); if (ret->bits == NULL) abort(); return ret; diff --git a/common/utils/T/tracer/view/scrolltti.c b/common/utils/T/tracer/view/scrolltti.c index 66fe0b3f02..3bf1c93bd2 100644 --- a/common/utils/T/tracer/view/scrolltti.c +++ b/common/utils/T/tracer/view/scrolltti.c @@ -15,14 +15,14 @@ struct scrolltti { int plot; float refresh_rate; pthread_mutex_t lock; - int subframes_per_frame; + int ticks_per_frame; unsigned long *data; unsigned long total; /* sum data[0..n] to have smoother value printed */ float *xout; float *yout; int insert_point; int next_tick_frame; - int next_tick_subframe; + int next_tick_tick; }; /* this array is used to get Y range 1000, 2000, 5000, 10000, ... */ @@ -41,21 +41,21 @@ static void *scrolltti_thread(void *_this) /* TODO: optimize */ p = this->insert_point; max = 0; - for (i = 0; i < this->subframes_per_frame * 100; i++) { + for (i = 0; i < this->ticks_per_frame * 100; i++) { this->xout[i] = i; this->yout[i] = this->data[p]; if (this->data[p] > max) max = this->data[p]; - p = (p + 1) % (this->subframes_per_frame * 100); + p = (p + 1) % (this->ticks_per_frame * 100); } - bps(o, this->total/(this->subframes_per_frame * 100.), "b/s"); + bps(o, this->total/(this->ticks_per_frame * 100.), "b/s"); textarea_set_text(this->g, this->throughput_textarea, o); /* for Y range we want 1000, 2000, 5000, 10000, 20000, 50000, etc. */ if (max < 1000) max = 1000; mlog = pow(10, floor(log10(max))); max = tolog[(int)ceil(max/mlog)] * mlog; - xy_plot_set_range(this->g, this->w, 0, this->subframes_per_frame * 100, 0, max); + xy_plot_set_range(this->g, this->w, 0, this->ticks_per_frame * 100, 0, max); xy_plot_set_points(this->g, this->w, this->plot, - this->subframes_per_frame * 100, this->xout, this->yout); + this->ticks_per_frame * 100, this->xout, this->yout); if (pthread_mutex_unlock(&this->lock)) abort(); sleepms(1000/this->refresh_rate); } @@ -73,35 +73,35 @@ static void insert(struct scrolltti *this, double value) this->total -= this->data[this->insert_point]; this->data[this->insert_point] = value; this->total += this->data[this->insert_point]; - this->insert_point = (this->insert_point + 1) % (this->subframes_per_frame * 100); + this->insert_point = (this->insert_point + 1) % (this->ticks_per_frame * 100); } -static void next_subframe(struct scrolltti *this) +static void next_tick(struct scrolltti *this) { - this->next_tick_subframe++; - if (this->next_tick_subframe == this->subframes_per_frame) { - this->next_tick_subframe = 0; + this->next_tick_tick++; + if (this->next_tick_tick == this->ticks_per_frame) { + this->next_tick_tick = 0; this->next_tick_frame++; this->next_tick_frame %= 1024; } } -static void append(view *_this, int frame, int subframe, double value) +static void append(view *_this, int frame, int tick, double value) { struct scrolltti *this = (struct scrolltti *)_this; if (pthread_mutex_lock(&this->lock)) abort(); - while (this->next_tick_frame != frame || this->next_tick_subframe != subframe) { + while (this->next_tick_frame != frame || this->next_tick_tick != tick) { insert(this, 0); - next_subframe(this); + next_tick(this); } insert(this, value); - next_subframe(this); + next_tick(this); if (pthread_mutex_unlock(&this->lock)) abort(); } view *new_view_scrolltti(float refresh_rate, gui *g, widget *w, int color, - widget *throughput_textarea, int subframes_per_frame) + widget *throughput_textarea, int ticks_per_frame) { struct scrolltti *ret = calloc(1, sizeof(struct scrolltti)); if (ret == NULL) abort(); @@ -115,12 +115,12 @@ view *new_view_scrolltti(float refresh_rate, gui *g, widget *w, int color, ret->throughput_textarea = throughput_textarea; ret->plot = xy_plot_new_plot(g, w, color); - ret->subframes_per_frame = subframes_per_frame; - ret->data = calloc(subframes_per_frame * 100, sizeof(unsigned long)); + ret->ticks_per_frame = ticks_per_frame; + ret->data = calloc(ticks_per_frame * 100, sizeof(unsigned long)); if (ret->data == NULL) abort(); - ret->xout = calloc(subframes_per_frame * 100, sizeof(float)); + ret->xout = calloc(ticks_per_frame * 100, sizeof(float)); if (ret->xout == NULL) abort(); - ret->yout = calloc(subframes_per_frame * 100, sizeof(float)); + ret->yout = calloc(ticks_per_frame * 100, sizeof(float)); if (ret->yout == NULL) abort(); if (pthread_mutex_init(&ret->lock, NULL)) abort(); diff --git a/common/utils/T/tracer/view/tti.c b/common/utils/T/tracer/view/tti.c index 6c352d08d5..73d43b539b 100644 --- a/common/utils/T/tracer/view/tti.c +++ b/common/utils/T/tracer/view/tti.c @@ -21,20 +21,20 @@ struct tti { float *xout; float *yout; int last_insert_point; - int subframes_per_frame; + int ticks_per_frame; }; static int far_enough(int i, int last_insert, int plot_width, - int subframes_per_frame) + int ticks_per_frame) { int p1; int p2; int hole_size_px; int hole_size_tti; hole_size_px = 10; - hole_size_tti = 1024 * subframes_per_frame * hole_size_px / plot_width; + hole_size_tti = 1024 * ticks_per_frame * hole_size_px / plot_width; p1 = last_insert; - p2 = (last_insert + hole_size_tti) % (1024 * subframes_per_frame); + p2 = (last_insert + hole_size_tti) % (1024 * ticks_per_frame); if (p1 < p2) { return !(i > p1 && i < p2); } @@ -55,11 +55,11 @@ static void *tti_thread(void *_this) length = 0; double max = 0; /* TODO: optimize */ - for (i = 0; i < 1024 * this->subframes_per_frame; i++) + for (i = 0; i < 1024 * this->ticks_per_frame; i++) /* do not take points too close after last insertion point */ if (this->valid[i] && far_enough(i, this->last_insert_point, plot_width, - this->subframes_per_frame)) { + this->ticks_per_frame)) { this->xout[length] = i; this->yout[length] = this->data[i]; if (this->data[i] > max) max = this->data[i]; @@ -92,11 +92,11 @@ static void clear(view *this) /* TODO */ } -static void append(view *_this, int frame, int subframe, double value) +static void append(view *_this, int frame, int tick, double value) { struct tti *this = (struct tti *)_this; int i; - int index = frame * this->subframes_per_frame + subframe; + int index = frame * this->ticks_per_frame + tick; if (pthread_mutex_lock(&this->lock)) abort(); @@ -105,10 +105,10 @@ static void append(view *_this, int frame, int subframe, double value) * this may be wrong if delay between two append is * greater than 1024 frames (something like that) */ - i = (this->last_insert_point + 1) % (1024 * this->subframes_per_frame); + i = (this->last_insert_point + 1) % (1024 * this->ticks_per_frame); while (i != index) { this->valid[i] = 0; - i = (i + 1) % (1024 * this->subframes_per_frame); + i = (i + 1) % (1024 * this->ticks_per_frame); } this->data[index] = value; @@ -120,7 +120,7 @@ static void append(view *_this, int frame, int subframe, double value) } view *new_view_tti(float refresh_rate, gui *g, widget *w, int color, - int subframes_per_frame) + int ticks_per_frame) { struct tti *ret = calloc(1, sizeof(struct tti)); if (ret == NULL) abort(); @@ -137,14 +137,14 @@ view *new_view_tti(float refresh_rate, gui *g, widget *w, int color, if (pthread_mutex_init(&ret->lock, NULL)) abort(); - ret->subframes_per_frame = subframes_per_frame; - ret->data = calloc(subframes_per_frame * 1024, sizeof(float)); + ret->ticks_per_frame = ticks_per_frame; + ret->data = calloc(ticks_per_frame * 1024, sizeof(float)); if (ret->data == NULL) abort(); - ret->valid = calloc(subframes_per_frame * 1024, sizeof(int)); + ret->valid = calloc(ticks_per_frame * 1024, sizeof(int)); if (ret->valid == NULL) abort(); - ret->xout = calloc(subframes_per_frame * 1024, sizeof(float)); + ret->xout = calloc(ticks_per_frame * 1024, sizeof(float)); if (ret->xout == NULL) abort(); - ret->yout = calloc(subframes_per_frame * 1024, sizeof(float)); + ret->yout = calloc(ticks_per_frame * 1024, sizeof(float)); if (ret->yout == NULL) abort(); new_thread(tti_thread, ret); diff --git a/common/utils/T/tracer/view/view.h b/common/utils/T/tracer/view/view.h index 7f131efbb5..bc37e654d1 100644 --- a/common/utils/T/tracer/view/view.h +++ b/common/utils/T/tracer/view/view.h @@ -18,9 +18,9 @@ view *new_view_textlist(int maxsize, float refresh_rate, gui *g, widget *w); view *new_view_xy(int length, float refresh_rate, gui *g, widget *w, int color, enum xy_mode mode); view *new_view_tti(float refresh_rate, gui *g, widget *w, int color, - int subframes_per_frame); + int ticks_per_frame); view *new_view_scrolltti(float refresh_rate, gui *g, widget *w, - int color, widget *throughput_label, int subframes_per_frame); + int color, widget *throughput_label, int ticks_per_frame); view *new_view_time(int number_of_seconds, float refresh_rate, gui *g, widget *w); view *new_subview_time(view *time, int line, int color, int size);