#include #include #include #include "queue.h" char msg[] = "hello, world!"; int msglen = 13; void writeproc(void *v) { int i; Queue *q; q = v; for(i = 0; i < 100; i++){ qwrite(q, msg, strlen(msg)); } qclose(q); } void readproc(void *v) { long n; char buf[512]; Queue *q; q = v; while((n = qread(q, buf, sizeof(buf))) > 0){ buf[n] = 0; fprint(2, "qread %s\n", buf); } fprint(2, "qread: %r\n"); } void intrproc(void *v) { char buf[1]; void **vv; Queue *q; Channel *quitc; vv = v; q = vv[0]; quitc = vv[1]; qread(q, buf, sizeof(buf)); chanclose(quitc); threadexits(nil); } void timerproc(void *v) { Channel *timerc; ulong ms; void **vv; vv = v; timerc = vv[0]; ms = (ulong)(uintptr)vv[1]; sleep(ms); sendul(timerc, ms); chanclose(timerc); threadexits(nil); } static void q_test_interrupt(void) { int rpid, tpid; Channel *quitc, *timerc; void *arg[2]; Queue *q; quitc = chancreate(sizeof(int), 0); timerc = chancreate(sizeof(ulong), 0); q = qopen(8*1024, 0, nil, nil); /* setup reader */ arg[0] = q; arg[1] = quitc; rpid = proccreate(intrproc, arg, 8192); /* setup timer */ arg[0] = timerc; arg[1] = (void*)100; /* ms */ tpid = proccreate(timerproc, arg, 8192); /* fire the interrupt, and wait for it */ threadint(rpid); Alt a[] = { { quitc, nil, CHANRCV }, { timerc, nil, CHANRCV }, { nil, nil, CHANEND }, }; switch(alt(a)){ case 0: /* success */ break; case 1: /* timer fired before interrupt succeeded */ sysfatal("q_test_interrupt: timed out"); } chanfree(quitc); chanfree(timerc); qfree(q); } static void q_test_coalesce(void) { int n; char buf[32]; Queue *q; q = qopen(8*1024, Qcoalesce, nil, nil); /* 2 writes */ if(qwrite(q, msg, msglen) < 0) sysfatal("q_test_coalesce: qwrite failed: %r"); if(qwrite(q, msg, msglen) < 0) sysfatal("q_test_coalesce qwrite failed: %r"); /* ensure a qread gets both of the writes */ n = qread(q, buf, sizeof(buf)); if(n < 0){ fprint(2, "q_test_coalesce: short read: %r"); qfree(q); return; } buf[n] = 0; if(n != msglen*2) sysfatal("q_test_coalesce: wrong read size %d", n); if(strncmp(buf, msg, msglen) != 0 || strncmp(buf+msglen, msg, msglen) != 0){ fprint(2, "'%s' '%s'\n", buf, buf+msglen); sysfatal("q_test_coalesce: wrong message read: '%s'", buf); } qfree(q); } static void q_test_rw(void) { int n; char buf[32]; Queue *q; q = qopen(8*1024, 0, nil, nil); /* 2 writes */ if(qwrite(q, msg, msglen) < 0) sysfatal("q_test_rw: qwrite failed: %r"); if(qwrite(q, msg, msglen) < 0) sysfatal("q_test_rw: qwrite failed: %r"); /* ensure a qread gets one of the writes */ n = qread(q, buf, sizeof(buf)); if(n < 0){ fprint(2, "q_test_rw: short read: %r"); qfree(q); return; } buf[n] = 0; if(n != msglen) sysfatal("q_test_rw: wrong read size %d", n); if(strcmp(buf, msg) != 0) sysfatal("q_test_rw: wrong message read: '%s'", buf); qfree(q); } void threadmain(int argc, char *argv[]) { ARGBEGIN{ }ARGEND q_test_rw(); q_test_coalesce(); q_test_interrupt(); print("pass\n"); threadexitsall(nil); }