Bug 366 - Packet is not thread-safe
Packet is not thread-safe
Status: NEW
Product: ns-3
Classification: Unclassified
Component: core
pre-release
All All
: P3 normal
Assigned To: Mathieu Lacage
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2008-09-23 18:03 EDT by Mathieu Lacage
Modified: 2009-04-03 11:42 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mathieu Lacage 2008-09-23 18:03:02 EDT
you can't create a packet in a thread and pass it to another thread, even if you forget about it in the first thread. This is because of the global cache used in buffer.cc, packet-metadata.cc, and tag-list.cc
Comment 1 Gustavo J. A. M. Carneiro 2008-09-24 05:38:00 EDT
Good to know this, because I am currently making this mistake :-/

Anyway, in my opinion we do not want to make packets thread safe; doing so would incur a significant performance penalty for non-threaded simulations, so -1 from me.  I can easily work around this problem, and I want my optimized simulation scripts to run as fast as they can.
Comment 2 Gustavo J. A. M. Carneiro 2008-09-24 05:47:39 EDT
It turns out I am not sure I am making that mistake any more.  When you say:

 "you can't create a packet in a thread and pass it to another thread, even if
you forget about it in the first thread."

Is this really 100% accurate?  In my case, I have one thread doing simulation, and the main thread doing GUI stuff.  But I use a mutex in the GUI thread, so I am sure that the simulation thread is suspended while I am operating on the packet.  Even if there is a global cache, I am pretty sure only one thread is operating on that cache at any given time.
Comment 3 Mathieu Lacage 2008-09-24 11:46:16 EDT
(In reply to comment #2)
> It turns out I am not sure I am making that mistake any more.  When you say:
> 
>  "you can't create a packet in a thread and pass it to another thread, even if
> you forget about it in the first thread."
> 
> Is this really 100% accurate?  In my case, I have one thread doing simulation,

yes, I believe that this is accurate. Removing entries from the global from one thread to create packets and adding entries in this cache from another thread to 'destroy' them can't be safe without serious thinking.

> and the main thread doing GUI stuff.  But I use a mutex in the GUI thread, so I
> am sure that the simulation thread is suspended while I am operating on the
> packet.  Even if there is a global cache, I am pretty sure only one thread is
> operating on that cache at any given time.

that _might_ work.

There are many ways to make that implementation thread-safe and I agree with your previous comment that adding locking would be most likely a mistake. We need to figure out a better way to avoid locking and ensure thread-safety.
Comment 4 Craig Dowell 2008-09-24 14:40:16 EDT
> > Even if there is a global cache, I am pretty sure only one thread is
> > operating on that cache at any given time.

> that _might_ work.

This depends on what kind of threads we're talking about.  Any mucking about in the global cache has got to be atomic.  Reference counting using Ptr<Packet> will kill you as well.  You can't pass a Ptr<Packet> between threads because the act of "forgetting about it" can cause an error.

If you have a thread model in which threads run to completion or to a Yield operation, this could work.  If you have a kernel-type thread that is pre-empted halfway through some critical section anywhere in the packet code, you'll die a horrible death.  I believe the answer is going to depend on the threading model.

In the real-time simulator (which you can think of as a multi-threaded simulator), we allow the event code (which allows multiple threads to access events) to "borrow" a critical section from the simulator that does nothing in the non-multi-threaded case, but performs real mutual exclusion in the multi-threaded case.