int main() { int val; int rc; /* Receiver waits for sender. */ int ch1[2]; rc = chmake(ch1); errno_assert(rc == 0); assert(ch1[0] >= 0); assert(ch1[1] >= 0); int hndl1 = go(sender(ch1[0], 1, 333)); errno_assert(hndl1 >= 0); rc = chrecv(ch1[1], &val, sizeof(val), -1); errno_assert(rc == 0); assert(val == 333); rc = hclose(ch1[1]); errno_assert(rc == 0); rc = hclose(ch1[0]); errno_assert(rc == 0); rc = hclose(hndl1); errno_assert(rc == 0); /* Sender waits for receiver. */ int ch2[2]; rc = chmake(ch2); errno_assert(rc == 0); int hndl2 = go(sender(ch2[0], 0, 444)); errno_assert(hndl2 >= 0); rc = chrecv(ch2[1], &val, sizeof(val), -1); errno_assert(rc == 0); assert(val == 444); rc = hclose(ch2[1]); errno_assert(rc == 0); rc = hclose(ch2[0]); errno_assert(rc == 0); rc = hclose(hndl2); errno_assert(rc == 0); /* Test two simultaneous senders. */ int ch3[2]; rc = chmake(ch3); errno_assert(rc == 0); int hndl3[2]; hndl3[0] = go(sender(ch3[0], 0, 888)); errno_assert(hndl3[0] >= 0); hndl3[1] = go(sender(ch3[0], 0, 999)); errno_assert(hndl3[1] >= 0); rc = chrecv(ch3[1], &val, sizeof(val), -1); errno_assert(rc == 0); assert(val == 888); rc = yield(); errno_assert(rc == 0); rc = chrecv(ch3[1], &val, sizeof(val), -1); errno_assert(rc == 0); assert(val == 999); rc = hclose(ch3[1]); errno_assert(rc == 0); rc = hclose(ch3[0]); errno_assert(rc == 0); rc = hclose(hndl3[0]); errno_assert(rc == 0); rc = hclose(hndl3[1]); errno_assert(rc == 0); /* Test two simultaneous receivers. */ int ch4[2]; rc = chmake(ch4); errno_assert(rc == 0); int hndl4[2]; hndl4[0] = go(receiver(ch4[0], 333)); errno_assert(hndl4[0] >= 0); hndl4[1] = go(receiver(ch4[0], 444)); errno_assert(hndl4[1] >= 0); val = 333; rc = chsend(ch4[1], &val, sizeof(val), -1); errno_assert(rc == 0); val = 444; rc = chsend(ch4[1], &val, sizeof(val), -1); errno_assert(rc == 0); rc = hclose(ch4[1]); errno_assert(rc == 0); rc = hclose(ch4[0]); errno_assert(rc == 0); rc = hclose(hndl4[0]); errno_assert(rc == 0); rc = hclose(hndl4[1]); errno_assert(rc == 0); /* Test simple chdone() scenario. */ int ch8[2]; rc = chmake(ch8); errno_assert(rc == 0); rc = chdone(ch8[0]); errno_assert(rc == 0); rc = chrecv(ch8[1], &val, sizeof(val), -1); errno_assert(rc == -1 && errno == EPIPE); rc = chrecv(ch8[1], &val, sizeof(val), -1); errno_assert(rc == -1 && errno == EPIPE); rc = chrecv(ch8[1], &val, sizeof(val), -1); errno_assert(rc == -1 && errno == EPIPE); rc = hclose(ch8[1]); errno_assert(rc == 0); rc = hclose(ch8[0]); errno_assert(rc == 0); /* Test whether chdone() unblocks all receivers. */ int ch12[2]; rc = chmake(ch12); errno_assert(rc == 0); int hndl6[2]; hndl6[0] = go(receiver2(ch12[0])); errno_assert(hndl6[0] >= 0); hndl6[1] = go(receiver2(ch12[0])); errno_assert(hndl6[1] >= 0); rc = chdone(ch12[1]); errno_assert(rc == 0); rc = chrecv(ch12[1], &val, sizeof(val), -1); errno_assert(rc == 0); assert(val == 0); rc = chrecv(ch12[1], &val, sizeof(val), -1); errno_assert(rc == 0); assert(val == 0); rc = hclose(ch12[1]); errno_assert(rc == 0); rc = hclose(ch12[0]); errno_assert(rc == 0); rc = hclose(hndl6[0]); errno_assert(rc == 0); rc = hclose(hndl6[1]); errno_assert(rc == 0); /* Test whether chdone() unblocks blocked senders. */ int ch15[2]; rc = chmake(ch15); errno_assert(rc == 0); int hndl8[3]; hndl8[0] = go(sender2(ch15[0])); errno_assert(hndl8[0] >= 0); hndl8[1] = go(sender2(ch15[0])); errno_assert(hndl8[1] >= 0); hndl8[2] = go(sender2(ch15[0])); errno_assert(hndl8[2] >= 0); rc = msleep(now() + 50); errno_assert(rc == 0); rc = chdone(ch15[1]); errno_assert(rc == 0); rc = hclose(ch15[1]); errno_assert(rc == 0); rc = hclose(ch15[0]); errno_assert(rc == 0); rc = hclose(hndl8[0]); errno_assert(rc == 0); rc = hclose(hndl8[1]); errno_assert(rc == 0); rc = hclose(hndl8[2]); errno_assert(rc == 0); /* Test whether hclose() unblocks blocked senders and receivers. */ int ch16[2]; rc = chmake(ch16); errno_assert(rc == 0); int hndl9[2]; hndl9[0] = go(receiver3(ch16[0])); errno_assert(hndl9[0] >= 0); hndl9[1] = go(receiver3(ch16[0])); errno_assert(hndl9[1] >= 0); rc = msleep(now() + 50); errno_assert(rc == 0); rc = hclose(ch16[1]); errno_assert(rc == 0); rc = hclose(ch16[0]); errno_assert(rc == 0); rc = hclose(hndl9[0]); errno_assert(rc == 0); rc = hclose(hndl9[1]); errno_assert(rc == 0); /* Test cancelation. */ int ch17[2]; rc = chmake(ch17); errno_assert(rc == 0); int hndl10 = go(cancel(ch17[0])); errno_assert(hndl10 >= 0); rc = hclose(hndl10); errno_assert(rc == 0); rc = hclose(ch17[1]); errno_assert(rc == 0); rc = hclose(ch17[0]); errno_assert(rc == 0); /* Receiver waits for sender (zero-byte message). */ int ch18[2]; rc = chmake(ch18); errno_assert(rc == 0); int hndl11 = go(sender3(ch18[0], 1)); errno_assert(hndl11 >= 0); rc = chrecv(ch18[1], NULL, 0, -1); errno_assert(rc == 0); rc = hclose(ch18[1]); errno_assert(rc == 0); rc = hclose(ch18[0]); errno_assert(rc == 0); rc = hclose(hndl11); errno_assert(rc == 0); /* Sender waits for receiver (zero-byte message). */ int ch19[2]; rc = chmake(ch19); errno_assert(rc == 0); int hndl12 = go(sender3(ch19[0], 0)); errno_assert(hndl12 >= 0); rc = chrecv(ch19[1], NULL, 0, -1); errno_assert(rc == 0); rc = hclose(ch19[1]); errno_assert(rc == 0); rc = hclose(ch19[0]); errno_assert(rc == 0); rc = hclose(hndl12); errno_assert(rc == 0); /* Channel with user-supplied storage. */ struct chstorage mem; int ch20[2]; rc = chmake_mem(&mem, ch20); errno_assert(rc == 0); rc = chrecv(ch20[0], NULL, 0, now() + 50); errno_assert(rc == -1 && errno == ETIMEDOUT); rc = hclose(ch20[1]); errno_assert(rc == 0); rc = hclose(ch20[0]); errno_assert(rc == 0); return 0; }
void fork_off_workers(void) { /* Fork off the two workers, M0 and M1. */ if (fork() != 0) { /* This is the Parent. It will become main, but first fork off M1. */ if (fork() != 0) { /* This is main. */ sigaction(SIGPIPE, &act, &oact); setvbuf(stdout, (char *)0, _IONBF, (size_t)0);/*don't buffer*/ close(r1); close(w1); close(r2); close(w2); close(r3); close(w4); close(r5); close(w6); return; } else { /* This is the code for M1. Run protocol. */ sigaction(SIGPIPE, &act, &oact); setvbuf(stdout, (char *)0, _IONBF, (size_t)0);/*don't buffer*/ close(w1); close(r2); close(r3); close(w3); close(r4); close(w4); close(w5); close(r6); id = 1; /* M1 gets id 1 */ mrfd = r5; /* fd for reading time from main */ mwfd = w6; /* fd for writing reply to main */ prfd = r1; /* fd for reading frames from worker 0 */ switch(protocol) { case 2: receiver2(); break; case 3: receiver3(); break; case 4: protocol4(); break; case 5: protocol5(); break; case 6: protocol6(); break; } terminate("Impossible. Protocol terminated"); } } else { /* This is the code for M0. Run protocol. */ sigaction(SIGPIPE, &act, &oact); setvbuf(stdout, (char *)0, _IONBF, (size_t)0);/*don't buffer*/ close(r1); close(w2); close(w3); close(r4); close(r5); close(w5); close(r6); id = 0; /* M0 gets id 0 */ mrfd = r3; /* fd for reading time from main */ mwfd = w4; /* fd for writing reply to main */ prfd = r2; /* fd for reading frames from worker 1 */ switch(protocol) { case 2: sender2(); break; case 3: sender3(); break; case 4: protocol4(); break; case 5: protocol5(); break; case 6: protocol6(); break; } terminate("Impossible. protocol terminated"); } }
int main() { int rc; int val; /* Non-blocking receiver case. */ int ch1 = chmake(sizeof(int)); errno_assert(ch1 >= 0); int hndl1 = go(sender1(ch1, 555)); errno_assert(hndl1 >= 0); struct chclause cls1[] = {{CHRECV, ch1, &val, sizeof(val)}}; rc = choose(cls1, 1, -1); choose_assert(0, 0); assert(val == 555); hclose(ch1); rc = hclose(hndl1); errno_assert(rc == 0); /* Blocking receiver case. */ int ch2 = chmake(sizeof(int)); errno_assert(ch2 >= 0); int hndl2 = go(sender2(ch2, 666)); errno_assert(hndl2 >= 0); struct chclause cls2[] = {{CHRECV, ch2, &val, sizeof(val)}}; rc = choose(cls2, 1, -1); choose_assert(0, 0); assert(val == 666); hclose(ch2); rc = hclose(hndl2); errno_assert(rc == 0); /* Non-blocking sender case. */ int ch3 = chmake(sizeof(int)); errno_assert(ch3 >= 0); int hndl3 = go(receiver1(ch3, 777)); errno_assert(hndl3 >= 0); val = 777; struct chclause cls3[] = {{CHSEND, ch3, &val, sizeof(val)}}; rc = choose(cls3, 1, -1); choose_assert(0, 0); hclose(ch3); rc = hclose(hndl3); errno_assert(rc == 0); /* Blocking sender case. */ int ch4 = chmake(sizeof(int)); errno_assert(ch4 >= 0); int hndl4 = go(receiver2(ch4, 888)); errno_assert(hndl4 >= 0); val = 888; struct chclause cls4[] = {{CHSEND, ch4, &val, sizeof(val)}}; rc = choose(cls4, 1, -1); choose_assert(0, 0); hclose(ch4); rc = hclose(hndl4); errno_assert(rc == 0); /* Check with two channels. */ int hndl5[2]; int ch5 = chmake(sizeof(int)); errno_assert(ch5 >= 0); int ch6 = chmake(sizeof(int)); errno_assert(ch6 >= 0); hndl5[0] = go(sender1(ch6, 555)); errno_assert(hndl5 >= 0); struct chclause cls5[] = { {CHRECV, ch5, &val, sizeof(val)}, {CHRECV, ch6, &val, sizeof(val)} }; rc = choose(cls5, 2, -1); choose_assert(1, 0); assert(val == 555); hndl5[1] = go(sender2(ch5, 666)); errno_assert(hndl5 >= 0); rc = choose(cls5, 2, -1); choose_assert(0, 0); assert(val == 666); hclose(ch5); hclose(ch6); rc = hclose(hndl5[0]); errno_assert(rc == 0); rc = hclose(hndl5[1]); errno_assert(rc == 0); /* Test whether selection of in channels is random. */ int ch7 = chmake(sizeof(int)); errno_assert(ch7 >= 0); int ch8 = chmake(sizeof(int)); errno_assert(ch8 >= 0); int hndl6[2]; hndl6[0] = go(feeder(ch7, 111)); errno_assert(hndl6[0] >= 0); hndl6[1] = go(feeder(ch8, 222)); errno_assert(hndl6[1] >= 0); int i; int first = 0; int second = 0; int third = 0; for(i = 0; i != 100; ++i) { struct chclause cls6[] = { {CHRECV, ch7, &val, sizeof(val)}, {CHRECV, ch8, &val, sizeof(val)} }; rc = choose(cls6, 2, -1); errno_assert(rc == 0 || rc == 1); if(rc == 0) { assert(val == 111); ++first; } if(rc == 1) { assert(val == 222); ++second; } int rc = yield(); errno_assert(rc == 0); } assert(first > 1 && second > 1); hclose(hndl6[0]); hclose(hndl6[1]); hclose(ch7); hclose(ch8); /* Test 'otherwise' clause. */ int ch9 = chmake(sizeof(int)); errno_assert(ch9 >= 0); struct chclause cls7[] = {{CHRECV, ch9, &val, sizeof(val)}}; rc = choose(cls7, 1, 0); choose_assert(-1, ETIMEDOUT); hclose(ch9); rc = choose(NULL, 0, 0); choose_assert(-1, ETIMEDOUT); /* Test two simultaneous senders vs. choose statement. */ int ch10 = chmake(sizeof(int)); errno_assert(ch10 >= 0); int hndl7[2]; hndl7[0] = go(sender1(ch10, 888)); errno_assert(hndl7[0] >= 0); hndl7[1] = go(sender1(ch10, 999)); errno_assert(hndl7[1] >= 0); val = 0; struct chclause cls8[] = {{CHRECV, ch10, &val, sizeof(val)}}; rc = choose(cls8, 1, -1); choose_assert(0, 0); assert(val == 888); val = 0; rc = choose(cls8, 1, -1); choose_assert(0, 0); assert(val == 999); hclose(ch10); rc = hclose(hndl7[0]); errno_assert(rc == 0); rc = hclose(hndl7[1]); errno_assert(rc == 0); /* Test two simultaneous receivers vs. choose statement. */ int ch11 = chmake(sizeof(int)); errno_assert(ch11 >= 0); int hndl8[2]; hndl8[0] = go(receiver1(ch11, 333)); errno_assert(hndl8[0] >= 0); hndl8[1] = go(receiver1(ch11, 444)); errno_assert(hndl8[1] >= 0); val = 333; struct chclause cls9[] = {{CHSEND, ch11, &val, sizeof(val)}}; rc = choose(cls9, 1, -1); choose_assert(0, 0); val = 444; rc = choose(cls9, 1, -1); choose_assert(0, 0); hclose(ch11); rc = hclose(hndl8[0]); errno_assert(rc == 0); rc = hclose(hndl8[1]); errno_assert(rc == 0); /* Choose vs. choose. */ int ch12 = chmake(sizeof(int)); errno_assert(ch12 >= 0); int hndl9 = go(choosesender(ch12, 111)); errno_assert(hndl9 >= 0); struct chclause cls10[] = {{CHRECV, ch12, &val, sizeof(val)}}; rc = choose(cls10, 1, -1); choose_assert(0, 0); assert(val == 111); hclose(ch12); rc = hclose(hndl9); errno_assert(rc == 0); /* Test transferring a large object. */ int ch17 = chmake(sizeof(struct large)); errno_assert(ch17 >= 0); int hndl10 = go(sender4(ch17)); errno_assert(hndl9 >= 0); struct large lrg; struct chclause cls14[] = {{CHRECV, ch17, &lrg, sizeof(lrg)}}; rc = choose(cls14, 1, -1); choose_assert(0, 0); hclose(ch17); /* Test that 'in' on done-with channel fires. */ int ch18 = chmake(sizeof(int)); errno_assert(ch18 >= 0); rc = hdone(ch18); errno_assert(rc == 0); struct chclause cls15[] = {{CHRECV, ch18, &val, sizeof(val)}}; rc = choose(cls15, 1, -1); choose_assert(0, EPIPE); hclose(ch18); /* Test expiration of 'deadline' clause. */ int ch21 = chmake(sizeof(int)); errno_assert(ch21 >= 0); int64_t start = now(); struct chclause cls17[] = {{CHRECV, ch21, &val, sizeof(val)}}; rc = choose(cls17, 1, start + 50); choose_assert(-1, ETIMEDOUT); int64_t diff = now() - start; time_assert(diff, 50); hclose(ch21); /* Test unexpired 'deadline' clause. */ int ch22 = chmake(sizeof(int)); errno_assert(ch22 >= 0); start = now(); int hndl11 = go(sender3(ch22, 4444, start + 50)); errno_assert(hndl11 >= 0); struct chclause cls18[] = {{CHRECV, ch22, &val, sizeof(val)}}; rc = choose(cls17, 1, start + 1000); choose_assert(0, 0); assert(val == 4444); diff = now() - start; time_assert(diff, 50); hclose(ch22); rc = hclose(hndl11); errno_assert(rc == 0); /* Test that first channel in the array is prioritized. */ int ch23 = chmake(sizeof(int)); errno_assert(ch23 >= 0); int ch24 = chmake(sizeof(int)); errno_assert(ch24 >= 0); int hndl12 = go(sender1(ch23, 0)); errno_assert(hndl12 >= 0); int hndl13 = go(sender1(ch24, 0)); errno_assert(hndl13 >= 0); struct chclause cls19[] = { {CHRECV, ch24, &val, sizeof(val)}, {CHRECV, ch23, &val, sizeof(val)} }; rc = choose(cls19, 2, -1); choose_assert(0, 0); rc = chrecv(ch23, &val, sizeof(val), -1); errno_assert(rc == 0); rc = hclose(hndl13); errno_assert(rc == 0); rc = hclose(hndl12); errno_assert(rc == 0); rc = hclose(ch24); errno_assert(rc == 0); rc = hclose(ch23); errno_assert(rc == 0); /* Try adding the same channel to choose twice. Doing so is pointless, but it shouldn't crash the application. */ int ch25 = chmake(sizeof(int)); errno_assert(ch25 >= 0); struct chclause cls20[] = { {CHRECV, ch25, &val, sizeof(val)}, {CHRECV, ch25, &val, sizeof(val)} }; rc = choose(cls20, 2, now() + 50); choose_assert(-1, ETIMEDOUT); rc = hclose(ch25); errno_assert(rc == 0); return 0; }
int sc_main(int argc, char *argv[]) { sc_signal<pkt> pkt_in0; sc_signal<pkt> pkt_in1; sc_signal<pkt> pkt_in2; sc_signal<pkt> pkt_in3; sc_signal<pkt> pkt_out0; sc_signal<pkt> pkt_out1; sc_signal<pkt> pkt_out2; sc_signal<pkt> pkt_out3; sc_signal<sc_int<4> > id0, id1, id2, id3; sc_signal<bool> switch_cntrl; sc_clock clock1("CLOCK1", 75, SC_NS, 0.5, 0.0, SC_NS); sc_clock clock2("CLOCK2", 30, SC_NS, 0.5, 10.0, SC_NS); // Module instiatiations follow // Note that modules can be connected by hooking up ports // to signals by name or by using a positional notation sender sender0("SENDER0"); // hooking up signals to ports by name sender0.pkt_out(pkt_in0); sender0.source_id(id0); sender0.CLK(clock1); sender sender1("SENDER1"); // hooking up signals to ports by position sender1(pkt_in1, id1, clock1); sender sender2("SENDER2"); // hooking up signals to ports by name sender2.pkt_out(pkt_in2); sender2.source_id(id2); sender2.CLK(clock1); sender sender3("SENDER3"); // hooking up signals to ports by position sender3( pkt_in3, id3, clock1 ); switch_clk switch_clk1("SWITCH_CLK"); // hooking up signals to ports by name switch_clk1.switch_cntrl(switch_cntrl); switch_clk1.CLK(clock2); mcast_pkt_switch switch1("SWITCH"); // hooking up signals to ports by name switch1.switch_cntrl(switch_cntrl); switch1.in0(pkt_in0); switch1.in1(pkt_in1); switch1.in2(pkt_in2); switch1.in3(pkt_in3); switch1.out0(pkt_out0); switch1.out1(pkt_out1); switch1.out2(pkt_out2); switch1.out3(pkt_out3); receiver receiver0("RECEIVER0"); // hooking up signals to ports by name receiver0.pkt_in(pkt_out0); receiver0.sink_id(id0); receiver receiver1("RECEIVER1"); // hooking up signals to ports by position receiver1( pkt_out1, id1 ); receiver receiver2("RECEIVER2"); // hooking up signals to ports by name receiver2.pkt_in(pkt_out2); receiver2.sink_id(id2); receiver receiver3("RECEIVER3"); // hooking up signals to ports by position receiver3( pkt_out3, id3 ); sc_start(0, SC_NS); #if !defined(__SUNPRO_CC) id0.write(0); id1.write(1); id2.write(2); id3.write(3); #else // you cannot do that with SC5.0 // since it doesn't support member templates id0.write(sc_int<4>(0)); id0.write(sc_int<4>(1)); id0.write(sc_int<4>(2)); id0.write(sc_int<4>(3)); #endif sc_start(); return 0; }