ports.h 3.1 KB
Newer Older
Antoine Kaufmann's avatar
Antoine Kaufmann committed
1
2
3
4
5
#ifndef NET_MENSHEN_PORTS_H_
#define NET_MENSHEN_PORTS_H_

#include <stdint.h>

6
#include <simbricks/base/cxxatomicfix.h>
Antoine Kaufmann's avatar
Antoine Kaufmann committed
7
extern "C" {
8
#include <simbricks/network/if.h>
Antoine Kaufmann's avatar
Antoine Kaufmann committed
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
}

extern uint64_t sync_period;
extern uint64_t eth_latency;
extern int sync_mode;

/** Abstract base switch port */
class Port {
 public:
  enum RxPollState {
    kRxPollSuccess = 0,
    kRxPollFail = 1,
    kRxPollSync = 2,
  };

  virtual ~Port() = default;

  virtual bool Connect(const char *path, int sync) = 0;
  virtual bool IsSync() = 0;
  virtual void Sync(uint64_t cur_ts) = 0;
  virtual uint64_t NextTimestamp() = 0;
  virtual enum RxPollState RxPacket(
      const void *& data, size_t &len, uint64_t cur_ts) = 0;
  virtual void RxDone() = 0;
  virtual bool TxPacket(const void *data, size_t len, uint64_t cur_ts) = 0;
};


/** Normal network switch port (conneting to a NIC) */
class NetPort : public Port {
 protected:
40
41
42
43
  struct SimbricksBaseIfParams *params_;
  struct SimbricksNetIf netifObj_;
  struct SimbricksNetIf *netif_;
  volatile union SimbricksProtoNetMsg *rx_;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
44
45
46
  int sync_;

 public:
47
48
49
  NetPort(struct SimbricksBaseIfParams *params) : params_(params),
      netif_(&netifObj_), rx_(nullptr), sync_(0) {
    memset(&netifObj_, 0, sizeof(netifObj_));
Antoine Kaufmann's avatar
Antoine Kaufmann committed
50
51
  }

52
53
  NetPort(const NetPort &other) : netifObj_(other.netifObj_),
      netif_(&netifObj_), rx_(other.rx_), sync_(other.sync_) {}
Antoine Kaufmann's avatar
Antoine Kaufmann committed
54
55
56

  virtual bool Connect(const char *path, int sync) override {
    sync_ = sync;
57
    return SimbricksNetIfInit(netif_, params_, path, &sync_) == 0;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
58
59
60
61
62
63
64
  }

  virtual bool IsSync() override {
    return sync_;
  }

  virtual void Sync(uint64_t cur_ts) override {
65
    while (SimbricksNetIfOutSync(netif_, cur_ts));
Antoine Kaufmann's avatar
Antoine Kaufmann committed
66
67
68
  }

  virtual uint64_t NextTimestamp() override {
69
    return SimbricksNetIfInTimestamp(netif_);
Antoine Kaufmann's avatar
Antoine Kaufmann committed
70
71
72
73
74
75
  }

  virtual enum RxPollState RxPacket(
      const void *& data, size_t &len, uint64_t cur_ts) override {
    assert(rx_ == nullptr);

76
    rx_ = SimbricksNetIfInPoll(netif_, cur_ts);
Antoine Kaufmann's avatar
Antoine Kaufmann committed
77
78
79
    if (!rx_)
      return kRxPollFail;

80
81
82
83
    uint8_t type = SimbricksNetIfInType(netif_, rx_);
    if (type == SIMBRICKS_PROTO_NET_MSG_PACKET) {
      data = (const void *)rx_->packet.data;
      len = rx_->packet.len;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
84
      return kRxPollSuccess;
85
    } else if (type == SIMBRICKS_PROTO_MSG_TYPE_SYNC) {
Antoine Kaufmann's avatar
Antoine Kaufmann committed
86
87
88
89
90
91
92
93
94
95
      return kRxPollSync;
    } else {
      fprintf(stderr, "switch_pkt: unsupported type=%u\n", type);
      abort();
    }
  }

  virtual void RxDone() override {
    assert(rx_ != nullptr);

96
    SimbricksNetIfInDone(netif_, rx_);
Antoine Kaufmann's avatar
Antoine Kaufmann committed
97
98
99
100
101
    rx_ = nullptr;
  }

  virtual bool TxPacket(
      const void *data, size_t len, uint64_t cur_ts) override {
102
103
    volatile union SimbricksProtoNetMsg *msg_to =
      SimbricksNetIfOutAlloc(netif_, cur_ts);
Antoine Kaufmann's avatar
Antoine Kaufmann committed
104
105
106
107
    if (!msg_to && !sync_) {
      return false;
    } else if (!msg_to && sync_) {
      while (!msg_to)
108
        msg_to = SimbricksNetIfOutAlloc(netif_, cur_ts);
Antoine Kaufmann's avatar
Antoine Kaufmann committed
109
    }
110
111
    volatile struct SimbricksProtoNetMsgPacket *rx;
    rx = &msg_to->packet;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
112
113
114
115
    rx->len = len;
    rx->port = 0;
    memcpy((void *)rx->data, data, len);

116
    SimbricksNetIfOutSend(netif_, msg_to, SIMBRICKS_PROTO_NET_MSG_PACKET);
Antoine Kaufmann's avatar
Antoine Kaufmann committed
117
118
119
120
121
    return true;
  }
};

#endif  // NET_MENSHEN_PORTS_H_