restore ue compilation with ocp-softmodem, some RF simulator improvement
This commit is contained in:
@@ -616,7 +616,7 @@ void pusch_procedures_fromsplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *
|
||||
&ulsch_harq->Kminus,
|
||||
&ulsch_harq->F);
|
||||
ulsch_decoding_data(eNB, proc, i, harq_pid,
|
||||
ulsch_harq->nb_rb>20 ? 1 : 0);
|
||||
ulsch_harq->nb_rb>20 ? 1 : 0);
|
||||
stop_meas(&eNB->ulsch_decoding_stats);
|
||||
} // if ((ulsch) &&
|
||||
// (ulsch->rnti>0) &&
|
||||
@@ -634,6 +634,7 @@ void pusch_procedures_fromsplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *
|
||||
LOG_W (PHY, "Removing stale ULSCH config for UE %x harq_pid %d (harq_mask is now 0x%2.2x)\n", ulsch->rnti, harq_pid, ulsch->harq_mask);
|
||||
}
|
||||
} // for (i=0; i<NUMBER_OF_UE_MAX; i++)
|
||||
|
||||
while (proc->nbDecode > 0) {
|
||||
notifiedFIFO_elt_t *req=pullTpool(&proc->respDecode, &proc->threadPool);
|
||||
postDecode(proc, req);
|
||||
|
||||
@@ -672,11 +672,11 @@ void tx_rf(RU_t *ru, L1_rxtx_proc_t *proc) {
|
||||
/* add fail safe for late command end */
|
||||
// prepare tx buffer pointers
|
||||
ru->rfdevice.trx_write_func(&ru->rfdevice,
|
||||
proc->timestamp_tx+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension,
|
||||
txp,
|
||||
siglen+sf_extension,
|
||||
ru->nb_tx,
|
||||
flags);
|
||||
proc->timestamp_tx+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension,
|
||||
txp,
|
||||
siglen+sf_extension,
|
||||
ru->nb_tx,
|
||||
flags);
|
||||
LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, subframe %d\n",ru->idx,
|
||||
(long long unsigned int)proc->timestamp_tx,proc->frame_tx,proc->subframe_tx);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ enum pckType {
|
||||
};
|
||||
|
||||
// CU to DU definition of a future UL subframe decode
|
||||
// defines a UE future data plane
|
||||
// defines a UE future data plane
|
||||
typedef struct {
|
||||
enum pckType type:8;
|
||||
uint16_t UE_id;
|
||||
|
||||
@@ -103,7 +103,7 @@ typedef struct {
|
||||
/// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
|
||||
uint8_t e[MAX_NUM_CHANNEL_BITS] __attribute__((aligned(32)));
|
||||
/// Turbo-code outputs (36-212 V8.6 2009-03, p.12
|
||||
//uint8_t *d[MAX_NUM_DLSCH_SEGMENTS];//[(96+3+(3*6144))];
|
||||
uint8_t *d[MAX_NUM_DLSCH_SEGMENTS];//[(96+3+(3*6144))];
|
||||
/// Sub-block interleaver outputs (36-212 V8.6 2009-03, p.16-17)
|
||||
uint8_t w[MAX_NUM_DLSCH_SEGMENTS][3*6144];
|
||||
/// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9)
|
||||
|
||||
@@ -705,7 +705,7 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue,
|
||||
G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,beamforming_mode);
|
||||
|
||||
// if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet
|
||||
if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet
|
||||
if (dlsch->harq_processes[harq_pid]->DLround == 0) { // this is a new packet
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
printf("SIC encoding thinks this is a new packet \n");
|
||||
#endif
|
||||
|
||||
+366
-2
@@ -73,6 +73,217 @@
|
||||
|
||||
|
||||
|
||||
typedef struct RU_proc_t_s {
|
||||
/// Pointer to associated RU descriptor
|
||||
struct RU_t_s *ru;
|
||||
/// timestamp received from HW
|
||||
openair0_timestamp timestamp_rx;
|
||||
/// timestamp to send to "slave rru"
|
||||
openair0_timestamp timestamp_tx;
|
||||
/// subframe to act upon for reception
|
||||
int subframe_rx;
|
||||
/// subframe to act upon for transmission
|
||||
int subframe_tx;
|
||||
/// subframe to act upon for reception of prach
|
||||
int subframe_prach;
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
/// subframe to act upon for reception of prach BL/CE UEs
|
||||
int subframe_prach_br;
|
||||
#endif
|
||||
/// frame to act upon for reception
|
||||
int frame_rx;
|
||||
/// frame to act upon for transmission
|
||||
int frame_tx;
|
||||
/// unwrapped frame count
|
||||
int frame_tx_unwrap;
|
||||
/// frame to act upon for reception of prach
|
||||
int frame_prach;
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
/// frame to act upon for reception of prach
|
||||
int frame_prach_br;
|
||||
#endif
|
||||
/// frame offset for slave RUs (to correct for frame asynchronism at startup)
|
||||
int frame_offset;
|
||||
/// \brief Instance count for FH processing thread.
|
||||
/// \internal This variable is protected by \ref mutex_FH.
|
||||
int instance_cnt_FH;
|
||||
int instance_cnt_FH1;
|
||||
/// \internal This variable is protected by \ref mutex_prach.
|
||||
int instance_cnt_prach;
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
/// \internal This variable is protected by \ref mutex_prach.
|
||||
int instance_cnt_prach_br;
|
||||
#endif
|
||||
/// \internal This variable is protected by \ref mutex_synch.
|
||||
int instance_cnt_synch;
|
||||
/// \internal This variable is protected by \ref mutex_eNBs.
|
||||
int instance_cnt_eNBs;
|
||||
/// \brief Instance count for rx processing thread.
|
||||
/// \internal This variable is protected by \ref mutex_asynch_rxtx.
|
||||
int instance_cnt_asynch_rxtx;
|
||||
/// \internal This variable is protected by \ref mutex_fep
|
||||
int instance_cnt_fep;
|
||||
/// \internal This variable is protected by \ref mutex_feptx
|
||||
int instance_cnt_feptx;
|
||||
|
||||
/// \internal This variable is protected by \ref mutex_ru_thread
|
||||
int instance_cnt_ru;
|
||||
/// pthread structure for RU FH processing thread
|
||||
pthread_t pthread_FH;
|
||||
/// pthread structure for RU control thread
|
||||
pthread_t pthread_ctrl;
|
||||
|
||||
/// This varible is protected by \ref mutex_emulatedRF
|
||||
int instance_cnt_emulateRF;
|
||||
/// pthread structure for RU FH processing thread
|
||||
|
||||
pthread_t pthread_FH1;
|
||||
|
||||
/// pthread structure for RU prach processing thread
|
||||
pthread_t pthread_prach;
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
/// pthread structure for RU prach processing thread BL/CE UEs
|
||||
pthread_t pthread_prach_br;
|
||||
#endif
|
||||
/// pthread struct for RU synch thread
|
||||
pthread_t pthread_synch;
|
||||
/// pthread struct for RU RX FEP worker thread
|
||||
pthread_t pthread_fep;
|
||||
/// pthread struct for RU TX FEP worker thread
|
||||
pthread_t pthread_feptx;
|
||||
/// pthread struct for emulated RF
|
||||
pthread_t pthread_emulateRF;
|
||||
/// pthread structure for asychronous RX/TX processing thread
|
||||
pthread_t pthread_asynch_rxtx;
|
||||
/// flag to indicate first RX acquisition
|
||||
int first_rx;
|
||||
/// flag to indicate first TX transmission
|
||||
int first_tx;
|
||||
/// pthread attributes for RU FH processing thread
|
||||
pthread_attr_t attr_FH;
|
||||
|
||||
/// pthread attributes for RU control thread
|
||||
pthread_attr_t attr_ctrl;
|
||||
|
||||
pthread_attr_t attr_FH1;
|
||||
|
||||
/// pthread attributes for RU prach
|
||||
pthread_attr_t attr_prach;
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
/// pthread attributes for RU prach BL/CE UEs
|
||||
pthread_attr_t attr_prach_br;
|
||||
#endif
|
||||
/// pthread attributes for RU synch thread
|
||||
pthread_attr_t attr_synch;
|
||||
/// pthread attributes for asynchronous RX thread
|
||||
pthread_attr_t attr_asynch_rxtx;
|
||||
/// pthread attributes for worker fep thread
|
||||
pthread_attr_t attr_fep;
|
||||
/// pthread attributes for worker feptx thread
|
||||
pthread_attr_t attr_feptx;
|
||||
/// pthread attributes for emulated RF
|
||||
pthread_attr_t attr_emulateRF;
|
||||
/// scheduling parameters for RU FH thread
|
||||
struct sched_param sched_param_FH;
|
||||
struct sched_param sched_param_FH1;
|
||||
/// scheduling parameters for RU prach thread
|
||||
struct sched_param sched_param_prach;
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
/// scheduling parameters for RU prach thread BL/CE UEs
|
||||
struct sched_param sched_param_prach_br;
|
||||
#endif
|
||||
/// scheduling parameters for RU synch thread
|
||||
struct sched_param sched_param_synch;
|
||||
/// scheduling parameters for asynch_rxtx thread
|
||||
struct sched_param sched_param_asynch_rxtx;
|
||||
/// condition variable for RU FH thread
|
||||
pthread_cond_t cond_FH;
|
||||
pthread_cond_t cond_FH1;
|
||||
/// condition variable for RU prach thread
|
||||
pthread_cond_t cond_prach;
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
/// condition variable for RU prach thread BL/CE UEs
|
||||
pthread_cond_t cond_prach_br;
|
||||
#endif
|
||||
/// condition variable for RU synch thread
|
||||
pthread_cond_t cond_synch;
|
||||
/// condition variable for asynch RX/TX thread
|
||||
pthread_cond_t cond_asynch_rxtx;
|
||||
/// condition variable for RU RX FEP thread
|
||||
pthread_cond_t cond_fep;
|
||||
/// condition variable for RU TX FEP thread
|
||||
pthread_cond_t cond_feptx;
|
||||
/// condition variable for emulated RF
|
||||
pthread_cond_t cond_emulateRF;
|
||||
/// condition variable for eNB signal
|
||||
pthread_cond_t cond_eNBs;
|
||||
/// condition variable for ru_thread
|
||||
pthread_cond_t cond_ru_thread;
|
||||
/// mutex for RU FH
|
||||
pthread_mutex_t mutex_FH;
|
||||
pthread_mutex_t mutex_FH1;
|
||||
/// mutex for RU prach
|
||||
pthread_mutex_t mutex_prach;
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
/// mutex for RU prach BL/CE UEs
|
||||
pthread_mutex_t mutex_prach_br;
|
||||
#endif
|
||||
/// mutex for RU synch
|
||||
pthread_mutex_t mutex_synch;
|
||||
/// mutex for eNB signal
|
||||
pthread_mutex_t mutex_eNBs;
|
||||
/// mutex for asynch RX/TX thread
|
||||
pthread_mutex_t mutex_asynch_rxtx;
|
||||
/// mutex for fep RX worker thread
|
||||
pthread_mutex_t mutex_fep;
|
||||
/// mutex for fep TX worker thread
|
||||
pthread_mutex_t mutex_feptx;
|
||||
|
||||
/// mutex for ru_thread
|
||||
pthread_mutex_t mutex_ru;
|
||||
|
||||
/// mutex for emulated RF thread
|
||||
pthread_mutex_t mutex_emulateRF;
|
||||
|
||||
/// symbol mask for IF4p5 reception per subframe
|
||||
uint32_t symbol_mask[10];
|
||||
/// time measurements for each subframe
|
||||
struct timespec t[10];
|
||||
/// number of slave threads
|
||||
int num_slaves;
|
||||
/// array of pointers to slaves
|
||||
struct RU_proc_t_s **slave_proc;
|
||||
#ifdef PHY_TX_THREAD
|
||||
/// pthread structure for PRACH thread
|
||||
pthread_t pthread_phy_tx;
|
||||
pthread_mutex_t mutex_phy_tx;
|
||||
pthread_cond_t cond_phy_tx;
|
||||
/// \internal This variable is protected by \ref mutex_phy_tx.
|
||||
int instance_cnt_phy_tx;
|
||||
/// frame to act upon for transmission
|
||||
int frame_phy_tx;
|
||||
/// subframe to act upon for transmission
|
||||
int subframe_phy_tx;
|
||||
/// timestamp to send to "slave rru"
|
||||
openair0_timestamp timestamp_phy_tx;
|
||||
/// pthread structure for RF TX thread
|
||||
pthread_t pthread_rf_tx;
|
||||
pthread_mutex_t mutex_rf_tx;
|
||||
pthread_cond_t cond_rf_tx;
|
||||
/// \internal This variable is protected by \ref mutex_rf_tx.
|
||||
int instance_cnt_rf_tx;
|
||||
#endif
|
||||
#if defined(PRE_SCD_THREAD)
|
||||
pthread_t pthread_pre_scd;
|
||||
/// condition variable for time processing thread
|
||||
pthread_cond_t cond_pre_scd;
|
||||
/// mutex for time thread
|
||||
pthread_mutex_t mutex_pre_scd;
|
||||
int instance_pre_scd;
|
||||
#endif
|
||||
int emulate_rf_busy;
|
||||
} RU_proc_t;
|
||||
|
||||
typedef enum {
|
||||
LOCAL_RF =0,
|
||||
REMOTE_IF5 =1,
|
||||
@@ -257,7 +468,7 @@ typedef struct RU_t_s{
|
||||
/// value to be passed using command
|
||||
uint16_t cmdval;
|
||||
/// process scheduling variables
|
||||
//RU_proc_t proc;
|
||||
RU_proc_t proc;
|
||||
/// stats thread pthread descriptor
|
||||
pthread_t ru_stats_thread;
|
||||
/// OTA synchronization signal
|
||||
@@ -547,6 +758,159 @@ typedef struct {
|
||||
pthread_mutex_t mutex_te;
|
||||
} te_params;
|
||||
|
||||
/// Context data structure for eNB subframe processing
|
||||
typedef struct L1_proc_t_s {
|
||||
/// Component Carrier index
|
||||
uint8_t CC_id;
|
||||
/// thread index
|
||||
int thread_index;
|
||||
/// timestamp received from HW
|
||||
openair0_timestamp timestamp_rx;
|
||||
/// timestamp to send to "slave rru"
|
||||
openair0_timestamp timestamp_tx;
|
||||
/// subframe to act upon for reception
|
||||
int subframe_rx;
|
||||
/// subframe to act upon for PRACH
|
||||
int subframe_prach;
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
/// subframe to act upon for reception of prach BL/CE UEs
|
||||
int subframe_prach_br;
|
||||
#endif
|
||||
/// frame to act upon for reception
|
||||
int frame_rx;
|
||||
/// frame to act upon for transmission
|
||||
int frame_tx;
|
||||
/// frame to act upon for PRACH
|
||||
int frame_prach;
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
/// frame to act upon for PRACH BL/CE UEs
|
||||
int frame_prach_br;
|
||||
#endif
|
||||
/// \internal This variable is protected by \ref mutex_td.
|
||||
int instance_cnt_td;
|
||||
/// \internal This variable is protected by \ref mutex_te.
|
||||
int instance_cnt_te;
|
||||
/// \internal This variable is protected by \ref mutex_prach.
|
||||
int instance_cnt_prach;
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
/// \internal This variable is protected by \ref mutex_prach for BL/CE UEs.
|
||||
int instance_cnt_prach_br;
|
||||
#endif
|
||||
// instance count for over-the-air eNB synchronization
|
||||
int instance_cnt_synch;
|
||||
|
||||
|
||||
/// \internal This variable is protected by \ref mutex_asynch_rxtx.
|
||||
int instance_cnt_asynch_rxtx;
|
||||
/// pthread structure for asychronous RX/TX processing thread
|
||||
pthread_t pthread_asynch_rxtx;
|
||||
/// flag to indicate first RX acquisition
|
||||
int first_rx;
|
||||
/// flag to indicate first TX transmission
|
||||
int first_tx;
|
||||
/// pthread attributes for parallel turbo-decoder thread
|
||||
pthread_attr_t attr_td;
|
||||
/// pthread attributes for parallel turbo-encoder thread
|
||||
pthread_attr_t attr_te;
|
||||
/// pthread attributes for single eNB processing thread
|
||||
pthread_attr_t attr_single;
|
||||
/// pthread attributes for prach processing thread
|
||||
pthread_attr_t attr_prach;
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
/// pthread attributes for prach processing thread BL/CE UEs
|
||||
pthread_attr_t attr_prach_br;
|
||||
#endif
|
||||
/// pthread attributes for asynchronous RX thread
|
||||
pthread_attr_t attr_asynch_rxtx;
|
||||
/// scheduling parameters for parallel turbo-decoder thread
|
||||
struct sched_param sched_param_td;
|
||||
/// scheduling parameters for parallel turbo-encoder thread
|
||||
struct sched_param sched_param_te;
|
||||
/// scheduling parameters for single eNB thread
|
||||
struct sched_param sched_param_single;
|
||||
/// scheduling parameters for prach thread
|
||||
struct sched_param sched_param_prach;
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
/// scheduling parameters for prach thread
|
||||
struct sched_param sched_param_prach_br;
|
||||
#endif
|
||||
/// scheduling parameters for asynch_rxtx thread
|
||||
struct sched_param sched_param_asynch_rxtx;
|
||||
/// pthread structure for parallel turbo-decoder thread
|
||||
pthread_t pthread_td;
|
||||
/// pthread structure for parallel turbo-encoder thread
|
||||
pthread_t pthread_te;
|
||||
/// pthread structure for PRACH thread
|
||||
pthread_t pthread_prach;
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
/// pthread structure for PRACH thread BL/CE UEs
|
||||
pthread_t pthread_prach_br;
|
||||
#endif
|
||||
/// condition variable for parallel turbo-decoder thread
|
||||
pthread_cond_t cond_td;
|
||||
/// condition variable for parallel turbo-encoder thread
|
||||
pthread_cond_t cond_te;
|
||||
/// condition variable for PRACH processing thread;
|
||||
pthread_cond_t cond_prach;
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
/// condition variable for PRACH processing thread BL/CE UEs;
|
||||
pthread_cond_t cond_prach_br;
|
||||
#endif
|
||||
|
||||
/// condition variable for asynch RX/TX thread
|
||||
pthread_cond_t cond_asynch_rxtx;
|
||||
/// mutex for parallel turbo-decoder thread
|
||||
pthread_mutex_t mutex_td;
|
||||
/// mutex for parallel turbo-encoder thread
|
||||
pthread_mutex_t mutex_te;
|
||||
/// mutex for PRACH thread
|
||||
pthread_mutex_t mutex_prach;
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
/// mutex for PRACH thread for BL/CE UEs
|
||||
pthread_mutex_t mutex_prach_br;
|
||||
#endif
|
||||
/// mutex for asynch RX/TX thread
|
||||
pthread_mutex_t mutex_asynch_rxtx;
|
||||
/// mutex for RU access to eNB processing (PDSCH/PUSCH)
|
||||
pthread_mutex_t mutex_RU;
|
||||
/// mutex for eNB processing to access RU TX (PDSCH/PUSCH)
|
||||
pthread_mutex_t mutex_RU_tx;
|
||||
/// mutex for RU access to eNB processing (PRACH)
|
||||
pthread_mutex_t mutex_RU_PRACH;
|
||||
/// mutex for RU access to eNB processing (PRACH BR)
|
||||
pthread_mutex_t mutex_RU_PRACH_br;
|
||||
/// mask for RUs serving eNB (PDSCH/PUSCH)
|
||||
int RU_mask[10];
|
||||
/// mask for RUs serving eNB (PDSCH/PUSCH)
|
||||
int RU_mask_tx;
|
||||
/// time measurements for RU arrivals
|
||||
struct timespec t[10];
|
||||
/// Timing statistics (RU_arrivals)
|
||||
time_stats_t ru_arrival_time;
|
||||
/// mask for RUs serving eNB (PRACH)
|
||||
int RU_mask_prach;
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
/// mask for RUs serving eNB (PRACH)
|
||||
int RU_mask_prach_br;
|
||||
#endif
|
||||
/// parameters for turbo-decoding worker thread
|
||||
td_params tdp;
|
||||
/// parameters for turbo-encoding worker thread
|
||||
te_params tep[3];
|
||||
/// set of scheduling variables RXn-TXnp4 threads
|
||||
L1_rxtx_proc_t L1_proc,L1_proc_tx;
|
||||
/// stats thread pthread descriptor
|
||||
pthread_t process_stats_thread;
|
||||
/// for waking up tx procedure
|
||||
RU_proc_t *ru_proc;
|
||||
} L1_proc_t;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
//unsigned int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (linear)
|
||||
//unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (dB)
|
||||
@@ -608,7 +972,7 @@ typedef struct PHY_VARS_eNB_s {
|
||||
module_id_t Mod_id;
|
||||
uint8_t CC_id;
|
||||
uint8_t configured;
|
||||
//L1_proc_t proc;
|
||||
L1_proc_t proc;
|
||||
int single_thread_flag;
|
||||
int abstraction_flag;
|
||||
int num_RU;
|
||||
|
||||
@@ -1,668 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
mem_block.c - description
|
||||
-------------------
|
||||
AUTHOR : Lionel GAUTHIER
|
||||
COMPANY : EURECOM
|
||||
EMAIL : Lionel.Gauthier@eurecom.fr
|
||||
|
||||
|
||||
***************************************************************************/
|
||||
#define MEM_BLOCK_C
|
||||
//#include "rtos_header.h"
|
||||
#include "mem_block.h"
|
||||
#include "mem_pool.h"
|
||||
#include "list.h"
|
||||
#include "LAYER2/MAC/mac_extern.h"
|
||||
#include "assertions.h"
|
||||
/* all function calls are protected by a mutex
|
||||
* to ensure that many threads calling them at
|
||||
* the same time don't mess up.
|
||||
* We might be more clever in the future, it's a
|
||||
* bit overkill.
|
||||
* Commenting this define removes the protection,
|
||||
* so be careful with it.
|
||||
*/
|
||||
#define MEMBLOCK_BIG_LOCK
|
||||
|
||||
#ifdef MEMBLOCK_BIG_LOCK
|
||||
static pthread_mutex_t mtex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//#define DEBUG_MEM_MNGT_FREE
|
||||
//#define DEBUG_MEM_MNGT_ALLOC_SIZE
|
||||
//#define DEBUG_MEM_MNGT_ALLOC
|
||||
//-----------------------------------------------------------------------------
|
||||
#if defined(DEBUG_MEM_MNGT_ALLOC)
|
||||
uint32_t counters[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* initialize all ures
|
||||
*/
|
||||
extern mem_pool *memBlockVar;
|
||||
void *
|
||||
pool_buffer_init (void)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
uint32_t index, mb_index, pool_index;
|
||||
mem_pool *memory = (mem_pool *) &mem_block_var;
|
||||
memBlockVar=malloc(sizeof(mem_pool));
|
||||
int pool_sizes[14] = { MEM_MNGT_MB0_NB_BLOCKS, MEM_MNGT_MB1_NB_BLOCKS,
|
||||
MEM_MNGT_MB2_NB_BLOCKS, MEM_MNGT_MB3_NB_BLOCKS,
|
||||
MEM_MNGT_MB4_NB_BLOCKS, MEM_MNGT_MB5_NB_BLOCKS,
|
||||
MEM_MNGT_MB6_NB_BLOCKS, MEM_MNGT_MB7_NB_BLOCKS,
|
||||
MEM_MNGT_MB8_NB_BLOCKS, MEM_MNGT_MB9_NB_BLOCKS,
|
||||
MEM_MNGT_MB10_NB_BLOCKS, MEM_MNGT_MB11_NB_BLOCKS,
|
||||
MEM_MNGT_MB12_NB_BLOCKS, MEM_MNGT_MBCOPY_NB_BLOCKS
|
||||
};
|
||||
|
||||
#ifdef MEMBLOCK_BIG_LOCK
|
||||
if (pthread_mutex_lock(&mtex)) abort();
|
||||
#endif
|
||||
|
||||
memset (memory, 0, sizeof (mem_pool));
|
||||
mb_index = 0;
|
||||
|
||||
// LG_TEST
|
||||
for (pool_index = 0; pool_index <= MEM_MNGT_POOL_ID_COPY; pool_index++) {
|
||||
list_init (&memory->mem_lists[pool_index], "POOL");
|
||||
|
||||
for (index = 0; index < pool_sizes[pool_index]; index++) {
|
||||
//memory->mem_blocks[mb_index + index].previous = NULL; -> done in memset 0
|
||||
//memory->mem_blocks[mb_index + index].next = NULL; -> done in memset 0
|
||||
switch (pool_index) {
|
||||
case 0:
|
||||
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool0[index][0]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool1[index][0]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool2[index][0]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool3[index][0]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool4[index][0]);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool5[index][0]);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool6[index][0]);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool7[index][0]);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool8[index][0]);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool9[index][0]);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool10[index][0]);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool11[index][0]);
|
||||
break;
|
||||
|
||||
case 12:
|
||||
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool12[index][0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
memory->mem_blocks[mb_index + index].data = NULL; // pool copy
|
||||
|
||||
}
|
||||
|
||||
memory->mem_blocks[mb_index + index].pool_id = pool_index;
|
||||
list_add_tail_eurecom (&memory->mem_blocks[mb_index + index], &memory->mem_lists[pool_index]);
|
||||
}
|
||||
|
||||
mb_index += pool_sizes[pool_index];
|
||||
}
|
||||
|
||||
#ifdef MEMBLOCK_BIG_LOCK
|
||||
if (pthread_mutex_unlock(&mtex)) abort();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void *
|
||||
pool_buffer_clean (void *arg)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
return 0;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
free_mem_block (mem_block_t * leP, const char* caller)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
if (!(leP)) {
|
||||
LOG_W (RLC,"[MEM_MNGT][FREE] WARNING FREE NULL MEM_BLOCK\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MEMBLOCK_BIG_LOCK
|
||||
if (pthread_mutex_lock(&mtex)) abort();
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_MEM_MNGT_FREE
|
||||
LOG_D (RLC,"[MEM_MNGT][FREE] free_mem_block() %p pool: %d\n", leP, leP->pool_id);
|
||||
#endif
|
||||
#ifdef DEBUG_MEM_MNGT_ALLOC
|
||||
check_free_mem_block (leP);
|
||||
#endif
|
||||
|
||||
if (leP->pool_id <= MEM_MNGT_POOL_ID_COPY) {
|
||||
list_add_tail_eurecom (leP, &mem_block_var.mem_lists[leP->pool_id]);
|
||||
#ifdef DEBUG_MEM_MNGT_ALLOC
|
||||
counters[leP->pool_id] -= 1;
|
||||
LGO_D (RLC,"[%s][MEM_MNGT][INFO] after pool[%2d] freed: counters = {%2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d}\n",
|
||||
caller, leP->pool_id,
|
||||
counters[0],counters[1],counters[2],counters[3],counters[4],
|
||||
counters[5],counters[6],counters[7],counters[8],counters[9],
|
||||
counters[10],counters[11]);
|
||||
#endif
|
||||
leP = NULL; // this prevent from freeing the block twice
|
||||
} else {
|
||||
LOG_E (RLC,"[MEM_MNGT][FREE] ERROR free_mem_block() unknown pool_id : %d\n", leP->pool_id);
|
||||
}
|
||||
|
||||
#ifdef MEMBLOCK_BIG_LOCK
|
||||
if (pthread_mutex_unlock(&mtex)) abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
mem_block_t *
|
||||
get_free_mem_block (uint32_t sizeP, const char* caller)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
mem_block_t *le = NULL;
|
||||
int pool_selected;
|
||||
int size;
|
||||
|
||||
if (sizeP > MEM_MNGT_MB12_BLOCK_SIZE) {
|
||||
LOG_E (RLC,"[MEM_MNGT][ERROR][FATAL] size requested %d out of bounds\n", sizeP);
|
||||
display_mem_load ();
|
||||
AssertFatal(1==0,"get_free_mem_block size requested out of bounds");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef MEMBLOCK_BIG_LOCK
|
||||
if (pthread_mutex_lock(&mtex)) abort();
|
||||
#endif
|
||||
|
||||
size = sizeP >> 6;
|
||||
pool_selected = 0;
|
||||
|
||||
while ((size)) {
|
||||
pool_selected += 1;
|
||||
size = size >> 1;
|
||||
}
|
||||
|
||||
// pool is selected according to the size requested, now get a block
|
||||
// if no block is available pick one in an other pool
|
||||
do {
|
||||
if ((le = list_remove_head (&mem_block_var.mem_lists[pool_selected]))) {
|
||||
#ifdef DEBUG_MEM_MNGT_ALLOC
|
||||
counters[pool_selected] += 1;
|
||||
LOG_D (RLC,"[%s][MEM_MNGT][INFO] after pool[%2d] allocated: counters = {%2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d}\n",
|
||||
caller,
|
||||
pool_selected,
|
||||
counters[0],counters[1],counters[2],counters[3],counters[4],
|
||||
counters[5],counters[6],counters[7],counters[8],counters[9],
|
||||
counters[10],counters[11]);
|
||||
#endif
|
||||
#ifdef DEBUG_MEM_MNGT_ALLOC_SIZE
|
||||
LOG_D (RLC,"[MEM_MNGT][INFO] ALLOC MEM_BLOCK SIZE %d bytes pool %d (%p)\n", sizeP, pool_selected,le);
|
||||
#endif
|
||||
|
||||
AssertFatal(le->pool_id == pool_selected, "Unexpected pool ID!");
|
||||
|
||||
#ifdef MEMBLOCK_BIG_LOCK
|
||||
if (pthread_mutex_unlock(&mtex)) abort();
|
||||
#endif
|
||||
|
||||
return le;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MEM_MNGT_ALLOC
|
||||
LOG_E (RLC,"[MEM_MNGT][ERROR][MINOR] memory pool %d is empty trying next pool alloc count = %d\n", pool_selected, counters[pool_selected]);
|
||||
// display_mem_load ();
|
||||
// check_mem_area ((void *)&mem_block_var);
|
||||
#endif
|
||||
} while (pool_selected++ < 12);
|
||||
|
||||
LOG_E(PHY, "[MEM_MNGT][ERROR][FATAL] failed allocating MEM_BLOCK size %d byes (pool_selected=%d size=%d)\n", sizeP, pool_selected, size);
|
||||
// display_mem_load();
|
||||
// AssertFatal(1==0,"get_free_mem_block failed");
|
||||
LOG_E(MAC,"[MEM_MNGT][ERROR][FATAL] get_free_mem_block failed!!!\n");
|
||||
#ifdef MEMBLOCK_BIG_LOCK
|
||||
if (pthread_mutex_unlock(&mtex)) abort();
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
mem_block_t *
|
||||
get_free_copy_mem_block (void)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
mem_block_t *le;
|
||||
|
||||
#ifdef MEMBLOCK_BIG_LOCK
|
||||
AssertFatal(0, "This function is not handled properly but not used anywhere. FIXME?\n");
|
||||
#endif
|
||||
|
||||
if ((le = list_remove_head (&mem_block_var.mem_lists[MEM_MNGT_POOL_ID_COPY]))) {
|
||||
#ifdef DEBUG_MEM_MNGT_ALLOC_SIZE
|
||||
LOG_D (RLC,"[MEM_MNGT][INFO] ALLOC COPY MEM BLOCK (%p)\n",le);
|
||||
#endif
|
||||
#ifdef DEBUG_MEM_MNGT_ALLOC
|
||||
counters[MEM_MNGT_POOL_ID_COPY] += 1;
|
||||
LOG_D (RLC,"[MEM_MNGT][INFO] pool counters = {%2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d}\n",
|
||||
counters[0],counters[1],counters[2],counters[3],counters[4],
|
||||
counters[5],counters[6],counters[7],counters[8],counters[9],
|
||||
counters[10],counters[11]);
|
||||
#endif
|
||||
return le;
|
||||
} else {
|
||||
LOG_E (RLC,"[MEM_MNGT][ERROR] POOL COPY IS EMPTY\n");
|
||||
//#ifdef DEBUG_MEM_MNGT_ALLOC
|
||||
check_mem_area ();
|
||||
// break_point ();
|
||||
//#endif
|
||||
|
||||
AssertFatal(1==0,"mem pool is empty");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
mem_block_t *
|
||||
copy_mem_block (mem_block_t * leP, mem_block_t * destP)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef MEMBLOCK_BIG_LOCK
|
||||
AssertFatal(0, "This function is not handled properly but not used anywhere. FIXME?\n");
|
||||
#endif
|
||||
|
||||
if ((destP != NULL) && (leP != NULL) && (destP->pool_id == MEM_MNGT_POOL_ID_COPY)) {
|
||||
destP->data = leP->data;
|
||||
} else {
|
||||
LOG_E (RLC,"[MEM_MNGT][COPY] copy_mem_block() pool dest src or dest is NULL\n");
|
||||
}
|
||||
|
||||
return destP;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
display_mem_load (void)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef MEMBLOCK_BIG_LOCK
|
||||
/* this function does not need to be protected, do nothing */
|
||||
#endif
|
||||
|
||||
mem_pool *memory = (mem_pool *) &mem_block_var;
|
||||
|
||||
LOG_D (RLC,"POOL 0 (%d elements of %d Bytes): ", MEM_MNGT_MB0_NB_BLOCKS, MEM_MNGT_MB0_BLOCK_SIZE);
|
||||
list_display (&memory->mem_lists[MEM_MNGT_POOL_ID0]);
|
||||
LOG_D (RLC,"POOL 1 (%d elements of %d Bytes): ", MEM_MNGT_MB1_NB_BLOCKS, MEM_MNGT_MB1_BLOCK_SIZE);
|
||||
list_display (&memory->mem_lists[MEM_MNGT_POOL_ID1]);
|
||||
LOG_D (RLC,"POOL 2 (%d elements of %d Bytes): ", MEM_MNGT_MB2_NB_BLOCKS, MEM_MNGT_MB2_BLOCK_SIZE);
|
||||
list_display (&memory->mem_lists[MEM_MNGT_POOL_ID2]);
|
||||
LOG_D (RLC,"POOL 3 (%d elements of %d Bytes): ", MEM_MNGT_MB3_NB_BLOCKS, MEM_MNGT_MB3_BLOCK_SIZE);
|
||||
list_display (&memory->mem_lists[MEM_MNGT_POOL_ID3]);
|
||||
LOG_D (RLC,"POOL 4 (%d elements of %d Bytes): ", MEM_MNGT_MB4_NB_BLOCKS, MEM_MNGT_MB4_BLOCK_SIZE);
|
||||
list_display (&memory->mem_lists[MEM_MNGT_POOL_ID4]);
|
||||
LOG_D (RLC,"POOL 5 (%d elements of %d Bytes): ", MEM_MNGT_MB5_NB_BLOCKS, MEM_MNGT_MB5_BLOCK_SIZE);
|
||||
list_display (&memory->mem_lists[MEM_MNGT_POOL_ID5]);
|
||||
LOG_D (RLC,"POOL 6 (%d elements of %d Bytes): ", MEM_MNGT_MB6_NB_BLOCKS, MEM_MNGT_MB6_BLOCK_SIZE);
|
||||
list_display (&memory->mem_lists[MEM_MNGT_POOL_ID6]);
|
||||
LOG_D (RLC,"POOL 7 (%d elements of %d Bytes): ", MEM_MNGT_MB7_NB_BLOCKS, MEM_MNGT_MB7_BLOCK_SIZE);
|
||||
list_display (&memory->mem_lists[MEM_MNGT_POOL_ID7]);
|
||||
LOG_D (RLC,"POOL 8 (%d elements of %d Bytes): ", MEM_MNGT_MB8_NB_BLOCKS, MEM_MNGT_MB8_BLOCK_SIZE);
|
||||
list_display (&memory->mem_lists[MEM_MNGT_POOL_ID8]);
|
||||
LOG_D (RLC,"POOL 9 (%d elements of %d Bytes): ", MEM_MNGT_MB9_NB_BLOCKS, MEM_MNGT_MB9_BLOCK_SIZE);
|
||||
list_display (&memory->mem_lists[MEM_MNGT_POOL_ID9]);
|
||||
LOG_D (RLC,"POOL 10 (%d elements of %d Bytes): ", MEM_MNGT_MB10_NB_BLOCKS, MEM_MNGT_MB10_BLOCK_SIZE);
|
||||
list_display (&memory->mem_lists[MEM_MNGT_POOL_ID10]);
|
||||
LOG_D (RLC,"POOL 11 (%d elements of %d Bytes): ", MEM_MNGT_MB11_NB_BLOCKS, MEM_MNGT_MB11_BLOCK_SIZE);
|
||||
list_display (&memory->mem_lists[MEM_MNGT_POOL_ID11]);
|
||||
LOG_D (RLC,"POOL 12 (%d elements of %d Bytes): ", MEM_MNGT_MB12_NB_BLOCKS, MEM_MNGT_MB12_BLOCK_SIZE);
|
||||
list_display (&memory->mem_lists[MEM_MNGT_POOL_ID12]);
|
||||
LOG_D (RLC,"POOL C (%d elements): ", MEM_MNGT_MBCOPY_NB_BLOCKS);
|
||||
list_display (&memory->mem_lists[MEM_MNGT_POOL_ID_COPY]);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
check_mem_area (void)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
int index, mb_index;
|
||||
mem_pool *memory = (mem_pool *) &mem_block_var;
|
||||
|
||||
#ifdef MEMBLOCK_BIG_LOCK
|
||||
AssertFatal(0, "This function is not handled properly but not used anywhere. FIXME?\n");
|
||||
#endif
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB0_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[index].data != (unsigned char*)&(memory->mem_pool0[index][0])) && (memory->mem_blocks[index].pool_id != MEM_MNGT_POOL_ID0)) {
|
||||
LOG_D (RLC,"[MEM] ERROR POOL0 block index %d\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
mb_index = MEM_MNGT_MB0_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB1_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool1[index][0]))
|
||||
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID1)) {
|
||||
LOG_D (RLC,"[MEM] ERROR POOL1 block index %d\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB1_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB2_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool2[index][0]))
|
||||
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID2)) {
|
||||
LOG_D (RLC,"[MEM] ERROR POOL2 block index %d\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB2_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB3_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool3[index][0]))
|
||||
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID3)) {
|
||||
LOG_D (RLC,"[MEM] ERROR POOL3 block index %d\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB3_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB4_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool4[index][0]))
|
||||
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID4)) {
|
||||
LOG_D (RLC,"[MEM] ERROR POOL4 block index %d\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB4_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB5_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool5[index][0]))
|
||||
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID5)) {
|
||||
LOG_D (RLC,"[MEM] ERROR POOL5 block index %d\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB5_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB6_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool6[index][0]))
|
||||
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID6)) {
|
||||
LOG_D (RLC,"[MEM] ERROR POOL6 block index %d\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB6_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB7_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool7[index][0]))
|
||||
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID7)) {
|
||||
LOG_D (RLC,"[MEM] ERROR POOL7 block index %d\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB7_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB8_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool8[index][0]))
|
||||
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID8)) {
|
||||
LOG_D (RLC,"[MEM] ERROR POOL8 block index %d\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB8_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB9_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool9[index][0]))
|
||||
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID9)) {
|
||||
LOG_D (RLC,"[MEM] ERROR POOL9 block index %d\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB9_NB_BLOCKS;
|
||||
|
||||
for (index = mb_index; index < MEM_MNGT_MB10_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool10[index][0]))
|
||||
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID10)) {
|
||||
LOG_D (RLC,"[MEM] ERROR POOL10 block index %d\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB10_NB_BLOCKS;
|
||||
|
||||
for (index = mb_index; index < MEM_MNGT_MB11_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool11[index][0]))
|
||||
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID11)) {
|
||||
LOG_D (RLC,"[MEM] ERROR POOL11 block index %d\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB11_NB_BLOCKS;
|
||||
|
||||
for (index = mb_index; index < MEM_MNGT_MB12_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool12[index][0]))
|
||||
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID12)) {
|
||||
LOG_D (RLC,"[MEM] ERROR POOL12 block index %d\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB12_NB_BLOCKS;
|
||||
|
||||
for (index = mb_index; index < MEM_MNGT_NB_ELEMENTS; index++) {
|
||||
if ((memory->mem_blocks[index].data != NULL) && (memory->mem_blocks[index].pool_id != MEM_MNGT_POOL_ID_COPY)) {
|
||||
LOG_D (RLC,"[MEM] ERROR POOL COPY block index %d\n", index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
check_free_mem_block (mem_block_t * leP)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
ptrdiff_t block_index;
|
||||
|
||||
#ifdef MEMBLOCK_BIG_LOCK
|
||||
/* this function does not SEEM TO need to be protected, do nothing (for the moment) */
|
||||
#endif
|
||||
|
||||
if ((leP >= mem_block_var.mem_blocks) && (leP <= &mem_block_var.mem_blocks[MEM_MNGT_NB_ELEMENTS-1])) {
|
||||
// the pointer is inside the memory region
|
||||
block_index = leP - mem_block_var.mem_blocks;
|
||||
// block_index is now: 0 <= block_index < MEM_MNGT_NB_ELEMENTS
|
||||
|
||||
if (block_index < MEM_MNGT_MB0_NB_BLOCKS) {
|
||||
if ((leP->data != (unsigned char*)mem_block_var.mem_pool0[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID0)) {
|
||||
LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
block_index -= MEM_MNGT_MB0_NB_BLOCKS;
|
||||
|
||||
if (block_index < MEM_MNGT_MB1_NB_BLOCKS) {
|
||||
if ((leP->data != (unsigned char*)mem_block_var.mem_pool1[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID1)) {
|
||||
LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
block_index -= MEM_MNGT_MB1_NB_BLOCKS;
|
||||
|
||||
if (block_index < MEM_MNGT_MB2_NB_BLOCKS) {
|
||||
if ((leP->data != (unsigned char*)mem_block_var.mem_pool2[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID2)) {
|
||||
LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
block_index -= MEM_MNGT_MB2_NB_BLOCKS;
|
||||
|
||||
if (block_index < MEM_MNGT_MB3_NB_BLOCKS) {
|
||||
if ((leP->data != (unsigned char*)mem_block_var.mem_pool3[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID3)) {
|
||||
LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
block_index -= MEM_MNGT_MB3_NB_BLOCKS;
|
||||
|
||||
if (block_index < MEM_MNGT_MB4_NB_BLOCKS) {
|
||||
if ((leP->data != (unsigned char*)mem_block_var.mem_pool4[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID4)) {
|
||||
LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
block_index -= MEM_MNGT_MB4_NB_BLOCKS;
|
||||
|
||||
if (block_index < MEM_MNGT_MB5_NB_BLOCKS) {
|
||||
if ((leP->data != (unsigned char*)mem_block_var.mem_pool5[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID5)) {
|
||||
LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
block_index -= MEM_MNGT_MB5_NB_BLOCKS;
|
||||
|
||||
if (block_index < MEM_MNGT_MB6_NB_BLOCKS) {
|
||||
if ((leP->data != (unsigned char*)mem_block_var.mem_pool6[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID6)) {
|
||||
LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
block_index -= MEM_MNGT_MB6_NB_BLOCKS;
|
||||
|
||||
if (block_index < MEM_MNGT_MB7_NB_BLOCKS) {
|
||||
if ((leP->data != (unsigned char*)mem_block_var.mem_pool7[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID7)) {
|
||||
LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
block_index -= MEM_MNGT_MB7_NB_BLOCKS;
|
||||
|
||||
if (block_index < MEM_MNGT_MB8_NB_BLOCKS) {
|
||||
if ((leP->data != (unsigned char*)mem_block_var.mem_pool8[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID8)) {
|
||||
LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
block_index -= MEM_MNGT_MB8_NB_BLOCKS;
|
||||
|
||||
if (block_index < MEM_MNGT_MB9_NB_BLOCKS) {
|
||||
if ((leP->data != (unsigned char*)mem_block_var.mem_pool9[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID9)) {
|
||||
LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
block_index -= MEM_MNGT_MB9_NB_BLOCKS;
|
||||
|
||||
if (block_index < MEM_MNGT_MB10_NB_BLOCKS) {
|
||||
if ((leP->data != (unsigned char*)mem_block_var.mem_pool10[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID10)) {
|
||||
LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
block_index -= MEM_MNGT_MB10_NB_BLOCKS;
|
||||
|
||||
if (block_index < MEM_MNGT_MB11_NB_BLOCKS) {
|
||||
if ((leP->data != (unsigned char*)mem_block_var.mem_pool11[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID11)) {
|
||||
LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
block_index -= MEM_MNGT_MB11_NB_BLOCKS;
|
||||
|
||||
if (block_index < MEM_MNGT_MB12_NB_BLOCKS) {
|
||||
if ((leP->data != (unsigned char*)mem_block_var.mem_pool12[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID12)) {
|
||||
LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
|
||||
// the block is ok
|
||||
}
|
||||
@@ -57,91 +57,8 @@ mem_block_t *get_free_copy_mem_block (void);
|
||||
mem_block_t *get_free_copy_mem_block_up (void);
|
||||
mem_block_t *copy_mem_block (mem_block_t * leP, mem_block_t * destP);
|
||||
void display_mem_load (void);
|
||||
|
||||
void check_mem_area (void);
|
||||
void check_free_mem_block (mem_block_t * leP);
|
||||
# define MEM_SCALE MAX_MOBILES_PER_ENB
|
||||
// definition of the size of the allocated memory area
|
||||
# define MEM_MNGT_MB0_BLOCK_SIZE 64
|
||||
// 64
|
||||
# define MEM_MNGT_MB0_NB_BLOCKS 4096 * MEM_SCALE
|
||||
# define MEM_MNGT_POOL_ID0 0
|
||||
|
||||
# define MEM_MNGT_MB1_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*2
|
||||
// 128
|
||||
# define MEM_MNGT_MB1_NB_BLOCKS 4096 * MEM_SCALE
|
||||
# define MEM_MNGT_POOL_ID1 1
|
||||
|
||||
# define MEM_MNGT_MB2_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*4
|
||||
// 256
|
||||
# define MEM_MNGT_MB2_NB_BLOCKS 2048 * MEM_SCALE
|
||||
# define MEM_MNGT_POOL_ID2 2
|
||||
|
||||
# define MEM_MNGT_MB3_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*8
|
||||
// 512
|
||||
# define MEM_MNGT_MB3_NB_BLOCKS 2048 * MEM_SCALE
|
||||
# define MEM_MNGT_POOL_ID3 3
|
||||
|
||||
# define MEM_MNGT_MB4_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*16
|
||||
// 1024
|
||||
# define MEM_MNGT_MB4_NB_BLOCKS 1024 * MEM_SCALE
|
||||
# define MEM_MNGT_POOL_ID4 4
|
||||
|
||||
# define MEM_MNGT_MB5_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*32
|
||||
// 2048
|
||||
# define MEM_MNGT_MB5_NB_BLOCKS 1024 * MEM_SCALE // LG WAS 1024
|
||||
# define MEM_MNGT_POOL_ID5 5
|
||||
|
||||
# define MEM_MNGT_MB6_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*64
|
||||
// 4096
|
||||
# define MEM_MNGT_MB6_NB_BLOCKS 1024 * MEM_SCALE // LG WAS 256
|
||||
# define MEM_MNGT_POOL_ID6 6
|
||||
|
||||
# define MEM_MNGT_MB7_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*128
|
||||
// 8192
|
||||
# define MEM_MNGT_MB7_NB_BLOCKS 64* MEM_SCALE // LG WAS 32
|
||||
# define MEM_MNGT_POOL_ID7 7
|
||||
|
||||
# define MEM_MNGT_MB8_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*256
|
||||
|
||||
#ifdef JUMBO_FRAMES
|
||||
# define MEM_MNGT_MB8_NB_BLOCKS 256 * MEM_SCALE
|
||||
#else
|
||||
# define MEM_MNGT_MB8_NB_BLOCKS 16 * MEM_SCALE
|
||||
// 16384
|
||||
#endif
|
||||
# define MEM_MNGT_POOL_ID8 8
|
||||
|
||||
# define MEM_MNGT_MB9_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*512
|
||||
// 32768
|
||||
# define MEM_MNGT_MB9_NB_BLOCKS 8 * MEM_SCALE
|
||||
# define MEM_MNGT_POOL_ID9 9
|
||||
|
||||
# define MEM_MNGT_MB10_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*1024
|
||||
// 65536
|
||||
# define MEM_MNGT_MB10_NB_BLOCKS 0 * MEM_SCALE
|
||||
# define MEM_MNGT_POOL_ID10 10
|
||||
|
||||
# define MEM_MNGT_MB11_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*2048
|
||||
// 131072
|
||||
# define MEM_MNGT_MB11_NB_BLOCKS 0 * MEM_SCALE
|
||||
# define MEM_MNGT_POOL_ID11 11
|
||||
|
||||
# define MEM_MNGT_MB12_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*4096
|
||||
// 262144
|
||||
# define MEM_MNGT_MB12_NB_BLOCKS 32 * MEM_SCALE
|
||||
//# define MEM_MNGT_MB12_NB_BLOCKS 4096 * MEM_SCALE
|
||||
|
||||
# define MEM_MNGT_POOL_ID12 12
|
||||
|
||||
|
||||
# define MEM_MNGT_MBCOPY_NB_BLOCKS 1024
|
||||
# define MEM_MNGT_NB_ELEMENTS MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS + MEM_MNGT_MB6_NB_BLOCKS + MEM_MNGT_MB7_NB_BLOCKS + MEM_MNGT_MB8_NB_BLOCKS + MEM_MNGT_MB9_NB_BLOCKS + MEM_MNGT_MB10_NB_BLOCKS + MEM_MNGT_MB11_NB_BLOCKS + MEM_MNGT_MB12_NB_BLOCKS + MEM_MNGT_MBCOPY_NB_BLOCKS
|
||||
# define MEM_MNGT_POOL_ID_COPY 13
|
||||
|
||||
#define LIST_NAME_MAX_CHAR 32
|
||||
|
||||
|
||||
typedef struct {
|
||||
struct mem_block_t *head;
|
||||
struct mem_block_t *tail;
|
||||
@@ -156,33 +73,6 @@ typedef struct {
|
||||
char name[LIST_NAME_MAX_CHAR];
|
||||
} list_t;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
//-----------------------------------------------------------
|
||||
// basic memory management
|
||||
//-----------------------------------------------------------
|
||||
char mem_pool0[MEM_MNGT_MB0_NB_BLOCKS][MEM_MNGT_MB0_BLOCK_SIZE];
|
||||
char mem_pool1[MEM_MNGT_MB1_NB_BLOCKS][MEM_MNGT_MB1_BLOCK_SIZE];
|
||||
char mem_pool2[MEM_MNGT_MB2_NB_BLOCKS][MEM_MNGT_MB2_BLOCK_SIZE];
|
||||
char mem_pool3[MEM_MNGT_MB3_NB_BLOCKS][MEM_MNGT_MB3_BLOCK_SIZE];
|
||||
char mem_pool4[MEM_MNGT_MB4_NB_BLOCKS][MEM_MNGT_MB4_BLOCK_SIZE];
|
||||
char mem_pool5[MEM_MNGT_MB5_NB_BLOCKS][MEM_MNGT_MB5_BLOCK_SIZE];
|
||||
char mem_pool6[MEM_MNGT_MB6_NB_BLOCKS][MEM_MNGT_MB6_BLOCK_SIZE];
|
||||
char mem_pool7[MEM_MNGT_MB7_NB_BLOCKS][MEM_MNGT_MB7_BLOCK_SIZE];
|
||||
char mem_pool8[MEM_MNGT_MB8_NB_BLOCKS][MEM_MNGT_MB8_BLOCK_SIZE];
|
||||
char mem_pool9[MEM_MNGT_MB9_NB_BLOCKS][MEM_MNGT_MB9_BLOCK_SIZE];
|
||||
char mem_pool10[MEM_MNGT_MB10_NB_BLOCKS][MEM_MNGT_MB10_BLOCK_SIZE];
|
||||
char mem_pool11[MEM_MNGT_MB11_NB_BLOCKS][MEM_MNGT_MB11_BLOCK_SIZE];
|
||||
char mem_pool12[MEM_MNGT_MB12_NB_BLOCKS][MEM_MNGT_MB12_BLOCK_SIZE];
|
||||
mem_block_t mem_blocks[MEM_MNGT_NB_ELEMENTS];
|
||||
list_t mem_lists[14];
|
||||
|
||||
} mem_pool;
|
||||
|
||||
mem_pool *memBlockVar;
|
||||
#define mem_block_var (*memBlockVar)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,489 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
mem_mngt.c - description
|
||||
-------------------
|
||||
AUTHOR : Lionel GAUTHIER
|
||||
COMPANY : EURECOM
|
||||
EMAIL : Lionel.Gauthier@eurecom.fr
|
||||
|
||||
|
||||
***************************************************************************/
|
||||
#define MEM_MNGT_C
|
||||
#include "rtos_header.h"
|
||||
#include "platform.h"
|
||||
#include "protocol_vars_extern.h"
|
||||
#include "print.h"
|
||||
|
||||
#include "mem_block.h"
|
||||
#include "mem_pool.h"
|
||||
#include "lists_proto_extern.h"
|
||||
#include "umts_sched.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
#define DEBUG_MEM_MNGT_FREE
|
||||
#define DEBUG_MEM_MNGT_ALLOC_SIZE
|
||||
#define DEBUG_MEM_MNGT_ALLOC
|
||||
#ifdef DEBUG_MEM_MNGT_ADDR
|
||||
# define PRINT_MEM_MNGT_ADDR msg
|
||||
#else
|
||||
# define PRINT_MEM_MNGT_ADDR
|
||||
//
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
uint32_t counters[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* initialize all ures
|
||||
*/
|
||||
void *
|
||||
pool_buffer_init (void *arg)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
uint32_t index, mb_index, pool_index;
|
||||
mem_pool *memory = (mem_pool *) arg;
|
||||
int pool_sizes[11] = { MEM_MNGT_MB0_NB_BLOCKS, MEM_MNGT_MB1_NB_BLOCKS,
|
||||
MEM_MNGT_MB2_NB_BLOCKS, MEM_MNGT_MB3_NB_BLOCKS,
|
||||
MEM_MNGT_MB4_NB_BLOCKS, MEM_MNGT_MB5_NB_BLOCKS,
|
||||
MEM_MNGT_MB6_NB_BLOCKS, MEM_MNGT_MB7_NB_BLOCKS,
|
||||
MEM_MNGT_MB8_NB_BLOCKS, MEM_MNGT_MB9_NB_BLOCKS,
|
||||
MEM_MNGT_MBCOPY_NB_BLOCKS
|
||||
};
|
||||
|
||||
memset (memory, 0, sizeof (mem_pool));
|
||||
mb_index = 0;
|
||||
|
||||
// LG_TEST
|
||||
for (pool_index = 0; pool_index <= MEM_MNGT_POOL_ID_COPY; pool_index++) {
|
||||
init_list (&memory->mem_lists[pool_index], "POOL");
|
||||
|
||||
for (index = 0; index < pool_sizes[pool_index]; index++) {
|
||||
//memory->mem_blocks[mb_index + index].previous = NULL; -> done in memset 0
|
||||
//memory->mem_blocks[mb_index + index].next = NULL; -> done in memset 0
|
||||
switch (pool_index) {
|
||||
case 0:
|
||||
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool0[index][0]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool1[index][0]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool2[index][0]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool3[index][0]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool4[index][0]);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool5[index][0]);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool6[index][0]);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool7[index][0]);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool8[index][0]);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool9[index][0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
memory->mem_blocks[mb_index + index].data = NULL; // pool copy
|
||||
|
||||
}
|
||||
|
||||
memory->mem_blocks[mb_index + index].pool_id = pool_index;
|
||||
add_tail (&memory->mem_blocks[mb_index + index], &memory->mem_lists[pool_index]);
|
||||
}
|
||||
|
||||
mb_index += pool_sizes[pool_index];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void *
|
||||
pool_buffer_clean (void *arg)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef NO_THREAD_SAFE
|
||||
mem_pool *memory = (mem_pool *) arg;
|
||||
pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID0].mutex);
|
||||
pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID1].mutex);
|
||||
pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID2].mutex);
|
||||
pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID3].mutex);
|
||||
pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID4].mutex);
|
||||
pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID5].mutex);
|
||||
pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID6].mutex);
|
||||
pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID7].mutex);
|
||||
pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID8].mutex);
|
||||
pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID9].mutex);
|
||||
pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID_COPY].mutex);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
free_mem_block (mem_block_t * leP, __func__)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
if (!(leP)) {
|
||||
msg ("[MEM_MNGT][FREE] WARNING FREE NULL MEM_BLOCK\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MEM_MNGT_FREE
|
||||
msg ("[MEM_MNGT][FREE] free_mem_block() %p pool: %d\n", leP, leP->pool_id, __func__);
|
||||
#endif
|
||||
#ifdef DEBUG_MEM_MNGT_ALLOC
|
||||
check_free_mem_block (leP, __func__);
|
||||
#endif
|
||||
|
||||
if (leP->pool_id <= MEM_MNGT_POOL_ID_COPY) {
|
||||
add_tail (leP, &mem->mem_lists[leP->pool_id]);
|
||||
#ifdef DEBUG_MEM_MNGT_ALLOC
|
||||
counters[leP->pool_id] -= 1;
|
||||
#endif
|
||||
leP = NULL; // this prevent from freeing the block twice
|
||||
} else {
|
||||
msg ("[MEM_MNGT][FREE] ERROR free_mem_block() unknown pool_id : %d\n", leP->pool_id, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
mem_block_t *
|
||||
get_free_mem_block (uint16_t sizeP, __func__)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
mem_block_t *le = NULL;
|
||||
int pool_selected;
|
||||
int size;
|
||||
|
||||
if (sizeP > MEM_MNGT_MB9_BLOCK_SIZE) {
|
||||
msg ("[MEM_MNGT][ERROR][FATAL] size requested %d out of bounds %d\n",sizeP,MEM_MNGT_MB9_BLOCK_SIZE);
|
||||
wcdma_handle_error (WCDMA_ERROR_OUT_OF_MEM_BLOCK);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = sizeP >> 6;
|
||||
pool_selected = 0;
|
||||
|
||||
while ((size)) {
|
||||
pool_selected += 1;
|
||||
size = size >> 1;
|
||||
}
|
||||
|
||||
// pool is selected according to the size requested, now get a block
|
||||
// if no block is available pick one in an other pool
|
||||
do {
|
||||
if ((le = remove_head (&mem->mem_lists[pool_selected]))) {
|
||||
#ifdef DEBUG_MEM_MNGT_ALLOC
|
||||
counters[pool_selected] += 1;
|
||||
#endif
|
||||
#ifdef DEBUG_MEM_MNGT_ALLOC_SIZE
|
||||
msg ("[MEM_MNGT][INFO] ALLOC MEM_BLOCK SIZE %d bytes pool %d\n", sizeP, pool_selected);
|
||||
#endif
|
||||
return le;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MEM_MNGT_ALLOC
|
||||
msg ("[MEM_MNGT][ERROR][MINOR] memory pool %d is empty trying next pool alloc count = %d\n", pool_selected, counters[pool_selected]);
|
||||
display_mem_load ();
|
||||
check_mem_area (mem);
|
||||
#endif
|
||||
} while (pool_selected++ < 9);
|
||||
|
||||
msg ("[MEM_MNGT][ERROR][FATAL] size %d requested out of bounds or memory pools empty\n", sizeP);
|
||||
wcdma_handle_error (WCDMA_ERROR_OUT_OF_MEM_BLOCK);
|
||||
return NULL;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
mem_block_t *
|
||||
get_free_copy_mem_block (void)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
mem_block_t *le;
|
||||
|
||||
if ((le = remove_head (&mem->mem_lists[MEM_MNGT_POOL_ID_COPY]))) {
|
||||
return le;
|
||||
} else {
|
||||
msg ("[MEM_MNGT][ERROR] POOL COPY IS EMPTY\n");
|
||||
display_mem_load ();
|
||||
#ifdef DEBUG_MEM_MNGT_ALLOC
|
||||
check_mem_area (mem);
|
||||
break_point ();
|
||||
#endif
|
||||
wcdma_handle_error (WCDMA_ERROR_OUT_OF_MEM_BLOCK);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
mem_block_t *
|
||||
copy_mem_block (mem_block_t * leP, mem_block_t * destP)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
if ((destP != NULL) && (leP != NULL) && (destP->pool_id == MEM_MNGT_POOL_ID_COPY)) {
|
||||
destP->data = leP->data;
|
||||
} else {
|
||||
msg ("[MEM_MNGT][COPY] copy_mem_block() pool dest src or dest is NULL\n");
|
||||
}
|
||||
|
||||
return destP;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
display_mem_load (void)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
msg ("POOL 0 (%d elements of %d Bytes): \n", MEM_MNGT_MB0_NB_BLOCKS, MEM_MNGT_MB0_BLOCK_SIZE);
|
||||
display_list (&mem->mem_lists[MEM_MNGT_POOL_ID0]);
|
||||
msg ("POOL 1 (%d elements of %d Bytes): \n", MEM_MNGT_MB1_NB_BLOCKS, MEM_MNGT_MB1_BLOCK_SIZE);
|
||||
display_list (&mem->mem_lists[MEM_MNGT_POOL_ID1]);
|
||||
msg ("POOL 2 (%d elements of %d Bytes): \n", MEM_MNGT_MB2_NB_BLOCKS, MEM_MNGT_MB2_BLOCK_SIZE);
|
||||
display_list (&mem->mem_lists[MEM_MNGT_POOL_ID2]);
|
||||
msg ("POOL 3 (%d elements of %d Bytes): \n", MEM_MNGT_MB3_NB_BLOCKS, MEM_MNGT_MB3_BLOCK_SIZE);
|
||||
display_list (&mem->mem_lists[MEM_MNGT_POOL_ID3]);
|
||||
msg ("POOL 4 (%d elements of %d Bytes): \n", MEM_MNGT_MB4_NB_BLOCKS, MEM_MNGT_MB4_BLOCK_SIZE);
|
||||
display_list (&mem->mem_lists[MEM_MNGT_POOL_ID4]);
|
||||
msg ("POOL 5 (%d elements of %d Bytes): \n", MEM_MNGT_MB5_NB_BLOCKS, MEM_MNGT_MB5_BLOCK_SIZE);
|
||||
display_list (&mem->mem_lists[MEM_MNGT_POOL_ID5]);
|
||||
msg ("POOL 6 (%d elements of %d Bytes): \n", MEM_MNGT_MB6_NB_BLOCKS, MEM_MNGT_MB6_BLOCK_SIZE);
|
||||
display_list (&mem->mem_lists[MEM_MNGT_POOL_ID6]);
|
||||
msg ("POOL 7 (%d elements of %d Bytes): \n", MEM_MNGT_MB7_NB_BLOCKS, MEM_MNGT_MB7_BLOCK_SIZE);
|
||||
display_list (&mem->mem_lists[MEM_MNGT_POOL_ID7]);
|
||||
msg ("POOL 8 (%d elements of %d Bytes): \n", MEM_MNGT_MB8_NB_BLOCKS, MEM_MNGT_MB8_BLOCK_SIZE);
|
||||
display_list (&mem->mem_lists[MEM_MNGT_POOL_ID8]);
|
||||
msg ("POOL 9 (%d elements of %d Bytes): \n", MEM_MNGT_MB9_NB_BLOCKS, MEM_MNGT_MB9_BLOCK_SIZE);
|
||||
display_list (&mem->mem_lists[MEM_MNGT_POOL_ID9]);
|
||||
msg ("POOL C (%d elements): \n", MEM_MNGT_MBCOPY_NB_BLOCKS);
|
||||
display_list (&mem->mem_lists[MEM_MNGT_POOL_ID_COPY]);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
check_mem_area (void *arg)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
int index, mb_index;
|
||||
mem_pool *memory = (mem_pool *) arg;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB0_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[index].data != &(memory->mem_pool0[index][0])) && (memory->mem_blocks[index].pool_id != MEM_MNGT_POOL_ID0)) {
|
||||
msg ("[MEM] ERROR POOL0 block index %d\n", index);
|
||||
break_point ();
|
||||
}
|
||||
}
|
||||
|
||||
mb_index = MEM_MNGT_MB0_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB1_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool1[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID1)) {
|
||||
msg ("[MEM] ERROR POOL1 block index %d\n", index);
|
||||
break_point ();
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB1_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB2_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool2[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID2)) {
|
||||
msg ("[MEM] ERROR POOL2 block index %d\n", index);
|
||||
break_point ();
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB2_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB3_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool3[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID3)) {
|
||||
msg ("[MEM] ERROR POOL3 block index %d\n", index);
|
||||
break_point ();
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB3_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB4_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool4[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID4)) {
|
||||
msg ("[MEM] ERROR POOL4 block index %d\n", index);
|
||||
break_point ();
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB4_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB5_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool5[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID5)) {
|
||||
msg ("[MEM] ERROR POOL5 block index %d\n", index);
|
||||
break_point ();
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB5_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB6_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool6[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID6)) {
|
||||
msg ("[MEM] ERROR POOL6 block index %d\n", index);
|
||||
break_point ();
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB6_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB7_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool7[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID7)) {
|
||||
msg ("[MEM] ERROR POOL7 block index %d\n", index);
|
||||
break_point ();
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB7_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB8_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool8[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID8)) {
|
||||
msg ("[MEM] ERROR POOL8 block index %d\n", index);
|
||||
break_point ();
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB8_NB_BLOCKS;
|
||||
|
||||
for (index = 0; index < MEM_MNGT_MB9_NB_BLOCKS; index++) {
|
||||
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool9[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID9)) {
|
||||
msg ("[MEM] ERROR POOL9 block index %d\n", index);
|
||||
break_point ();
|
||||
}
|
||||
}
|
||||
|
||||
mb_index += MEM_MNGT_MB9_NB_BLOCKS;
|
||||
|
||||
for (index = mb_index; index < MEM_MNGT_NB_ELEMENTS; index++) {
|
||||
if ((memory->mem_blocks[index].data != NULL) && (memory->mem_blocks[index].pool_id != MEM_MNGT_POOL_ID_COPY)) {
|
||||
msg ("[MEM] ERROR POOL COPY block index %d\n", index);
|
||||
break_point ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
check_free_mem_block (mem_block_t * leP, __func__)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
int block_index;
|
||||
|
||||
if ((leP >= &mem->mem_blocks[0]) && (leP <= &mem->mem_blocks[MEM_MNGT_NB_ELEMENTS])) {
|
||||
block_index = ((uint32_t) leP - (uint32_t) (&mem->mem_blocks[0])) / sizeof (mem_block_t);
|
||||
|
||||
if (block_index < MEM_MNGT_MB0_NB_BLOCKS) {
|
||||
if (((uint32_t) (leP->data) != (uint32_t) (&(mem->mem_pool0[block_index][0]))) && (leP->pool_id != MEM_MNGT_POOL_ID0)) {
|
||||
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
} else if (block_index < (MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS)) {
|
||||
if ((leP->data != &(mem->mem_pool1[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID1)) {
|
||||
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
} else if (block_index < MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS) {
|
||||
if ((leP->data != &(mem->mem_pool2[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID2)) {
|
||||
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
} else if (block_index < MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS) {
|
||||
if ((leP->data != &(mem->mem_pool3[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID3)) {
|
||||
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
} else if (block_index < MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS) {
|
||||
if ((leP->data != &(mem->mem_pool4[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID4)) {
|
||||
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
} else if (block_index < MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS +
|
||||
MEM_MNGT_MB5_NB_BLOCKS) {
|
||||
if ((leP->data != &(mem->mem_pool5[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID5)) {
|
||||
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
} else if (block_index <
|
||||
MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS +
|
||||
MEM_MNGT_MB6_NB_BLOCKS) {
|
||||
if ((leP->data != &(mem->mem_pool6[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID6)) {
|
||||
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
} else if (block_index <
|
||||
MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS +
|
||||
MEM_MNGT_MB6_NB_BLOCKS +
|
||||
MEM_MNGT_MB7_NB_BLOCKS) {
|
||||
if ((leP->data != &(mem->mem_pool7[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID7)) {
|
||||
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
} else if (block_index <
|
||||
MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS +
|
||||
MEM_MNGT_MB6_NB_BLOCKS +
|
||||
MEM_MNGT_MB7_NB_BLOCKS + MEM_MNGT_MB8_NB_BLOCKS) {
|
||||
if ((leP->data != &(mem->mem_pool8[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID8)) {
|
||||
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
} else if (block_index <
|
||||
MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS +
|
||||
MEM_MNGT_MB6_NB_BLOCKS +
|
||||
MEM_MNGT_MB7_NB_BLOCKS + MEM_MNGT_MB8_NB_BLOCKS + MEM_MNGT_MB9_NB_BLOCKS) {
|
||||
if ((leP->data != &(mem->mem_pool9[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID9)) {
|
||||
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
break_point (void)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
int break_var;
|
||||
|
||||
msg ("[BREAK_POINT]\n");
|
||||
break_var = 1;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
mem_pool.h - description
|
||||
-------------------
|
||||
AUTHOR : Lionel GAUTHIER
|
||||
COMPANY : EURECOM
|
||||
EMAIL : Lionel.Gauthier@eurecom.fr
|
||||
|
||||
|
||||
***************************************************************************/
|
||||
#ifndef __MEM_POOL_H__
|
||||
# define __MEM_POOL_H__
|
||||
|
||||
# include "list.h"
|
||||
# include "mem_block.h"
|
||||
|
||||
|
||||
#endif
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <openair1/SIMULATION/TOOLS/sim.h>
|
||||
|
||||
#define PORT 4043 //default TCP port for this simulator
|
||||
#define CirSize 3072000 // 100ms is enough
|
||||
#define CirSize 307200 // 100ms is enough
|
||||
#define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t))
|
||||
#define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b)))
|
||||
|
||||
@@ -106,7 +106,7 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
|
||||
ptr->headerMode=true;
|
||||
ptr->transferPtr=(char *)&ptr->th;
|
||||
ptr->remainToTransfer=sizeof(samplesBlockHeader_t);
|
||||
int sendbuff=1000*1000*10;
|
||||
int sendbuff=1000*1000*100;
|
||||
AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == 0, "");
|
||||
struct epoll_event ev= {0};
|
||||
ev.events = EPOLLIN | EPOLLRDHUP;
|
||||
@@ -183,7 +183,7 @@ void setblocking(int sock, enum blocking_t active) {
|
||||
AssertFatal(fcntl(sock, F_SETFL, opts) >= 0, "");
|
||||
}
|
||||
|
||||
static bool flushInput(rfsimulator_state_t *t, int timeout);
|
||||
static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps);
|
||||
|
||||
void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) {
|
||||
if (t->saveIQfile != -1) {
|
||||
@@ -207,7 +207,8 @@ void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) {
|
||||
if(errno==EAGAIN) {
|
||||
// The opposite side is saturated
|
||||
// we read incoming sockets meawhile waiting
|
||||
flushInput(t, 5);
|
||||
//flushInput(t, 5);
|
||||
usleep(500);
|
||||
continue;
|
||||
} else
|
||||
return;
|
||||
@@ -316,17 +317,19 @@ sin_addr:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) {
|
||||
rfsimulator_state_t *t = device->priv;
|
||||
static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) {
|
||||
LOG_D(HW,"sending %d samples at time: %ld\n", nsamps, timestamp);
|
||||
|
||||
for (int i=0; i<FD_SETSIZE; i++) {
|
||||
buffer_t *b=&t->buf[i];
|
||||
|
||||
if (b->conn_sock >= 0 ) {
|
||||
if ( abs((double)b->lastWroteTS-timestamp) > (double)CirSize)
|
||||
LOG_E(HW,"Tx/Rx shift too large Tx:%lu, Rx:%lu\n", b->lastWroteTS, b->lastReceivedTS);
|
||||
pthread_mutex_lock(&Sockmutex);
|
||||
|
||||
if ( b->lastWroteTS != 0 && abs((double)b->lastWroteTS-timestamp) > (double)CirSize)
|
||||
LOG_E(HW,"Discontinuous TX gap too large Tx:%lu, %lu\n", b->lastWroteTS, timestamp);
|
||||
|
||||
AssertFatal(b->lastWroteTS <= timestamp+1, " Not supported to send Tx out of order (same in USRP) %lu, %lu\n", b->lastWroteTS, timestamp);
|
||||
samplesBlockHeader_t header= {t->typeStamp, nsamps, nbAnt, timestamp};
|
||||
fullwrite(b->conn_sock,&header, sizeof(header), t);
|
||||
sample_t tmpSamples[nsamps][nbAnt];
|
||||
@@ -342,19 +345,23 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi
|
||||
fullwrite(b->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t);
|
||||
b->lastWroteTS=timestamp+nsamps;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&Sockmutex);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n",
|
||||
nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) );
|
||||
// Let's verify we don't have incoming data
|
||||
// This is mandatory when the opposite side don't transmit
|
||||
flushInput(t, 0);
|
||||
pthread_mutex_unlock(&Sockmutex);
|
||||
return nsamps;
|
||||
}
|
||||
|
||||
static bool flushInput(rfsimulator_state_t *t, int timeout) {
|
||||
int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) {
|
||||
return rfsimulator_write_internal(device->priv, timestamp, samplesVoid, nsamps, nbAnt, flags);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initial) {
|
||||
// Process all incoming events on sockets
|
||||
// store the data in lists
|
||||
struct epoll_event events[FD_SETSIZE]= {0};
|
||||
@@ -375,7 +382,29 @@ static bool flushInput(rfsimulator_state_t *t, int timeout) {
|
||||
AssertFatal( (conn_sock = accept(t->listen_sock,NULL,NULL)) != -1, "");
|
||||
setblocking(conn_sock, notBlocking);
|
||||
allocCirBuf(t, conn_sock);
|
||||
LOG_I(HW,"A ue connected\n");
|
||||
LOG_I(HW,"A ue connected, sending the current time\n");
|
||||
struct complex16 v= {0};
|
||||
void *samplesVoid[t->tx_num_channels];
|
||||
|
||||
for ( int i=0; i < t->tx_num_channels; i++)
|
||||
samplesVoid[i]=(void *)&v;
|
||||
|
||||
pthread_mutex_lock(&Sockmutex);
|
||||
openair0_timestamp timestamp=1;
|
||||
|
||||
for (int i=0; i<FD_SETSIZE; i++) {
|
||||
buffer_t *b=&t->buf[i];
|
||||
|
||||
if (t->buf[i].circularBuf != NULL && t->buf[i].lastWroteTS > 1) {
|
||||
timestamp=b->lastWroteTS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&Sockmutex);
|
||||
rfsimulator_write_internal(t, timestamp-1,
|
||||
samplesVoid, 1,
|
||||
t->tx_num_channels, 1);
|
||||
} else {
|
||||
if ( events[nbEv].events & (EPOLLHUP | EPOLLERR | EPOLLRDHUP) ) {
|
||||
socketError(t,fd);
|
||||
@@ -432,26 +461,34 @@ static bool flushInput(rfsimulator_state_t *t, int timeout) {
|
||||
}
|
||||
|
||||
if ( abs(b->th.timestamp-b->lastReceivedTS) > 50 )
|
||||
LOG_W(HW,"gap of: %ld in reception\n", b->th.timestamp-b->lastReceivedTS );
|
||||
LOG_W(HW,"UEsock: %d gap of: %ld in reception\n", fd, b->th.timestamp-b->lastReceivedTS );
|
||||
}
|
||||
|
||||
b->lastReceivedTS=b->th.timestamp;
|
||||
AssertFatal(b->lastWroteTS == 0 || ( abs((double)b->lastWroteTS-b->lastReceivedTS) < (double)CirSize),
|
||||
"Tx/Rx shift too large Tx:%lu, Rx:%lu\n", b->lastWroteTS, b->lastReceivedTS);
|
||||
pthread_mutex_lock(&Sockmutex);
|
||||
|
||||
if (b->lastWroteTS != 0 && ( abs((double)b->lastWroteTS-b->lastReceivedTS) > (double)CirSize))
|
||||
LOG_E(HW,"UEsock: %d Tx/Rx shift too large Tx:%lu, Rx:%lu\n", fd, b->lastWroteTS, b->lastReceivedTS);
|
||||
|
||||
pthread_mutex_unlock(&Sockmutex);
|
||||
b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize];
|
||||
b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt);
|
||||
}
|
||||
|
||||
if ( b->headerMode==false ) {
|
||||
LOG_D(HW,"Set b->lastReceivedTS %ld\n", b->lastReceivedTS);
|
||||
LOG_D(HW,"UEsock: %d Set b->lastReceivedTS %ld\n", fd, b->lastReceivedTS);
|
||||
b->lastReceivedTS=b->th.timestamp+b->th.size-byteToSample(b->remainToTransfer,b->th.nbAnt);
|
||||
|
||||
// First block in UE, resync with the eNB current TS
|
||||
if ( t->nextTimestamp == 0 )
|
||||
t->nextTimestamp=b->lastReceivedTS-b->th.size;
|
||||
if ( t->nextTimestamp == 0 && b->th.size < b->lastReceivedTS) {
|
||||
t->nextTimestamp=b->lastReceivedTS > nsamps_for_initial ?
|
||||
b->lastReceivedTS - nsamps_for_initial :
|
||||
0;
|
||||
LOG_W(HW,"UE got first timestamp: starting at %lu\n", t->nextTimestamp);
|
||||
}
|
||||
|
||||
if ( b->remainToTransfer==0) {
|
||||
LOG_D(HW,"Completed block reception: %ld\n", b->lastReceivedTS);
|
||||
LOG_D(HW,"UEsock: %d Completed block reception: %ld\n", fd, b->lastReceivedTS);
|
||||
b->headerMode=true;
|
||||
b->transferPtr=(char *)&b->th;
|
||||
b->remainToTransfer=sizeof(samplesBlockHeader_t);
|
||||
@@ -469,7 +506,6 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
LOG_W(HW, "rfsimulator: only 1 antenna tested\n");
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&Sockmutex);
|
||||
rfsimulator_state_t *t = device->priv;
|
||||
LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps);
|
||||
// deliver data from received data
|
||||
@@ -485,7 +521,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
if ( t->nextTimestamp == 0)
|
||||
LOG_W(HW,"No connected device, generating void samples...\n");
|
||||
|
||||
if (!flushInput(t, 10)) {
|
||||
if (!flushInput(t, 10, nsamps)) {
|
||||
for (int x=0; x < nbAnt; x++)
|
||||
memset(samplesVoid[x],0,sampleToByte(nsamps,1));
|
||||
|
||||
@@ -495,7 +531,6 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
LOG_W(HW,"Generated void samples for Rx: %ld\n", t->nextTimestamp);
|
||||
|
||||
*ptimestamp = t->nextTimestamp-nsamps;
|
||||
pthread_mutex_unlock(&Sockmutex);
|
||||
return nsamps;
|
||||
}
|
||||
} else {
|
||||
@@ -507,26 +542,6 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
for ( int sock=0; sock<FD_SETSIZE; sock++) {
|
||||
buffer_t *b=&t->buf[sock];
|
||||
|
||||
if ( b->circularBuf) {
|
||||
LOG_D(HW,"sock: %d, lastWroteTS: %lu, lastRecvTS: %lu, TS must be avail: %lu\n",
|
||||
sock, b->lastWroteTS,
|
||||
b->lastReceivedTS,
|
||||
t->nextTimestamp+nsamps);
|
||||
|
||||
if ( b->lastReceivedTS > b->lastWroteTS ) {
|
||||
// The caller momdem (NB, UE, ...) must send Tx in advance, so we fill TX if Rx is in advance
|
||||
// This occurs for example when UE is in sync mode: it doesn't transmit
|
||||
// with USRP, it seems ok: if "tx stream" is off, we may consider it actually cuts the Tx power
|
||||
struct complex16 v= {0};
|
||||
void *samplesVoid[b->th.nbAnt];
|
||||
|
||||
for ( int i=0; i <b->th.nbAnt; i++)
|
||||
samplesVoid[i]=(void *)&v;
|
||||
|
||||
rfsimulator_write(device, b->lastReceivedTS, samplesVoid, 1, b->th.nbAnt, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if ( b->circularBuf )
|
||||
if ( t->nextTimestamp+nsamps > b->lastReceivedTS ) {
|
||||
have_to_wait=true;
|
||||
@@ -539,7 +554,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
ptr->lastReceivedTS,
|
||||
t->nextTimestamp+nsamps);
|
||||
*/
|
||||
flushInput(t, 3);
|
||||
flushInput(t, 3, nsamps);
|
||||
} while (have_to_wait);
|
||||
}
|
||||
|
||||
@@ -586,7 +601,6 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
nsamps,
|
||||
*ptimestamp, t->nextTimestamp,
|
||||
signal_energy(samplesVoid[0], nsamps));
|
||||
pthread_mutex_unlock(&Sockmutex);
|
||||
return nsamps;
|
||||
}
|
||||
int rfsimulator_request(openair0_device *device, void *msg, ssize_t msg_len) {
|
||||
|
||||
@@ -264,7 +264,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name
|
||||
eNB->UL_INFO.subframe = proc->subframe_rx;
|
||||
eNB->UL_INFO.module_id = eNB->Mod_id;
|
||||
eNB->UL_INFO.CC_id = eNB->CC_id;
|
||||
eNB->if_inst->UL_indication(&eNB->UL_INFO);
|
||||
eNB->if_inst->UL_indication(&eNB->UL_INFO, proc);
|
||||
AssertFatal((ret= pthread_mutex_unlock(&eNB->UL_INFO_mutex))==0,"error unlocking UL_INFO_mutex, return %d\n",ret);
|
||||
|
||||
/* this conflict resolution may be totally wrong, to be tested */
|
||||
@@ -762,7 +762,7 @@ static void *eNB_thread_prach( void *param ) {
|
||||
if (oai_exit) break;
|
||||
|
||||
LOG_D(PHY,"Running eNB prach procedures\n");
|
||||
prach_procedures(eNB
|
||||
prach_procedures(eNB, &eNB->proc.L1_proc
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
,0
|
||||
#endif
|
||||
@@ -796,7 +796,7 @@ static void *eNB_thread_prach_br( void *param ) {
|
||||
if (oai_exit) break;
|
||||
|
||||
LOG_D(PHY,"Running eNB prach procedures for BL/CE UEs\n");
|
||||
prach_procedures(eNB,1);
|
||||
prach_procedures(eNB, &eNB->proc.L1_proc,1);
|
||||
|
||||
if (release_thread(&proc->mutex_prach_br,&proc->instance_cnt_prach_br,"eNB_prach_thread_br") < 0) break;
|
||||
}
|
||||
@@ -810,11 +810,6 @@ static void *eNB_thread_prach_br( void *param ) {
|
||||
|
||||
|
||||
|
||||
extern void init_td_thread(PHY_VARS_eNB *);
|
||||
extern void init_te_thread(PHY_VARS_eNB *);
|
||||
extern void kill_td_thread(PHY_VARS_eNB *);
|
||||
extern void kill_te_thread(PHY_VARS_eNB *);
|
||||
|
||||
static void *process_stats_thread(void *param) {
|
||||
PHY_VARS_eNB *eNB = (PHY_VARS_eNB *)param;
|
||||
wait_sync("process_stats_thread");
|
||||
@@ -919,12 +914,12 @@ void init_eNB_proc(int inst) {
|
||||
// attr_td = &proc->attr_td;
|
||||
// attr_te = &proc->attr_te;
|
||||
#endif
|
||||
|
||||
/*
|
||||
if(get_thread_worker_conf() == WORKER_ENABLE) {
|
||||
init_te_thread(eNB);
|
||||
init_td_thread(eNB);
|
||||
}
|
||||
|
||||
*/
|
||||
LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag);
|
||||
|
||||
if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) && NFAPI_MODE!=NFAPI_MODE_VNF) {
|
||||
@@ -990,12 +985,12 @@ void kill_eNB_proc(int inst) {
|
||||
proc = &eNB->proc;
|
||||
L1_proc = &proc->L1_proc;
|
||||
L1_proc_tx = &proc->L1_proc_tx;
|
||||
|
||||
/*
|
||||
if(get_thread_worker_conf() == WORKER_ENABLE) {
|
||||
kill_td_thread(eNB);
|
||||
kill_te_thread(eNB);
|
||||
}
|
||||
|
||||
*/
|
||||
LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst );
|
||||
|
||||
if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && NFAPI_MODE!=NFAPI_MODE_VNF) {
|
||||
|
||||
+25
-22
@@ -176,7 +176,7 @@ static inline void fh_if4p5_south_out(RU_t *ru) {
|
||||
void fh_if5_south_in(RU_t *ru,int *frame, int *subframe) {
|
||||
LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
recv_IF5(ru, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL);
|
||||
recv_IF5(ru, &ru->eNB_list[0]->proc.L1_proc, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL);
|
||||
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
|
||||
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
|
||||
|
||||
@@ -391,7 +391,7 @@ void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *subframe) {
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
int subframe_tx,frame_tx;
|
||||
openair0_timestamp timestamp_tx;
|
||||
recv_IF5(ru, ×tamp_tx, *subframe, IF5_RRH_GW_DL);
|
||||
recv_IF5(ru,&ru->eNB_list[0]->proc.L1_proc, ×tamp_tx, *subframe, IF5_RRH_GW_DL);
|
||||
// printf("Received subframe %d (TS %llu) from RCC\n",subframe_tx,timestamp_tx);
|
||||
subframe_tx = (timestamp_tx/fp->samples_per_tti)%10;
|
||||
frame_tx = (timestamp_tx/(fp->samples_per_tti*10))&1023;
|
||||
@@ -482,9 +482,9 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_IF4P5_NORTH_ASYNCH_IN,subframe_tx);
|
||||
}
|
||||
|
||||
if (ru->feptx_ofdm) ru->feptx_ofdm(ru);
|
||||
if (ru->feptx_ofdm) ru->feptx_ofdm(ru, &ru->eNB_list[0]->proc.L1_proc );
|
||||
|
||||
if (ru->fh_south_out) ru->fh_south_out(ru);
|
||||
if (ru->fh_south_out) ru->fh_south_out(ru , &ru->eNB_list[0]->proc.L1_proc);
|
||||
}
|
||||
|
||||
void fh_if5_north_out(RU_t *ru) {
|
||||
@@ -931,12 +931,14 @@ void *ru_thread_prach( void *param ) {
|
||||
if (ru->eNB_list[0]) {
|
||||
prach_procedures(
|
||||
ru->eNB_list[0]
|
||||
, &ru->eNB_list[0]->proc.L1_proc
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
,0
|
||||
#endif
|
||||
);
|
||||
} else {
|
||||
rx_prach(NULL,
|
||||
&ru->eNB_list[0]->proc.L1_proc,
|
||||
ru,
|
||||
NULL,
|
||||
NULL,
|
||||
@@ -976,6 +978,7 @@ void *ru_thread_prach_br( void *param ) {
|
||||
if (oai_exit) break;
|
||||
|
||||
rx_prach(NULL,
|
||||
&ru->eNB_list[0]->proc.L1_proc,
|
||||
ru,
|
||||
NULL,
|
||||
NULL,
|
||||
@@ -1176,7 +1179,7 @@ void wakeup_L1s(RU_t *ru) {
|
||||
|
||||
if (ru->wait_cnt == 0) {
|
||||
if (ru->num_eNB==1 && ru->eNB_top!=0 && get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD)
|
||||
ru->eNB_top(eNB_list[0],proc->frame_rx,proc->subframe_rx,string,ru);
|
||||
ru->eNB_top(eNB_list[0],&proc->L1_proc, proc->frame_rx,proc->subframe_rx,string,ru);
|
||||
else {
|
||||
for (i=0; i<ru->num_eNB; i++) {
|
||||
eNB_list[i]->proc.ru_proc = &ru->proc;
|
||||
@@ -1493,14 +1496,14 @@ void *ru_thread_tx( void *param ) {
|
||||
if (oai_exit) break;
|
||||
|
||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru);
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru, L1_proc);
|
||||
|
||||
// do OFDM if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru, L1_proc);
|
||||
|
||||
if(!(get_softmodem_params()->emulate_rf)) {
|
||||
// do outgoing fronthaul (south) if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru, L1_proc);
|
||||
}
|
||||
|
||||
LOG_D(PHY,"ru_thread_tx: releasing RU TX in %d.%d\n",proc->frame_tx,proc->subframe_tx);
|
||||
@@ -1765,7 +1768,7 @@ void *ru_thread( void *param ) {
|
||||
wakeup_slaves(proc);
|
||||
|
||||
// do RX front-end processing (frequency-shift, dft) if needed
|
||||
if (ru->feprx) ru->feprx(ru);
|
||||
if (ru->feprx) ru->feprx(ru, &ru->eNB_list[0]->proc.L1_proc);
|
||||
|
||||
// wakeup all eNB processes waiting for this RU
|
||||
AssertFatal((ret=pthread_mutex_lock(&proc->mutex_eNBs))==0,"mutex_lock returns %d\n",ret);
|
||||
@@ -1801,14 +1804,14 @@ void *ru_thread( void *param ) {
|
||||
|
||||
if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_eNB==0) {
|
||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru);
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru, &ru->eNB_list[0]->proc.L1_proc);
|
||||
|
||||
// do OFDM if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru, &ru->eNB_list[0]->proc.L1_proc);
|
||||
|
||||
if(!(get_softmodem_params()->emulate_rf)) {
|
||||
// do outgoing fronthaul (south) if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru, &ru->eNB_list[0]->proc.L1_proc);
|
||||
|
||||
if ((ru->fh_north_out) && (ru->state!=RU_CHECK_SYNC)) ru->fh_north_out(ru);
|
||||
}
|
||||
@@ -2240,12 +2243,12 @@ void init_RU_proc(RU_t *ru) {
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (get_thread_worker_conf() == WORKER_ENABLE) {
|
||||
init_fep_thread(ru,NULL);
|
||||
init_feptx_thread(ru,NULL);
|
||||
}
|
||||
|
||||
*/
|
||||
if (opp_enabled == 1) pthread_create(&ru->ru_stats_thread,NULL,ru_stats_thread,(void *)ru);
|
||||
|
||||
if (ru->function == eNodeB_3GPP) {
|
||||
@@ -2286,14 +2289,14 @@ void kill_RU_proc(RU_t *ru) {
|
||||
pthread_mutex_destroy( &proc->mutex_rf_tx);
|
||||
pthread_cond_destroy( &proc->cond_rf_tx);
|
||||
#endif
|
||||
|
||||
/*
|
||||
if (get_thread_worker_conf() == WORKER_ENABLE) {
|
||||
LOG_D(PHY, "killing FEP thread\n");
|
||||
kill_fep_thread(ru);
|
||||
LOG_D(PHY, "killing FEP TX thread\n");
|
||||
kill_feptx_thread(ru);
|
||||
}
|
||||
|
||||
*/
|
||||
AssertFatal((ret=pthread_mutex_lock(&proc->mutex_FH))==0,"mutex_lock returns %d\n",ret);
|
||||
proc->instance_cnt_FH = 0;
|
||||
pthread_cond_signal(&proc->cond_FH);
|
||||
@@ -2453,8 +2456,8 @@ void set_function_spec_param(RU_t *ru) {
|
||||
ru->fh_north_out = fh_if4p5_north_out; // send_IF4p5 on reception
|
||||
ru->fh_south_out = tx_rf; // send output to RF
|
||||
ru->fh_north_asynch_in = fh_if4p5_north_asynch_in; // TX packets come asynchronously
|
||||
ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full :ru_fep_full_2thread; // RX DFTs
|
||||
ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft only (no precoding in RRU)
|
||||
ru->feprx = fep_full; // RX DFTs
|
||||
ru->feptx_ofdm = feptx_ofdm; // this is fep with idft only (no precoding in RRU)
|
||||
ru->feptx_prec = NULL;
|
||||
ru->start_if = start_if; // need to start the if interface for if4p5
|
||||
ru->ifdevice.host_type = RRU_HOST;
|
||||
@@ -2475,8 +2478,8 @@ void set_function_spec_param(RU_t *ru) {
|
||||
malloc_IF4p5_buffer(ru);
|
||||
} else if (ru->function == eNodeB_3GPP) {
|
||||
ru->do_prach = 0; // no prach processing in RU
|
||||
ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full : ru_fep_full_2thread; // RX DFTs
|
||||
ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft and precoding
|
||||
ru->feprx = fep_full; // RX DFTs
|
||||
ru->feptx_ofdm = feptx_ofdm; // this is fep with idft and precoding
|
||||
ru->feptx_prec = feptx_prec; // this is fep with idft and precoding
|
||||
ru->fh_north_in = NULL; // no incoming fronthaul from north
|
||||
ru->fh_north_out = NULL; // no outgoing fronthaul to north
|
||||
@@ -2505,9 +2508,9 @@ void set_function_spec_param(RU_t *ru) {
|
||||
|
||||
case REMOTE_IF5: // the remote unit is IF5 RRU
|
||||
ru->do_prach = 0;
|
||||
ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full : fep_full; // this is frequency-shift + DFTs
|
||||
ru->feprx = fep_full; // this is frequency-shift + DFTs
|
||||
ru->feptx_prec = feptx_prec; // need to do transmit Precoding + IDFTs
|
||||
ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // need to do transmit Precoding + IDFTs
|
||||
ru->feptx_ofdm = feptx_ofdm ; // need to do transmit Precoding + IDFTs
|
||||
|
||||
if (ru->if_timing == synch_to_other) {
|
||||
ru->fh_south_in = fh_slave_south_in; // synchronize to master
|
||||
|
||||
+49
-19
@@ -1492,6 +1492,23 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
|
||||
* \param arg unused
|
||||
* \returns a pointer to an int. The storage is not on the heap and must not be freed.
|
||||
*/
|
||||
void write_dummy(PHY_VARS_UE *UE, openair0_timestamp timestamp) {
|
||||
// we have to write to tell explicitly to the eNB, else it will wait for us forever
|
||||
// we write the next subframe (always write in future of what we received)
|
||||
//
|
||||
struct complex16 v= {0};
|
||||
void *samplesVoid[UE->frame_parms.nb_antennas_tx];
|
||||
|
||||
for ( int i=0; i < UE->frame_parms.nb_antennas_tx; i++)
|
||||
samplesVoid[i]=(void *)&v;
|
||||
|
||||
AssertFatal( 1 == UE->rfdevice.trx_write_func(&UE->rfdevice,
|
||||
timestamp+2*UE->frame_parms.samples_per_tti,
|
||||
samplesVoid,
|
||||
1,
|
||||
UE->frame_parms.nb_antennas_tx,
|
||||
1),"");
|
||||
}
|
||||
|
||||
void *UE_thread(void *arg) {
|
||||
PHY_VARS_UE *UE = (PHY_VARS_UE *) arg;
|
||||
@@ -1542,21 +1559,25 @@ void *UE_thread(void *arg) {
|
||||
int instance_cnt_synch = UE->proc.instance_cnt_synch;
|
||||
int is_synchronized = UE->is_synchronized;
|
||||
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
|
||||
|
||||
|
||||
if (is_synchronized == 0) {
|
||||
if (instance_cnt_synch < 0) { // we can invoke the synch
|
||||
// grab 10 ms of signal and wakeup synch thread
|
||||
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
|
||||
rxp[i] = (void *)&UE->common_vars.rxdata[i][0];
|
||||
|
||||
if (UE->mode != loop_through_memory)
|
||||
AssertFatal( UE->frame_parms.samples_per_tti*10 ==
|
||||
UE->rfdevice.trx_read_func(&UE->rfdevice,
|
||||
×tamp,
|
||||
rxp,
|
||||
UE->frame_parms.samples_per_tti*10,
|
||||
UE->frame_parms.nb_antennas_rx), "");
|
||||
|
||||
for(int sf=0; sf<10; sf++) {
|
||||
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
|
||||
rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.samples_per_tti*sf];
|
||||
|
||||
AssertFatal( UE->frame_parms.samples_per_tti ==
|
||||
UE->rfdevice.trx_read_func(&UE->rfdevice,
|
||||
×tamp,
|
||||
rxp,
|
||||
UE->frame_parms.samples_per_tti,
|
||||
UE->frame_parms.nb_antennas_rx), "");
|
||||
if (IS_SOFTMODEM_RFSIM )
|
||||
write_dummy(UE, timestamp);
|
||||
}
|
||||
|
||||
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
|
||||
instance_cnt_synch = ++UE->proc.instance_cnt_synch;
|
||||
|
||||
@@ -1579,13 +1600,16 @@ void *UE_thread(void *arg) {
|
||||
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
|
||||
rxp[i] = (void *)&dummy_rx[i][0];
|
||||
|
||||
for (int sf=0; sf<10; sf++)
|
||||
for (int sf=0; sf<10; sf++) {
|
||||
// printf("Reading dummy sf %d\n",sf);
|
||||
UE->rfdevice.trx_read_func(&UE->rfdevice,
|
||||
×tamp,
|
||||
rxp,
|
||||
UE->frame_parms.samples_per_tti,
|
||||
UE->frame_parms.nb_antennas_rx);
|
||||
if (IS_SOFTMODEM_RFSIM )
|
||||
write_dummy(UE, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1598,12 +1622,18 @@ void *UE_thread(void *arg) {
|
||||
if (UE->mode != loop_through_memory) {
|
||||
if (UE->no_timing_correction==0) {
|
||||
LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
|
||||
AssertFatal(UE->rx_offset ==
|
||||
UE->rfdevice.trx_read_func(&UE->rfdevice,
|
||||
×tamp,
|
||||
(void **)UE->common_vars.rxdata,
|
||||
UE->rx_offset,
|
||||
UE->frame_parms.nb_antennas_rx),"");
|
||||
while ( UE->rx_offset ) {
|
||||
size_t s=min(UE->rx_offset,UE->frame_parms.samples_per_tti);
|
||||
AssertFatal(s ==
|
||||
UE->rfdevice.trx_read_func(&UE->rfdevice,
|
||||
×tamp,
|
||||
(void **)UE->common_vars.rxdata,
|
||||
s,
|
||||
UE->frame_parms.nb_antennas_rx),"");
|
||||
if (IS_SOFTMODEM_RFSIM )
|
||||
write_dummy(UE, timestamp);
|
||||
UE->rx_offset-=s;
|
||||
}
|
||||
}
|
||||
|
||||
UE->rx_offset=0;
|
||||
@@ -1644,7 +1674,7 @@ void *UE_thread(void *arg) {
|
||||
|
||||
pthread_mutex_unlock(&proc->mutex_rxtx);
|
||||
}
|
||||
usleep(3000);
|
||||
usleep(300);
|
||||
}
|
||||
|
||||
LOG_D(PHY,"Process Subframe %d thread Idx %d \n", sub_frame, UE->current_thread_id[sub_frame]);
|
||||
|
||||
@@ -597,6 +597,11 @@ void init_pdcp(void) {
|
||||
pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
|
||||
}
|
||||
|
||||
// Stupid function addition because UE itti messages queues definition is common with eNB
|
||||
void *rrc_enb_process_itti_msg(void *notUsed) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
int CC_id;
|
||||
uint8_t abstraction_flag=0;
|
||||
@@ -657,6 +662,7 @@ int main( int argc, char **argv ) {
|
||||
pthread_cond_init(&sync_cond,NULL);
|
||||
pthread_mutex_init(&sync_mutex, NULL);
|
||||
printf("ITTI init\n");
|
||||
#define UE
|
||||
itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info);
|
||||
|
||||
// initialize mscgen log after ITTI
|
||||
|
||||
Reference in New Issue
Block a user