#include <systemc>

using namespace sc_core;
using namespace sc_dt;
using namespace std;

//#define USE_MUTEX

SC_MODULE(TestMutex) {
    sc_in_clk cin;
    SC_CTOR(TestMutex) {
        SC_THREAD(thread1);
        sensitive << cin.pos();
        SC_THREAD(thread2);
        sensitive << cin.pos();
        SC_THREAD(printer);
    }
private:
    void send(string message) {
#ifdef USE_MUTEX
        m.lock();
#endif
        for (auto c: message) {
            fifo.write(c);
            wait();
        }
#ifdef USE_MUTEX
        m.unlock();
#endif
    }
    void thread1() {
        while (true) {
            wait();
            send("hello ");
        }
    }
    void thread2() {
        wait();
        while (true) {
            wait();
            send("world ");
        }
    }
    void printer() {
        while (1) {
            cout << fifo.read();
        }
    }
    sc_fifo<char> fifo;
    sc_mutex m;
};

int sc_main(int argc, char *argv[]) {
    TestMutex testMutex("testMutex");
    sc_clock clk("clk", 10, SC_NS);
    testMutex.cin(clk);

    sc_start(240, SC_NS);
    cout << endl << "Press enter key:" << endl;
    cin.get();
    return 0;
}
