|
|
| 48 |
#include <errno.h> |
48 |
#include <errno.h> |
| 49 |
#include <limits> |
49 |
#include <limits> |
| 50 |
#include <stdlib.h> |
50 |
#include <stdlib.h> |
|
|
51 |
#include <time.h> |
| 51 |
|
52 |
|
| 52 |
NS_LOG_COMPONENT_DEFINE ("EmuNetDevice"); |
53 |
NS_LOG_COMPONENT_DEFINE ("EmuNetDevice"); |
| 53 |
|
54 |
|
|
|
| 56 |
NS_OBJECT_ENSURE_REGISTERED (EmuNetDevice); |
57 |
NS_OBJECT_ENSURE_REGISTERED (EmuNetDevice); |
| 57 |
|
58 |
|
| 58 |
#define EMU_MAGIC 65867 |
59 |
#define EMU_MAGIC 65867 |
|
|
60 |
#define MAX_PENDING_READS 1 |
| 61 |
|
| 59 |
|
62 |
|
| 60 |
TypeId |
63 |
TypeId |
| 61 |
EmuNetDevice::GetTypeId (void) |
64 |
EmuNetDevice::GetTypeId (void) |
|
|
| 184 |
m_ifIndex (std::numeric_limits<uint32_t>::max ()), // absurdly large value |
187 |
m_ifIndex (std::numeric_limits<uint32_t>::max ()), // absurdly large value |
| 185 |
m_sll_ifindex (-1), |
188 |
m_sll_ifindex (-1), |
| 186 |
m_isBroadcast (true), |
189 |
m_isBroadcast (true), |
| 187 |
m_isMulticast (false) |
190 |
m_isMulticast (false), |
|
|
191 |
m_pendingReadCount (0) |
| 188 |
{ |
192 |
{ |
| 189 |
NS_LOG_FUNCTION (this); |
193 |
NS_LOG_FUNCTION (this); |
| 190 |
m_packetBuffer = new uint8_t[65536]; |
194 |
m_packetBuffer = new uint8_t[65536]; |
|
|
| 626 |
free (buf); |
630 |
free (buf); |
| 627 |
buf = 0; |
631 |
buf = 0; |
| 628 |
|
632 |
|
|
|
633 |
{ |
| 634 |
CriticalSection cs (m_pendingReadMutex); |
| 635 |
//std::cerr << std::endl << "EmuNetDevice main thread: m_pendingReadCount is " << m_pendingReadCount << std::endl; |
| 636 |
--m_pendingReadCount; |
| 637 |
} |
| 638 |
|
| 629 |
// |
639 |
// |
| 630 |
// Trace sinks will expect complete packets, not packets without some of the |
640 |
// Trace sinks will expect complete packets, not packets without some of the |
| 631 |
// headers. |
641 |
// headers. |
|
|
| 755 |
for (;;) |
765 |
for (;;) |
| 756 |
{ |
766 |
{ |
| 757 |
// |
767 |
// |
|
|
768 |
// Too many pending reads at the same time leads to excessive memory allocations. This counter prevents it. |
| 769 |
// |
| 770 |
bool skip = false; |
| 771 |
|
| 772 |
{ |
| 773 |
CriticalSection cs (m_pendingReadMutex); |
| 774 |
//std::cerr << std::endl << "EmuNetDevice read thread: m_pendingReadCount is " << m_pendingReadCount << std::endl; |
| 775 |
if (m_pendingReadCount >= MAX_PENDING_READS) |
| 776 |
{ |
| 777 |
skip = true; |
| 778 |
} |
| 779 |
else |
| 780 |
{ |
| 781 |
++m_pendingReadCount; |
| 782 |
} |
| 783 |
} |
| 784 |
|
| 785 |
if (skip) |
| 786 |
{ |
| 787 |
struct timespec time = { 0, 100000000L }; // 100 ms |
| 788 |
nanosleep (&time, NULL); |
| 789 |
continue; |
| 790 |
} |
| 791 |
|
| 792 |
// |
| 758 |
// to avoid any issues with a shared reference counted packet, we allocate a buffer on the heap and pass that |
793 |
// to avoid any issues with a shared reference counted packet, we allocate a buffer on the heap and pass that |
| 759 |
// buffer into the ns-3 context thread where it will create the packet, copy the buffer and then free it. |
794 |
// buffer into the ns-3 context thread where it will create the packet, copy the buffer and then free it. |
| 760 |
// |
795 |
// |