Skip to content

Commit e0e075b

Browse files
committed
st20 tests pass
Signed-off-by: Kasiewicz, Marek <marek.kasiewicz@intel.com>
1 parent 6c10b5c commit e0e075b

File tree

14 files changed

+1904
-1608
lines changed

14 files changed

+1904
-1608
lines changed

lib/src/meson.build

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ sources = files(
2020
'mt_instance.c',
2121
'mt_log.c',
2222
'mt_pcap.c',
23-
'mt_session.c',
24-
'mt_session_buffer.c',
25-
'mt_session_event.c',
2623
)
2724

2825
if is_windows
@@ -36,4 +33,5 @@ subdir('datapath')
3633
subdir('dev')
3734
subdir('st2110')
3835
subdir('deprecated/udp')
36+
subdir('new_api')
3937

lib/src/new_api/meson.build

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
# Copyright 2022 Intel Corporation
3+
4+
sources += files(
5+
'mt_session.c',
6+
'mt_session.h',
7+
'mt_session_buffer.c',
8+
'mt_session_event.c',
9+
'mt_session_video_common.c',
10+
'mt_session_video_common.h',
11+
'mt_session_video_tx.c',
12+
'mt_session_video_rx.c',
13+
)
Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414

1515
#include <errno.h>
1616

17-
#include "mt_log.h"
18-
#include "mt_mem.h"
17+
#include "../mt_log.h"
18+
#include "../mt_mem.h"
1919

2020
/*************************************************************************
2121
* Session Allocation / Deallocation
@@ -32,11 +32,9 @@ struct mtl_session_impl* mtl_session_alloc(struct mtl_main_impl* impl, int socke
3232

3333
s->parent = impl;
3434
s->socket_id = socket_id;
35-
s->state = MTL_SESSION_STATE_CREATED;
36-
s->stopped = false;
35+
__atomic_store_n(&s->state, MTL_SESSION_STATE_CREATED, __ATOMIC_RELAXED);
36+
__atomic_store_n(&s->stopped, 0, __ATOMIC_RELAXED);
3737
s->event_fd = -1;
38-
rte_spinlock_init(&s->state_lock);
39-
rte_spinlock_init(&s->stats_lock);
4038

4139
return s;
4240
}
@@ -164,17 +162,12 @@ int mtl_session_start(mtl_session_t* session) {
164162
return -EINVAL;
165163
}
166164

167-
rte_spinlock_lock(&s->state_lock);
168-
169-
if (s->state == MTL_SESSION_STATE_STARTED) {
170-
rte_spinlock_unlock(&s->state_lock);
165+
if (__atomic_load_n(&s->state, __ATOMIC_ACQUIRE) == MTL_SESSION_STATE_STARTED) {
171166
return 0; /* Already started */
172167
}
173168

174169
mtl_session_clear_stopped(s);
175170

176-
rte_spinlock_unlock(&s->state_lock);
177-
178171
int ret = 0;
179172
if (s->vt && s->vt->start) {
180173
ret = s->vt->start(s);
@@ -408,10 +401,17 @@ int mtl_session_stats_get(mtl_session_t* session, mtl_session_stats_t* stats) {
408401
return s->vt->stats_get(s, stats);
409402
}
410403

411-
/* Default: return cached stats */
412-
rte_spinlock_lock(&s->stats_lock);
413-
*stats = s->stats;
414-
rte_spinlock_unlock(&s->stats_lock);
404+
/* Default: return cached stats (atomic reads, relaxed ordering) */
405+
stats->buffers_processed =
406+
__atomic_load_n(&s->stats.buffers_processed, __ATOMIC_RELAXED);
407+
stats->bytes_processed =
408+
__atomic_load_n(&s->stats.bytes_processed, __ATOMIC_RELAXED);
409+
stats->buffers_dropped =
410+
__atomic_load_n(&s->stats.buffers_dropped, __ATOMIC_RELAXED);
411+
stats->epochs_missed =
412+
__atomic_load_n(&s->stats.epochs_missed, __ATOMIC_RELAXED);
413+
stats->buffers_free = 0;
414+
stats->buffers_in_use = 0;
415415
return 0;
416416
}
417417

@@ -426,9 +426,10 @@ int mtl_session_stats_reset(mtl_session_t* session) {
426426
return s->vt->stats_reset(s);
427427
}
428428

429-
rte_spinlock_lock(&s->stats_lock);
430-
memset(&s->stats, 0, sizeof(s->stats));
431-
rte_spinlock_unlock(&s->stats_lock);
429+
__atomic_store_n(&s->stats.buffers_processed, 0, __ATOMIC_RELAXED);
430+
__atomic_store_n(&s->stats.bytes_processed, 0, __ATOMIC_RELAXED);
431+
__atomic_store_n(&s->stats.buffers_dropped, 0, __ATOMIC_RELAXED);
432+
__atomic_store_n(&s->stats.epochs_missed, 0, __ATOMIC_RELAXED);
432433
return 0;
433434
}
434435

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,11 @@
2424
#include "mtl_session_api.h"
2525

2626
/* Internal MTL headers */
27-
#include "mt_main.h"
28-
#include "st2110/st_header.h"
27+
#include "../mt_main.h"
28+
#include "../st2110/st_header.h"
2929

3030
#include <rte_atomic.h>
3131
#include <rte_ring.h>
32-
#include <rte_spinlock.h>
3332

3433
#if defined(__cplusplus)
3534
extern "C" {
@@ -159,12 +158,23 @@ struct mtl_session_impl {
159158
int idx; /**< Session index (for logging) */
160159
int socket_id; /**< NUMA socket */
161160

162-
/* State */
161+
/*
162+
* Session state — accessed with C11 __atomic builtins.
163+
* No lock needed; state transitions pair with the stopped flag.
164+
*/
163165
mtl_session_state_t state;
164-
rte_spinlock_t state_lock;
165166

166-
/* Set by stop(), checked by buffer_get/event_poll to return -EAGAIN */
167-
volatile bool stopped;
167+
/**
168+
* Atomic stopped flag — the primary cross-thread signal.
169+
* Set by stop(), checked by buffer_get/event_poll to return -EAGAIN.
170+
*
171+
* Memory ordering rationale:
172+
* store (__ATOMIC_RELEASE): all prior stores (state, data) are visible
173+
* before stopped is observed by other threads.
174+
* load (__ATOMIC_ACQUIRE): subsequent reads in the checking thread see
175+
* all stores that happened before the set.
176+
*/
177+
int stopped;
168178

169179
/* Configuration (copied from create) */
170180
char name[ST_MAX_NAME_LEN];
@@ -194,6 +204,13 @@ struct mtl_session_impl {
194204
* Frame buffer management.
195205
* For library-owned mode, we manage mtl_buffer_impl wrappers.
196206
* The actual frame memory is in inner->st20_frames (st_frame_trans array).
207+
*
208+
* Thread safety: completely lock-free.
209+
* - TX: atomic CAS on per-frame state (enum tx_frame_state) provides
210+
* mutual exclusion — only the CAS winner owns a given frame.
211+
* - RX: multi-consumer rte_ring ensures safe concurrent dequeue.
212+
* Buffer wrapper assignment is race-free because each frame_idx maps
213+
* 1:1 to a unique buffer_impl slot (buffer_count >= frame_count).
197214
*/
198215
uint32_t buffer_count;
199216
struct mtl_buffer_impl* buffers; /**< Buffer wrapper pool */
@@ -202,9 +219,14 @@ struct mtl_session_impl {
202219
struct rte_ring* event_ring; /**< Pending events */
203220
int event_fd; /**< For epoll integration */
204221

205-
/* Statistics - aggregated view of inner session stats */
222+
/*
223+
* Statistics — aggregated view of inner session stats.
224+
* Thread safety: individual counter fields are accessed with __atomic builtins.
225+
* Increments use __ATOMIC_RELAXED (no ordering needed for counters).
226+
* Reads/resets also use __ATOMIC_RELAXED (approximate snapshot is fine).
227+
* No lock needed — each field is independently atomic.
228+
*/
206229
mtl_session_stats_t stats;
207-
rte_spinlock_t stats_lock;
208230

209231
/* Callbacks (optional, for low-latency notification) */
210232
int (*notify_buffer_ready)(void* priv);
@@ -353,27 +375,31 @@ void mtl_session_put_frame_trans(struct st_frame_trans* ft);
353375
*************************************************************************/
354376

355377
/**
356-
* Check if session is stopped.
378+
* Check if session is stopped (thread-safe, acquire semantics).
357379
* Call this at the start of any blocking operation.
358380
*/
359381
static inline bool mtl_session_check_stopped(struct mtl_session_impl* s) {
360-
return s->stopped;
382+
return __atomic_load_n(&s->stopped, __ATOMIC_ACQUIRE) != 0;
361383
}
362384

363385
/**
364-
* Set stopped flag. Called by mtl_session_stop().
386+
* Set stopped flag (thread-safe). Called by mtl_session_stop().
387+
* Uses release semantics so all prior stores are visible.
365388
*/
366389
static inline void mtl_session_set_stopped(struct mtl_session_impl* s) {
367-
s->stopped = true;
368-
s->state = MTL_SESSION_STATE_STOPPED;
390+
/* Store state first (relaxed), then stopped with release.
391+
* The release on stopped ensures that the state store is visible
392+
* to any thread that observes stopped == 1 via acquire load. */
393+
__atomic_store_n(&s->state, MTL_SESSION_STATE_STOPPED, __ATOMIC_RELAXED);
394+
__atomic_store_n(&s->stopped, 1, __ATOMIC_RELEASE);
369395
}
370396

371397
/**
372-
* Clear stopped flag. Called by mtl_session_start().
398+
* Clear stopped flag (thread-safe). Called by mtl_session_start().
373399
*/
374400
static inline void mtl_session_clear_stopped(struct mtl_session_impl* s) {
375-
s->stopped = false;
376-
s->state = MTL_SESSION_STATE_STARTED;
401+
__atomic_store_n(&s->state, MTL_SESSION_STATE_STARTED, __ATOMIC_RELAXED);
402+
__atomic_store_n(&s->stopped, 0, __ATOMIC_RELEASE);
377403
}
378404

379405
/*************************************************************************
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
#include <errno.h>
1515

16-
#include "mt_log.h"
17-
#include "mt_mem.h"
16+
#include "../mt_log.h"
17+
#include "../mt_mem.h"
1818

1919
/*************************************************************************
2020
* Buffer Pool Management
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
#include <sys/eventfd.h>
1616
#include <unistd.h>
1717

18-
#include "mt_log.h"
19-
#include "mt_mem.h"
18+
#include "../mt_log.h"
19+
#include "../mt_mem.h"
2020

2121
#define MTL_EVENT_RING_SIZE 64 /* Must be power of 2 */
2222

@@ -30,7 +30,7 @@ int mtl_session_events_init(struct mtl_session_impl* s) {
3030
snprintf(ring_name, sizeof(ring_name), "mtl_ev_%p", s);
3131

3232
s->event_ring =
33-
rte_ring_create(ring_name, MTL_EVENT_RING_SIZE, s->socket_id, RING_F_SC_DEQ);
33+
rte_ring_create(ring_name, MTL_EVENT_RING_SIZE, s->socket_id, 0);
3434
if (!s->event_ring) {
3535
err("%s(%s), failed to create event ring\n", __func__, s->name);
3636
return -ENOMEM;

0 commit comments

Comments
 (0)