I'm trying to understand how to model a simple pass through module correctly. Let's say I've got 3 threads/modules A, B, and C such that A sends messages to B which forwards them to C (A --> B --> C).
A naive approach for thread B:
sc_fifo<Message> incoming_fifo("incoming", 3);
sc_fifo<Message> outgoing_fifo("outgoing", 3);
Message msg = new Message();
Further, let's say that module C is negligent and not reading from outgoing_fifo (sorry, the names are B-thread centric). One would naively assume that thread_A can send 6 messages (3 in each fifo) before the fifos become full and it's write becomes blocking.
The problem is, thread_A can actually send 7 messages, because you essentially have an extra slot, conceptually, in thread_B between the success of its read and the block on its write.
One solution might be to use tlm_fifos, first waiting on outgoing_fifo.ok_to_put() then blocking on incoming_fifo.get(). But this becomes problematic if for example there was another module also putting into outgoing_fifo --then ok_to_put() might be true at one point, but when the read/get from incoming_fifo awakens thread_B, it there might no longer be room in the outgoing_fifo. (A similar situation arises if you try to wait on ok_to_get(), but there are multiple threads pulling from incoming_fifo).
Is there a way to solve this problem so that you can be sure that you don't pull from incoming_fifo if you don't have room in outgoing_fifo, ie. simultaneous condition checking, without resorting to something like polling?