1) The question is how should I handle the control tokens so all clients can send data-messages?
2) What happens with a token on a loose channel-end that hasn't a receiver, is it killed by the switch or is it trapped in a FIFO ?
This program receives a package of data from any core, but all other clients become trapped at
chkct, since the CT_END token they sent ended up somewhere else, killed or trapped ??
It's easier to read the program from the bottom.
The main() is rather easy to understand.
Code: Select all
#define CT_END 1
#define CT_PAUSE 2
#define CT_ACK 3
#define CT_NACK 4
#define len 8
static inline
int TESTCT(unsigned Chanend) {
int ret;
asm("testct %0,res[%1]":"=r"(ret) : "r"(Chanend));
return ret;
}
static inline
void OUTCT_END(unsigned Chanend) {
asm("outct res[%0],%1" ::"r"(Chanend),"r"(CT_END));
}
static inline
void OUTCHK_END(unsigned Chanend) {
asm("chkct res[%0],%1" ::"r"(Chanend),"r"(CT_END));
}
static inline
void SETD_CLIENT(unsigned Chanend, unsigned ServerCore) {
asm("setd res[%0],%1" ::"r"(Chanend),"r"((ServerCore<<16)+0x102));
}
static inline
void SETD_SERVER(unsigned Chanend, unsigned ClientCore) {
asm("setd res[%0],%1" ::"r"(Chanend),"r"((ClientCore<<16)+0x102));
}
static inline
unsigned GETR_CHANEND() {
unsigned Chanend;
asm("getr %0,2":"=r"(Chanend));
return Chanend;
}
void client(unsigned sh, unsigned ServerCore) {
unsigned Chanend;
Chanend = GETR_CHANEND();
SETD_CLIENT(Chanend, ServerCore);
OUTCT_END(Chanend);
OUTCHK_END(Chanend);
for (int i = 0; i < len; i++)
asm("out res[%0],%1" ::"r"(Chanend),"r"(i<<sh));
OUTCT_END(Chanend);
OUTCHK_END(Chanend);
}
void server(unsigned startScan,unsigned stopScan) {
unsigned Chanend;
int data;
unsigned ClientChanEnd;
Chanend = GETR_CHANEND();
while (1) {
for (int i = startScan; i <= stopScan; i++) {
ClientChanEnd = (i << 16) + 0x102;
if (TESTCT(ClientChanEnd)) {
SETD_SERVER(Chanend, i);
OUTCHK_END(Chanend);
OUTCT_END(Chanend);
for (int i = 0; i < len; i++) {
asm("in %0,res[%1] ":"=r"(data):"r"(Chanend));
printint(data);
printstr(", ");
}
OUTCHK_END(Chanend);
OUTCT_END(Chanend);
printstrln(" END");
}
}
}
}
int main() {
par {
on stdcore[0]:client(1, 3); //3 == Server is on stdcore[3]
on stdcore[1]:client(2, 3); //3 == Server is on stdcore[3]
on stdcore[2]:client(3, 3); //3 == Server is on stdcore[3]
on stdcore[3]:server(0,2); //0,2 == Scan clients from stdcore[0] to stdcore[2]
}
}