I'm stuck on some multithreaded programming, hoping someone can enlighten me. Here's the gist of what I'm trying to do:
- Run two threads - one for listening for input, and another for processing input.
- If no input has arrived when the processing thread finishes, it should just re-do its most recent setting.
I am getting hung up on how to communicate that the processing thread is finished, and thus the listener thread should finish its loop and start the next cycle.
Specifically:
Using the code below, I can't get the XC-1A to register any changes I submit to it. I don't see the return value get transmitted, and I don't see the "shutter" port close. The "debug" loop works properly, so I think the problem is not a deadlock with the "process" thread not sending its signal. Is the pinseq on rxd the wrong approach for the select statement?
Is there a better way to debug what the XC-1A is doing, besides xsim? If xsim is the only tool, how can I simulate user input to it?
Code: Select all
int main(void){
chan nChan,setChan,processDone;
char debug;
configure_clock_rate (clk , 50 , 2);
configure_out_port (shutter , clk , 0);
start_clock(clk);
debug=0;
par{
getSettings(nChan,setChan,processDone,debug);
process(nChan,setChan,processDone);
}
return 0;
}
void getSettings(chanend nSetOut, chanend setOut, chanend processDone, char debug){
unsigned char nSettings;
timeset settings[100];
char pDone;
switch (debug)
{
case 1:
{
while(1)
{
nSettings=2;
settings[0].nacqs=4;
settings[0].stime=500;
settings[0].shutterUnits='m'; //milliseconds
settings[0].setupDelay=100;
settings[0].setupUnits='m';
settings[1].nacqs=2;
settings[1].stime=2;
settings[1].shutterUnits='s'; //milliseconds
settings[1].setupDelay=2;
settings[1].setupUnits='s';
nSetOut <: nSettings;
setOut <: settings[0];
setOut <: settings[1];
processDone :> pDone;
}
break;
}
case 0:
{
nSetOut <: 255; // set the shutter initially open
while(1)
{
select
{
case processDone :> pDone: //timeout, process is ready for another round
{
nSetOut <: nSettings;
if (nSettings > 0 && nSettings < 255){
for (int i = 0; i < nSettings; i += 1) {
setOut <: settings[i];
}
}
break;
}
case rxd when pinseq (0) :> void:
{
nSettings=rxByte();
txByte(255);
nSetOut <: nSettings;
if (nSettings > 0 && nSettings < 255)
{
for (int i = 0; i < nSettings; i += 1) {
settings[i].nacqs=rxByte();
settings[i].setupDelay=rxInt();
settings[i].setupUnits=rxByte();
settings[i].stime=rxInt();
settings[i].shutterUnits=rxByte();
setOut <: settings[i];
}
}
break;
}
}
}
break;
}
}
}
void process(chanend nSetIn, chanend setIn, chanend processDone){
timeset settings[100];
int nSettings;
char pDone=1;
while(1){
nSetIn :> nSettings;
if (nSettings == 0){
shutter <: 0;
wait(50000000);
}
else if (nSettings == 255){
shutter <: 1;
wait(50000000);
}
else
{
for (int i = 0; i < nSettings; i+=1){
setIn :> settings[i];
for (int j = 0; j < settings[i].nacqs; j += 1){
setDelay(settings[i].setupDelay,settings[i].setupUnits,0);
//notscan when pinseq (1) :> void;
setDelay(settings[i].stime,settings[i].shutterUnits,1);
//notscan when pinseq (0) :> void;
}
}
}
processDone <: pDone;
}
}