// demonstrates thread mailboxes and events
//
// usage: tks thread_mbox_test.tks 1
// -> run in "ping-pong" send/reply mode
//
// tks thread_mbox_test.tks 0
// -> run in "send only" mode (inbox may overflow)
//
// tks thread_mbox_test.tks
// -> first run in "ping-pong", then again in "send-only" mode
//
dtrace false;
//dtrace true;
// 1=wait for reply from slave thread before sending a new message (recommended)
// 0=send anyway (mailbox may overflow)
boolean b_reply;
int sleepTime = 0;
class C {
static Thread t;
define int REPLY_OFF = 1000000;
define int ID_QUIT = 99999999 - REPLY_OFF;
define int NUM_ITERATIONS = 10000;
define int QUEUE_SIZE = 1000;
static int slave_num_recv;
static int slave_num_sent;
static int master_num_recv;
static int master_num_sent;
static MyThreadEntry(local Thread t) {
trace "MyThreadEntry: begin";
local Thread recv <= t.userdata;
while(true)
{
trace "MyThreadEntry: waitEvent()";
local Event ev <= t.waitEvent(0);
slave_num_recv++;
if(b_reply)
{
local Event evReply = ev;
evReply.id += REPLY_OFF;
trace "MyThreadEntry: send reply to ev.id="+ev.id +" evReply.id="+evReply.id;
recv.sendEvent(evReply);
master_num_sent++;
trace "MyThreadEntry: reply sent";
}
if(ID_QUIT == ev.id)
{
stderr "MyThreadEntry: got QUIT event\n";
return;
}
else
{
trace "MyThreadEntry: got event id="+ev.id;
}
}
}
static RunTest() {
trace "RunTest: begin";
slave_num_recv = 0;
slave_num_sent = 0;
master_num_recv = 0;
master_num_sent = 0;
Thread self <= GetCurrentThread();
self.allocEventQueue(QUEUE_SIZE);
t.allocEventQueue(QUEUE_SIZE);
t.userdata = self;
t.create(C.MyThreadEntry);
int k = 1;
loop(NUM_ITERATIONS)
{
Event ev;
ev.id = k;
trace "RunTest: sendEvent id="+k;
t.sendEvent(ev);
slave_num_sent++;
if(sleepTime)
{
TKS.sleep(sleepTime);
}
if(b_reply)
{
trace "RunTest: wait for reply";
Event evReply <= self.waitEvent(0);
trace "RunTest: got reply "+ evReply.id;
master_num_recv++;
}
k++;
}
trace "RunTest: all events sent";
//TKS.sleep(500);
trace "RunTest: send QUIT event";
ev.id = ID_QUIT;
t.sendEvent(ev);
slave_num_sent++;
t.wait();
stderr "RunTest: stats:\n\t slave: sent="+slave_num_sent+" recv="+slave_num_recv+"\n\tmaster: sent="+master_num_sent+" recv="+master_num_recv+"\n";
stderr "RunTest: end\n";
}
}
if(Arguments.numElements)
{
b_reply = Arguments[0];
C.RunTest();
}
else
{
b_reply = false;
C.RunTest();
b_reply = true;
C.RunTest();
}