|
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 |
// |