Files
openairinterface5g/nfapi/open-nFAPI/sim_common/inc/pool.h
T
Cedric Roux 922b5b595a Fix NFAPI integration
This commit fixes issues introduced by the previous commit.

Summary of work:
- cleanup:
  - fix LOG_XX to be less verbose
  - fix cmake_targets/CMakeLists.txt
  - fix oaienv
  - remove dead code
- bug fixes:
  - in openair1/SCHED/fapi_l1.c we had:
      eNB->pdcch_vars[subframe&1].num_dci           = number_dci;
    should be:
      eNB->pdcch_vars[subframe&1].num_dci           = 0;
    This bug let the PHY send more DCIs than what should have been
    sent because num_dci is incremented later on in the code.
    This fix may be a problem for fapi mode, to be checked.
  - add new T VCD traces
  - revert openair1/PHY/TOOLS/file_output.c to 'develop' version
  - remove thread_id in logRecord/logRecord_mt
  - revert (and adapt) configuration files
  - be careful when doing frame++, we need to % 1024
  - revert target_rx_power in openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
- NFAPI:
  - the open-nFAPI code has been included in the repository. See nfapi/README.
    Maybe we should "git clone" the Cisco repository instead. We have to be
    careful of availability though.

What has been tested:
- monolithic eNB FDD 5/10MHz with one UE, iperf UDP/TCP uplink/downlink

Anything else may fail to work, especially the FAPI mode, which has not
been tested at all.
2018-01-15 15:24:50 +01:00

187 lines
4.0 KiB
C++

/*
* Copyright 2017 Cisco Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
#ifndef _POOL_H_
#define _POOL_H_
#include <mutex>
#include <map>
#include <queue>
#include <cassert>
class pool_config
{
public:
size_t size;
uint16_t initial_count;
};
class memory_pool
{
std::mutex mutex;
std::map<size_t, std::queue<uint8_t*>> free_store;
std::map<size_t, uint16_t> allocated_store;
void init(std::vector<pool_config> config)
{
printf("memory_pool::init\n");
for(pool_config c : config)
{
// todo : use the initial count to allocate initial pool memory
free_store.insert(std::pair<size_t,
std::queue<uint8_t*>>
(c.size, std::queue<uint8_t*>()));
allocated_store.insert(std::pair<size_t, uint16_t>(c.size, 0));
}
}
memory_pool()
{
std::vector<pool_config> config
{
{8, 0}, {32, 0}, {64, 0}, {128, 0}, {256, 0},
{1024, 0}, {4096, 0}, {8912, 0}
};
init(config);
}
uint16_t determine_pool_size(size_t size)
{
for(auto pool : free_store)
{
if(pool.first >= size)
return pool.first;
}
return 0;
}
uint8_t* alloc(size_t size)
{
if(size == 0)
return 0;
uint8_t* ptr = 0;
size_t psize = determine_pool_size(size + 4);
if(psize == 0)
{
ptr = (uint8_t*)malloc(size + 4);
memset(ptr, 0, size + 4);
}
else
{
mutex.lock();
auto it = free_store.find(psize);
if(it == free_store.end())
{
// Unknown pool size
ptr = (uint8_t*)malloc(psize + 4);
memcpy(ptr, &psize, 4);
}
else
{
if(it->second.size() > 0)
{
// Take from the pool
ptr = (uint8_t*)(it->second.front());
it->second.pop();
}
else
{
// No memory left in pool
ptr = (uint8_t*)malloc(psize + 4);
memcpy(ptr, &psize, 4);
}
}
mutex.unlock();
}
return (ptr + 4);
}
void dealloc(uint8_t* ptr)
{
if(ptr == 0)
return;
uint8_t* _ptr = (uint8_t*)ptr;
size_t psize;
memcpy(&psize, _ptr - 4, 4);
if(psize == 0)
{
free(_ptr - 4);
}
else
{
mutex.lock();
auto it = free_store.find(psize);
if(it == free_store.end())
{
free(_ptr - 4);
}
else
{
assert((_ptr - 4) != 0);
it->second.push(_ptr - 4);
}
mutex.unlock();
}
}
public:
memory_pool(memory_pool const&) = delete;
void operator=(memory_pool const&) = delete;
/*! Get the memory_pool instance */
static memory_pool& instance()
{
static memory_pool instance;
return instance;
}
/*! Allocate a buffer from the memory_pool is at least size */
static uint8_t* allocate(size_t size)
{
return instance().alloc(size);
}
/*! Return the buffer to the memory_pool */
static void deallocate(uint8_t* ptr)
{
return instance().dealloc(ptr);
}
};
#endif // _POOL_H_