Simplify shm td iq channel implementation
Move the channel state management outside the channel implementation. This simplifies the channel implementation but forces users of the channel to manage it's state manually.
This commit is contained in:
@@ -40,7 +40,6 @@ typedef struct {
|
|||||||
int num_antennas_tx;
|
int num_antennas_tx;
|
||||||
int num_antennas_rx;
|
int num_antennas_rx;
|
||||||
uint64_t timestamp;
|
uint64_t timestamp;
|
||||||
bool is_connected;
|
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
pthread_cond_t cond;
|
pthread_cond_t cond;
|
||||||
} ShmTDIQChannelData;
|
} ShmTDIQChannelData;
|
||||||
@@ -48,7 +47,6 @@ typedef struct {
|
|||||||
typedef struct ShmTDIQChannel_s {
|
typedef struct ShmTDIQChannel_s {
|
||||||
IQChannelType type;
|
IQChannelType type;
|
||||||
ShmTDIQChannelData *data;
|
ShmTDIQChannelData *data;
|
||||||
uint64_t last_timestamp;
|
|
||||||
char name[256];
|
char name[256];
|
||||||
sample_t *tx_iq_data;
|
sample_t *tx_iq_data;
|
||||||
sample_t *rx_iq_data;
|
sample_t *rx_iq_data;
|
||||||
@@ -76,14 +74,12 @@ ShmTDIQChannel *shm_td_iq_channel_create(const char *name, int num_tx_ant, int n
|
|||||||
memset(shm_ptr, 0, total_size);
|
memset(shm_ptr, 0, total_size);
|
||||||
shm_ptr->num_antennas_tx = num_tx_ant;
|
shm_ptr->num_antennas_tx = num_tx_ant;
|
||||||
shm_ptr->num_antennas_rx = num_rx_ant;
|
shm_ptr->num_antennas_rx = num_rx_ant;
|
||||||
shm_ptr->is_connected = false;
|
|
||||||
ShmTDIQChannel *channel = calloc_or_fail(1, sizeof(ShmTDIQChannel));
|
ShmTDIQChannel *channel = calloc_or_fail(1, sizeof(ShmTDIQChannel));
|
||||||
strncpy(channel->name, name, sizeof(channel->name) - 1);
|
strncpy(channel->name, name, sizeof(channel->name) - 1);
|
||||||
channel->tx_iq_data = (sample_t *)(shm_ptr + 1);
|
channel->tx_iq_data = (sample_t *)(shm_ptr + 1);
|
||||||
channel->rx_iq_data = channel->tx_iq_data + tx_buffer_size / sizeof(sample_t);
|
channel->rx_iq_data = channel->tx_iq_data + tx_buffer_size / sizeof(sample_t);
|
||||||
channel->data = shm_ptr;
|
channel->data = shm_ptr;
|
||||||
channel->type = IQ_CHANNEL_TYPE_SERVER;
|
channel->type = IQ_CHANNEL_TYPE_SERVER;
|
||||||
channel->last_timestamp = 0;
|
|
||||||
pthread_mutexattr_t mutex_attr;
|
pthread_mutexattr_t mutex_attr;
|
||||||
pthread_condattr_t cond_attr;
|
pthread_condattr_t cond_attr;
|
||||||
int ret = pthread_mutexattr_init(&mutex_attr);
|
int ret = pthread_mutexattr_init(&mutex_attr);
|
||||||
@@ -138,12 +134,10 @@ ShmTDIQChannel *shm_td_iq_channel_connect(const char *name, int timeout_in_secon
|
|||||||
size_t tx_buffer_size = CIRCULAR_BUFFER_SIZE * sizeof(sample_t) * channel->data->num_antennas_tx;
|
size_t tx_buffer_size = CIRCULAR_BUFFER_SIZE * sizeof(sample_t) * channel->data->num_antennas_tx;
|
||||||
channel->rx_iq_data = channel->tx_iq_data + tx_buffer_size / sizeof(sample_t);
|
channel->rx_iq_data = channel->tx_iq_data + tx_buffer_size / sizeof(sample_t);
|
||||||
channel->type = IQ_CHANNEL_TYPE_CLIENT;
|
channel->type = IQ_CHANNEL_TYPE_CLIENT;
|
||||||
channel->last_timestamp = 0;
|
|
||||||
while (shm_ptr->magic != SHM_MAGIC_NUMBER) {
|
while (shm_ptr->magic != SHM_MAGIC_NUMBER) {
|
||||||
printf("Waiting for server to initialize shared memory\n");
|
printf("Waiting for server to initialize shared memory\n");
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
shm_ptr->is_connected = true;
|
|
||||||
close(fd);
|
close(fd);
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
@@ -155,9 +149,6 @@ IQChannelErrorType shm_td_iq_channel_tx(ShmTDIQChannel *channel,
|
|||||||
const sample_t *tx_iq_data)
|
const sample_t *tx_iq_data)
|
||||||
{
|
{
|
||||||
ShmTDIQChannelData *data = channel->data;
|
ShmTDIQChannelData *data = channel->data;
|
||||||
if (data->is_connected == false) {
|
|
||||||
return CHANNEL_ERROR_NOT_CONNECTED;
|
|
||||||
}
|
|
||||||
// timestamp in the past
|
// timestamp in the past
|
||||||
uint64_t current_time = data->timestamp;
|
uint64_t current_time = data->timestamp;
|
||||||
if (timestamp < current_time) {
|
if (timestamp < current_time) {
|
||||||
@@ -194,9 +185,6 @@ IQChannelErrorType shm_td_iq_channel_rx(ShmTDIQChannel *channel,
|
|||||||
sample_t *tx_iq_data)
|
sample_t *tx_iq_data)
|
||||||
{
|
{
|
||||||
ShmTDIQChannelData *data = channel->data;
|
ShmTDIQChannelData *data = channel->data;
|
||||||
if (data->is_connected == false) {
|
|
||||||
return CHANNEL_ERROR_NOT_CONNECTED;
|
|
||||||
}
|
|
||||||
// timestamp in the future
|
// timestamp in the future
|
||||||
uint64_t current_time = data->timestamp;
|
uint64_t current_time = data->timestamp;
|
||||||
if (timestamp > current_time) {
|
if (timestamp > current_time) {
|
||||||
@@ -229,9 +217,6 @@ IQChannelErrorType shm_td_iq_channel_rx(ShmTDIQChannel *channel,
|
|||||||
void shm_td_iq_channel_produce_samples(ShmTDIQChannel *channel, size_t num_samples)
|
void shm_td_iq_channel_produce_samples(ShmTDIQChannel *channel, size_t num_samples)
|
||||||
{
|
{
|
||||||
ShmTDIQChannelData *data = channel->data;
|
ShmTDIQChannelData *data = channel->data;
|
||||||
if (data->is_connected == false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mutexlock(data->mutex);
|
mutexlock(data->mutex);
|
||||||
data->timestamp += num_samples;
|
data->timestamp += num_samples;
|
||||||
condbroadcast(data->cond);
|
condbroadcast(data->cond);
|
||||||
@@ -241,12 +226,6 @@ void shm_td_iq_channel_produce_samples(ShmTDIQChannel *channel, size_t num_sampl
|
|||||||
void shm_td_iq_channel_wait(ShmTDIQChannel *channel, uint64_t timestamp, uint64_t timeout_uS)
|
void shm_td_iq_channel_wait(ShmTDIQChannel *channel, uint64_t timestamp, uint64_t timeout_uS)
|
||||||
{
|
{
|
||||||
ShmTDIQChannelData *data = channel->data;
|
ShmTDIQChannelData *data = channel->data;
|
||||||
if (data->is_connected == false) {
|
|
||||||
fprintf(stderr, "Error: Channel is not connected.\n");
|
|
||||||
abort();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t current_timestamp = data->timestamp;
|
size_t current_timestamp = data->timestamp;
|
||||||
if (current_timestamp >= timestamp) {
|
if (current_timestamp >= timestamp) {
|
||||||
return;
|
return;
|
||||||
@@ -294,11 +273,6 @@ uint64_t shm_td_iq_channel_get_current_sample(const ShmTDIQChannel *channel)
|
|||||||
return data->timestamp;
|
return data->timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shm_td_iq_channel_is_connected(const ShmTDIQChannel *channel)
|
|
||||||
{
|
|
||||||
return channel->data->is_connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
void shm_td_iq_channel_abort(ShmTDIQChannel *channel)
|
void shm_td_iq_channel_abort(ShmTDIQChannel *channel)
|
||||||
{
|
{
|
||||||
ShmTDIQChannelData *data = channel->data;
|
ShmTDIQChannelData *data = channel->data;
|
||||||
@@ -320,7 +294,6 @@ void shm_td_iq_channel_destroy(ShmTDIQChannel *channel)
|
|||||||
size_t rx_buffer_size = CIRCULAR_BUFFER_SIZE * sizeof(sample_t) * data->num_antennas_rx;
|
size_t rx_buffer_size = CIRCULAR_BUFFER_SIZE * sizeof(sample_t) * data->num_antennas_rx;
|
||||||
size_t total_size = sizeof(ShmTDIQChannelData) + tx_buffer_size + rx_buffer_size;
|
size_t total_size = sizeof(ShmTDIQChannelData) + tx_buffer_size + rx_buffer_size;
|
||||||
if (channel->type == IQ_CHANNEL_TYPE_SERVER) {
|
if (channel->type == IQ_CHANNEL_TYPE_SERVER) {
|
||||||
data->is_connected = false;
|
|
||||||
munmap(data, total_size);
|
munmap(data, total_size);
|
||||||
shm_unlink(channel->name);
|
shm_unlink(channel->name);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -123,14 +123,6 @@ void shm_td_iq_channel_produce_samples(ShmTDIQChannel *channel, uint64_t num_sam
|
|||||||
*/
|
*/
|
||||||
void shm_td_iq_channel_wait(ShmTDIQChannel *channel, uint64_t timestamp, uint64_t timeout_uS);
|
void shm_td_iq_channel_wait(ShmTDIQChannel *channel, uint64_t timestamp, uint64_t timeout_uS);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Checks if the IQ channel is connected.
|
|
||||||
*
|
|
||||||
* @param channel The ShmTDIQChannel structure.
|
|
||||||
* @return True if the channel is connected, false otherwise.
|
|
||||||
*/
|
|
||||||
bool shm_td_iq_channel_is_connected(const ShmTDIQChannel *channel);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Aborts the IQ channel causing the wait to return immediately
|
* @brief Aborts the IQ channel causing the wait to return immediately
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -87,15 +87,6 @@ void server(void)
|
|||||||
int num_ant_tx = 1;
|
int num_ant_tx = 1;
|
||||||
int num_ant_rx = 1;
|
int num_ant_rx = 1;
|
||||||
ShmTDIQChannel *channel = shm_td_iq_channel_create(SHM_CHANNEL_NAME, num_ant_tx, num_ant_rx);
|
ShmTDIQChannel *channel = shm_td_iq_channel_create(SHM_CHANNEL_NAME, num_ant_tx, num_ant_rx);
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
if (shm_td_iq_channel_is_connected(channel)) {
|
|
||||||
printf("Server connected\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
printf("Waiting for client\n");
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
AssertFatal(shm_td_iq_channel_is_connected(channel), "Server failed to connect\n");
|
|
||||||
|
|
||||||
pthread_t producer_thread;
|
pthread_t producer_thread;
|
||||||
int ret = pthread_create(&producer_thread, NULL, produce_symbols, channel);
|
int ret = pthread_create(&producer_thread, NULL, produce_symbols, channel);
|
||||||
@@ -127,15 +118,6 @@ int client(void)
|
|||||||
{
|
{
|
||||||
int total_errors = 0;
|
int total_errors = 0;
|
||||||
ShmTDIQChannel *channel = shm_td_iq_channel_connect(SHM_CHANNEL_NAME, 10);
|
ShmTDIQChannel *channel = shm_td_iq_channel_connect(SHM_CHANNEL_NAME, 10);
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
if (shm_td_iq_channel_is_connected(channel)) {
|
|
||||||
printf("Client connected\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
printf("Waiting for server\n");
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
AssertFatal(shm_td_iq_channel_is_connected(channel), "Client failed to connect\n");
|
|
||||||
|
|
||||||
uint64_t timestamp = 0;
|
uint64_t timestamp = 0;
|
||||||
int iq_contents = 0;
|
int iq_contents = 0;
|
||||||
|
|||||||
@@ -368,10 +368,6 @@ static int vrtsim_connect(openair0_device *device)
|
|||||||
vrtsim_state->peer_info.num_rx_antennas,
|
vrtsim_state->peer_info.num_rx_antennas,
|
||||||
device->openair0_cfg[0].rx_num_channels);
|
device->openair0_cfg[0].rx_num_channels);
|
||||||
vrtsim_state->run_timing_thread = true;
|
vrtsim_state->run_timing_thread = true;
|
||||||
while (!shm_td_iq_channel_is_connected(vrtsim_state->channel)) {
|
|
||||||
LOG_I(HW, "Waiting for client\n");
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
int ret = pthread_create(&vrtsim_state->timing_thread, NULL, vrtsim_timing_job, vrtsim_state);
|
int ret = pthread_create(&vrtsim_state->timing_thread, NULL, vrtsim_timing_job, vrtsim_state);
|
||||||
AssertFatal(ret == 0, "pthread_create() failed: errno: %d, %s\n", errno, strerror(errno));
|
AssertFatal(ret == 0, "pthread_create() failed: errno: %d, %s\n", errno, strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user