From 76b91cfefb3d755ab6d294f4ecb58d6bae0dda09 Mon Sep 17 00:00:00 2001 From: Navid Nikaein <navid.nikaein@eurecom.fr> Date: Thu, 18 Jul 2013 11:53:58 +0000 Subject: [PATCH] * add additional RLC buffer information for fine grain DL scheduling * protect ENABLE_DB flag with explicit user-defined flag git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4036 818b1a75-f10b-46b9-bf7c-635c3b92a50f --- openair2/COMMON/mac_rlc_primitives.h | 3 ++ openair2/LAYER2/MAC/defs.h | 14 ++++++++ openair2/LAYER2/MAC/pre_processor.c | 38 ++++++++++++++++++--- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c | 36 ++++++++++++++++++-- openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c | 46 ++++++++++++++++++++------ openair2/LAYER2/RLC/mac_primitives.h | 2 +- openair2/LAYER2/RLC/rlc.h | 3 ++ openair2/LAYER2/RLC/rlc_mac.c | 9 +++-- targets/SIMU/USER/Makefile | 2 ++ 9 files changed, 133 insertions(+), 20 deletions(-) diff --git a/openair2/COMMON/mac_rlc_primitives.h b/openair2/COMMON/mac_rlc_primitives.h index cf375d4ea20..8c48af0d75e 100644 --- a/openair2/COMMON/mac_rlc_primitives.h +++ b/openair2/COMMON/mac_rlc_primitives.h @@ -165,6 +165,9 @@ in a suspended state or to indicate the current buffer occupancy to MAC. struct mac_status_resp { unsigned int buffer_occupancy_in_bytes; /*!< \brief the parameter Buffer Occupancy (BO) indicates for each logical channel the amount of data in number of bytes that is available for transmission and retransmission in RLC layer. */ unsigned short buffer_occupancy_in_pdus; /*!< xxx*/ + u32_t head_sdu_creation_time; + u32_t head_sdu_remaining_size_to_send; + unsigned char head_sdu_is_segmented; struct rlc_entity_info rlc_info; /*!< xxx*/ }; diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index bdf5f6ed296..2ed4f7de46d 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -511,6 +511,17 @@ typedef struct{ u32_t dl_buffer_info[MAX_NUM_LCID]; u32_t dl_buffer_total; + + u32_t dl_pdus_total; + + u32_t dl_pdus_in_buffer[MAX_NUM_LCID]; + + u32_t dl_buffer_head_sdu_creation_time[MAX_NUM_LCID]; + + u8 dl_buffer_head_sdu_is_segmented[MAX_NUM_LCID]; + + u32_t dl_buffer_head_sdu_remaining_size_to_send[MAX_NUM_LCID]; + } UE_TEMPLATE; typedef struct { @@ -1079,6 +1090,9 @@ u8 is_UE_active(unsigned char Mod_id, unsigned char UE_id ); u16 find_ulgranted_UEs(u8 Mod_id); u16 find_dlgranted_UEs(u8 Mod_id); u8 process_ue_cqi (u8 Mod_id, u8 UE_id); + +s8 find_active_UEs_with_traffic(unsigned char Mod_id); + u8 find_num_active_UEs_in_cbagroup(unsigned char Mod_id, unsigned char group_id); u8 UE_is_to_be_scheduled(u8 Mod_id,u8 UE_id); /** \brief Round-robin scheduler for ULSCH traffic. diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index bef4ad56dee..82678a0a588 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -88,9 +88,14 @@ void store_dlsch_buffer (unsigned char Mod_id, granted_UEs = find_dlgranted_UEs(Mod_id); for (UE_id=0;UE_id<granted_UEs;UE_id++){ - eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_total = 0; - for(i=0;i< MAX_NUM_LCID; i++) + eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_total = 0; + eNB_mac_inst[Mod_id].UE_template[UE_id].dl_pdus_total = 0; + for(i=0;i< MAX_NUM_LCID; i++) { eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_info[i]=0; + eNB_mac_inst[Mod_id].UE_template[UE_id].dl_pdus_in_buffer[i]=0; + eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_head_sdu_creation_time[i]=0; + eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_head_sdu_remaining_size_to_send[i]=0; + } } @@ -106,11 +111,36 @@ void store_dlsch_buffer (unsigned char Mod_id, rlc_status = mac_rlc_status_ind(Mod_id,frame,1,RLC_MBMS_NO,i+(NB_RB_MAX*next_ue),0 ); eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel - + eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer; + eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time ; + eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_remaining_size_to_send[i] = rlc_status.head_sdu_remaining_size_to_send; + eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_is_segmented[i] = rlc_status.head_sdu_is_segmented; eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total = eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total + eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_info[i];//storing the total dlsch buffer - + eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_total += eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_in_buffer[i]; + +#ifdef DEBUG_eNB_SCHEDULER + /* note for dl_buffer_head_sdu_remaining_size_to_send[i] : + * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent + */ + if (eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_info[i]>0) + LOG_D(MAC,"[eNB %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and %d size, head sdu queuing time %d, remaining size %d, is segmeneted %d \n", + Mod_id, frame, subframe, next_ue, + i, eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_in_buffer[i],eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_info[i], + eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_creation_time[i], + eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_remaining_size_to_send[i], + eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_is_segmented[i] + ); +#endif } +#ifdef DEBUG_eNB_SCHEDULER + if ( eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total>0) + LOG_D(MAC,"[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n", + Mod_id, frame, subframe, next_ue, + eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total, + eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_total + ); +#endif } } diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index 282fab08dae..e550eeaf990 100755 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -45,7 +45,7 @@ Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis //#define TRACE_RLC_AM_DATA_REQUEST //#define TRACE_RLC_AM_TX_STATUS //#define TRACE_RLC_AM_TX -#//define TRACE_RLC_AM_RX +//#define TRACE_RLC_AM_RX //#define TRACE_RLC_AM_BO //----------------------------------------------------------------------------- u32_t @@ -439,10 +439,16 @@ rlc_am_mac_status_indication (void *rlcP, u32 frame, u16 tb_sizeP, struct mac_st { //----------------------------------------------------------------------------- struct mac_status_resp status_resp; + u16_t sdu_size = 0; + u16_t sdu_remaining_size = 0; + s32_t diff_time=0; rlc_am_entity_t *rlc = (rlc_am_entity_t *) rlcP; - status_resp.buffer_occupancy_in_bytes = 0; - status_resp.buffer_occupancy_in_pdus = 0; + status_resp.buffer_occupancy_in_bytes = 0; + status_resp.buffer_occupancy_in_pdus = 0; + status_resp.head_sdu_remaining_size_to_send = 0; + status_resp.head_sdu_creation_time = 0; + status_resp.head_sdu_is_segmented = 0; status_resp.rlc_info.rlc_protocol_state = rlc->protocol_state; if (rlc->last_frame_status_indication != frame) { @@ -455,6 +461,30 @@ rlc_am_mac_status_indication (void *rlcP, u32 frame, u16 tb_sizeP, struct mac_st rlc->nb_bytes_requested_by_mac = tb_sizeP; status_resp.buffer_occupancy_in_bytes = rlc_am_get_buffer_occupancy_in_bytes(rlc,frame); + + if ((rlc->input_sdus[rlc->current_sdu_index].mem_block != NULL) && (status_resp.buffer_occupancy_in_bytes)) { + + //status_resp.buffer_occupancy_in_bytes += ((rlc_am_entity_t *) rlc)->tx_header_min_length_in_bytes; + status_resp.buffer_occupancy_in_pdus = rlc->nb_sdu; + diff_time = frame - ((rlc_am_tx_sdu_management_t *) (rlc->input_sdus[rlc->current_sdu_index].mem_block->data))->sdu_creation_time; + + status_resp.head_sdu_creation_time = (diff_time > 0 ) ? (u32_t) diff_time : (u32_t)(0xffffffff - diff_time + frame) ; + + sdu_size = ((rlc_am_tx_sdu_management_t *) (rlc->input_sdus[rlc->current_sdu_index].mem_block->data))->sdu_size; + sdu_remaining_size = ((rlc_am_tx_sdu_management_t *) (rlc->input_sdus[rlc->current_sdu_index].mem_block->data))->sdu_remaining_size; + + status_resp.head_sdu_remaining_size_to_send = sdu_remaining_size; + if (sdu_size == sdu_remaining_size) { + status_resp.head_sdu_is_segmented = 0; + } + else { + status_resp.head_sdu_is_segmented = 1; + } + + } else { + } + + #ifdef TRACE_RLC_AM_TX_STATUS if (tb_sizeP > 0) { LOG_D(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d] MAC_STATUS_INDICATION (DATA) %d bytes -> %d bytes\n", frame, rlc->module_id, rlc->rb_id, tb_sizeP, status_resp.buffer_occupancy_in_bytes); diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c index a62306b0eb8..ccd64dd5d53 100755 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c @@ -334,19 +334,46 @@ rlc_um_mac_status_indication (void *rlcP, u32_t frame, u8_t eNB_flag, u16_t tbs_ { //----------------------------------------------------------------------------- struct mac_status_resp status_resp; - - status_resp.buffer_occupancy_in_pdus = 0; - status_resp.buffer_occupancy_in_bytes = 0; - status_resp.rlc_info.rlc_protocol_state = ((rlc_um_entity_t *) rlcP)->protocol_state; + u16_t sdu_size = 0; + u16_t sdu_remaining_size = 0; + s32_t diff_time=0; + rlc_um_entity_t *rlc = NULL; + + status_resp.buffer_occupancy_in_pdus = 0; + status_resp.buffer_occupancy_in_bytes = 0; + status_resp.head_sdu_remaining_size_to_send = 0; + status_resp.head_sdu_creation_time = 0; + status_resp.head_sdu_is_segmented = 0; + status_resp.rlc_info.rlc_protocol_state = ((rlc_um_entity_t *) rlcP)->protocol_state; if (rlcP) { - rlc_um_check_timer_dar_time_out((rlc_um_entity_t *) rlcP,frame,eNB_flag); + rlc = (rlc_um_entity_t *) rlcP; + rlc_um_check_timer_dar_time_out(rlc,frame,eNB_flag); - ((rlc_um_entity_t *) rlcP)->nb_bytes_requested_by_mac = tbs_sizeP; + rlc->nb_bytes_requested_by_mac = tbs_sizeP; - status_resp.buffer_occupancy_in_bytes = rlc_um_get_buffer_occupancy ((rlc_um_entity_t *) rlcP); + status_resp.buffer_occupancy_in_bytes = rlc_um_get_buffer_occupancy (rlc); if (status_resp.buffer_occupancy_in_bytes > 0) { - status_resp.buffer_occupancy_in_bytes += ((rlc_um_entity_t *) rlcP)->tx_header_min_length_in_bytes; + + status_resp.buffer_occupancy_in_bytes += rlc->tx_header_min_length_in_bytes; + status_resp.buffer_occupancy_in_pdus = rlc->nb_sdu; + + diff_time = frame - ((struct rlc_um_tx_sdu_management *) (rlc->input_sdus[rlc->current_sdu_index])->data)->sdu_creation_time; + status_resp.head_sdu_creation_time = (diff_time > 0 ) ? (u32_t) diff_time : (u32_t)(0xffffffff - diff_time + frame) ; + //msg("rlc status for frame %d diff time %d resp %d\n", frame, diff_time,status_resp.head_sdu_creation_time) ; + + sdu_size = ((struct rlc_um_tx_sdu_management *) (rlc->input_sdus[rlc->current_sdu_index])->data)->sdu_size; + sdu_remaining_size = ((struct rlc_um_tx_sdu_management *) (rlc->input_sdus[rlc->current_sdu_index])->data)->sdu_remaining_size; + + status_resp.head_sdu_remaining_size_to_send = sdu_remaining_size; + if (sdu_size == sdu_remaining_size) { + status_resp.head_sdu_is_segmented = 0; + } + else { + status_resp.head_sdu_is_segmented = 1; + } + + } else { } //msg("[RLC_UM][MOD %d][RB %d][FRAME %05d] MAC_STATUS_INDICATION BO = %d\n", ((rlc_um_entity_t *) rlcP)->module_id, ((rlc_um_entity_t *) rlcP)->rb_id, status_resp.buffer_occupancy_in_bytes); @@ -465,8 +492,7 @@ rlc_um_data_req (void *rlcP, u32_t frame, mem_block_t *sduP) ((struct rlc_um_tx_sdu_management *) (sduP->data))->sdu_remaining_size = ((struct rlc_um_tx_sdu_management *) (sduP->data))->sdu_size; ((struct rlc_um_tx_sdu_management *) (sduP->data))->sdu_segmented_size = 0; - // LG ((struct rlc_um_tx_sdu_management *) (sduP->data))->sdu_creation_time = *rlc->frame_tick_milliseconds; - // LG ??? WHO WROTE THAT LINE ?((struct rlc_um_tx_sdu_management *) (sduP->data))->sdu_creation_time = 0; + ((struct rlc_um_tx_sdu_management *) (sduP->data))->sdu_creation_time = frame; rlc->next_sdu_index = (rlc->next_sdu_index + 1) % rlc->size_input_sdus_buffer; rlc->stat_tx_pdcp_sdu += 1; diff --git a/openair2/LAYER2/RLC/mac_primitives.h b/openair2/LAYER2/RLC/mac_primitives.h index 0cedf7440e0..4b54f8be968 100644 --- a/openair2/LAYER2/RLC/mac_primitives.h +++ b/openair2/LAYER2/RLC/mac_primitives.h @@ -172,7 +172,7 @@ struct mac_data_ind { //--------------------- struct mac_status_resp { u32_t buffer_occupancy_in_bytes; - u16_t buffer_occupancy_in_pdus; + u32_t buffer_occupancy_in_pdus; struct rlc_entity_info rlc_info; }; //--------------------- diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h index 85865e24392..aa35be6d794 100755 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -132,6 +132,9 @@ typedef volatile struct { typedef struct { u32_t bytes_in_buffer; /*!< \brief Bytes buffered in RLC protocol instance. */ u32_t pdus_in_buffer; /*!< \brief Number of PDUs buffered in RLC protocol instance (OBSOLETE). */ + u32_t head_sdu_creation_time; /*!< \brief Head SDU creation time. */ + u32_t head_sdu_remaining_size_to_send; /*!< \brief remaining size of sdu: could be the total size or the remaining size of already segmented sdu */ + u32_t head_sdu_is_segmented; /*!< \brief 0 if head SDU has not been segmented, 1 if already segmeneted */ } mac_rlc_status_resp_t; diff --git a/openair2/LAYER2/RLC/rlc_mac.c b/openair2/LAYER2/RLC/rlc_mac.c index 099a95c1d46..ba96a306a8d 100644 --- a/openair2/LAYER2/RLC/rlc_mac.c +++ b/openair2/LAYER2/RLC/rlc_mac.c @@ -215,7 +215,9 @@ mac_rlc_status_resp_t mac_rlc_status_ind (module_id_t module_idP, u32_t fram case RLC_AM: status_resp = rlc_am_mac_status_indication(&rlc[module_idP].m_rlc_am_array[rlc[module_idP].m_rlc_pointer[channel_idP].rlc_index], frame, tb_sizeP, tx_status); mac_rlc_status_resp.bytes_in_buffer = status_resp.buffer_occupancy_in_bytes; - mac_rlc_status_resp.pdus_in_buffer = status_resp.buffer_occupancy_in_pdus; + mac_rlc_status_resp.head_sdu_creation_time = status_resp.head_sdu_creation_time; + mac_rlc_status_resp.head_sdu_remaining_size_to_send = status_resp.head_sdu_remaining_size_to_send; + mac_rlc_status_resp.head_sdu_is_segmented = status_resp.head_sdu_is_segmented; return mac_rlc_status_resp; break; @@ -223,7 +225,10 @@ mac_rlc_status_resp_t mac_rlc_status_ind (module_id_t module_idP, u32_t fram //msg("[RLC_UM][MOD %d] mac_rlc_status_ind tb_size %d\n", module_idP, tb_sizeP); status_resp = rlc_um_mac_status_indication(&rlc[module_idP].m_rlc_um_array[rlc[module_idP].m_rlc_pointer[channel_idP].rlc_index], frame, eNB_flag, tb_sizeP, tx_status); mac_rlc_status_resp.bytes_in_buffer = status_resp.buffer_occupancy_in_bytes; - //mac_rlc_status_resp.pdus_in_buffer = status_resp.buffer_occupancy_in_pdus; + mac_rlc_status_resp.pdus_in_buffer = status_resp.buffer_occupancy_in_pdus; + mac_rlc_status_resp.head_sdu_creation_time = status_resp.head_sdu_creation_time; + mac_rlc_status_resp.head_sdu_remaining_size_to_send = status_resp.head_sdu_remaining_size_to_send; + mac_rlc_status_resp.head_sdu_is_segmented = status_resp.head_sdu_is_segmented; return mac_rlc_status_resp; break; diff --git a/targets/SIMU/USER/Makefile b/targets/SIMU/USER/Makefile index 35a7e9ffe8c..80532dbc61b 100644 --- a/targets/SIMU/USER/Makefile +++ b/targets/SIMU/USER/Makefile @@ -65,12 +65,14 @@ ifdef XFORMS CFLAGS += -DXFORMS endif +ifdef DB # Check if libmysqlclient is installed and use it if found to store simulation data for postprocessing ENABLE_DB = $(shell if [ `dpkg -l | grep libmysqlclient -c` = "0" ]; then echo "0" ; else echo "1" ; fi ) ifeq ($(ENABLE_DB), 1) CFLAGS +=-I/usr/include/mysql -L/usr/lib/mysql -DENABLE_DB_STATS DB_LDFLAGS = -lmysqlclient endif +endif ifdef PRINT_STATS CFLAGS += -DPRINT_STATS -- GitLab