blob: 385395a15521279f62c20b4de7a965260233fec0 [file] [log] [blame]
Eric Wildd40300e2022-05-07 15:36:47 +02001#include <mutex>
2#include <queue>
3#include <deque>
4#include <condition_variable>
5#include <iostream>
6
7extern "C" {
8
9#include <unistd.h>
10#include <sys/eventfd.h>
11
12#include <osmocom/core/utils.h>
13#include <osmocom/core/select.h>
14}
15#include "l1if.h"
16
17using namespace std;
18using namespace std::chrono_literals;
19
20template<typename Data>
21class spsc_q{
22
23 std::queue<Data> m_q;
24 std::mutex m_mtx;
25 std::condition_variable m_cond;
26 bool killme;
27
28public:
29 spsc_q() : killme{ false } { }
30
31 void push(Data i){
32 std::unique_lock<std::mutex> lock(m_mtx);
33 m_q.push(i);
34 m_cond.notify_one();
35 }
36
37 Data pop(){
38 std::unique_lock<std::mutex> lock(m_mtx);
39 m_cond.wait_for(lock, 100ms, [&](){ return !m_q.empty() || killme; });
40
41 if (killme || m_q.empty()){
42 return {};
43 }
44
45 Data x = m_q.front();
46 m_q.pop();
47
48 return x;
49 }
50
51 void stop(){
52 killme = true;
53 m_cond.notify_all();
54 }
55
56 auto sz() { return m_q.size(); }
57};
58
59
60/*
61 * trxif_from_trx_c <-> push_c
62 * trxif_to_trx_c <-> pop_c
63 * trxif_from_trx_d <-> push_d
64 * trxif_to_trx_d <-> pop_d
65 * ...
66 *
67 *
68 */
69class trxl1if {
70public:
71 spsc_q<TRX_C*> c_to_trx;
72 spsc_q<TRX_C*> c_from_trx;
73
74 spsc_q<trxd_to_trx*> d_to_trx;
75 spsc_q<trxd_from_trx*> d_from_trx;
76
77 struct osmo_fd g_event_ofd_C;
78 struct osmo_fd g_event_ofd_D;
79};
80
81trxl1if trxif;
82
83void push_c(TRX_C* i) {
84 uint64_t one = 1;
85 int rc;
86 trxif.c_from_trx.push(i);
Eric935c8cb2022-06-06 00:48:09 +020087 // std::clog << trxif.c_from_trx.sz() << std::endl;
Eric Wildd40300e2022-05-07 15:36:47 +020088 rc = ::write(trxif.g_event_ofd_C.fd, &one, sizeof(one));
89 return;
90};
91TRX_C* pop_c() {
92 return trxif.c_to_trx.pop();
93};
94void push_d(trxd_from_trx* i) {
95 uint64_t one = 1;
96 int rc;
97 trxif.d_from_trx.push(i);
98 rc = ::write(trxif.g_event_ofd_D.fd, &one, sizeof(one));
99 return;
100};
101trxd_to_trx* pop_d() {
102 return trxif.d_to_trx.pop();
103};
104
105extern "C" {
106char* trxif_from_trx_c() {
107 uint64_t one = 1;
108 ::read(trxif.g_event_ofd_C.fd, &one, sizeof(one));
109 return (char*)trxif.c_from_trx.pop();
110}
111void trxif_to_trx_c(char* msg) {
112 trxif.c_to_trx.push((TRX_C*)msg);
113}
114trxd_from_trx* trxif_from_trx_d() {
115 uint64_t one = 1;
116 ::read(trxif.g_event_ofd_D.fd, &one, sizeof(one));
117 return trxif.d_from_trx.pop();
118}
119void trxif_to_trx_d(trxd_to_trx* msg) {
120 trxif.d_to_trx.push(msg);
121}
122struct osmo_fd* get_c_fd() { return &trxif.g_event_ofd_C;}
123struct osmo_fd* get_d_fd() { return &trxif.g_event_ofd_D;}
124}