mirror of https://github.com/BOINC/boinc.git
139 lines
3.5 KiB
C++
139 lines
3.5 KiB
C++
// test sporadic app
|
|
//
|
|
// loop
|
|
// wait for NWAIT secs
|
|
// wait for could compute
|
|
// ask to compute (simulate getting a request)
|
|
// when OK, compute for NCOMP secs
|
|
// suspend as needed
|
|
//
|
|
// computing is embedded in the loop.
|
|
// in a real app you'd want to use threads
|
|
|
|
// by default this uses the BOINC API for communicating sporadic state.
|
|
// --wrapped: use files instead (run under wrapper)
|
|
|
|
#define NWAIT 10
|
|
#define NCOMP 10
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#ifndef _WIN32
|
|
#include <unistd.h>
|
|
#endif
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
|
|
#include "boinc_api.h"
|
|
#include "util.h"
|
|
#include "common_defs.h"
|
|
|
|
bool wrapped = false;
|
|
int ac_fd, ca_fd;
|
|
|
|
void compute_one_sec() {
|
|
double start = dtime();
|
|
while (1) {
|
|
double x = 0;
|
|
for (int i=0; i<1e8; i++) {
|
|
x += 1;
|
|
}
|
|
if (dtime() > start+1) break;
|
|
}
|
|
}
|
|
|
|
void set_ac_state(SPORADIC_AC_STATE ac_state) {
|
|
static SPORADIC_AC_STATE last = AC_NONE;
|
|
if (wrapped) {
|
|
if (ac_state != last) {
|
|
char buf[256];
|
|
sprintf(buf, "%d\n", ac_state);
|
|
lseek(ac_fd, 0, SEEK_SET);
|
|
write(ac_fd, buf, strlen(buf));
|
|
}
|
|
last = ac_state;
|
|
} else {
|
|
boinc_sporadic_set_ac_state(ac_state);
|
|
}
|
|
}
|
|
|
|
SPORADIC_CA_STATE get_ca_state() {
|
|
if (wrapped) {
|
|
// could check mod time; don't bother
|
|
char buf[256];
|
|
lseek(ca_fd, 0, SEEK_SET);
|
|
read(ca_fd, buf, sizeof(buf));
|
|
int s;
|
|
int n = sscanf(buf, "%d", &s);
|
|
if (n==1) return (SPORADIC_CA_STATE)s;
|
|
fprintf(stderr, "can't read CA state\n");
|
|
exit(1);
|
|
} else {
|
|
return boinc_sporadic_get_ca_state();
|
|
}
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
SPORADIC_CA_STATE ca_state;
|
|
SPORADIC_AC_STATE ac_state;
|
|
|
|
for (int i=1; i<argc; i++) {
|
|
if (!strcmp(argv[i], "--wrapped")) {
|
|
wrapped = true;
|
|
}
|
|
}
|
|
|
|
if (wrapped) {
|
|
ca_fd = open("ca", O_RDONLY);
|
|
ac_fd = open("ac", O_WRONLY);
|
|
if (ca_fd<0 || ac_fd<0) {
|
|
fprintf(stderr, "can't open files\n");
|
|
exit(1);
|
|
}
|
|
} else {
|
|
boinc_init();
|
|
}
|
|
|
|
fprintf(stderr, "starting\n");
|
|
while (true) {
|
|
// wait for a bit
|
|
ac_state = AC_DONT_WANT_COMPUTE;
|
|
set_ac_state(ac_state);
|
|
for (int i=0; i<NWAIT; i++) {
|
|
fprintf(stderr, "sleep - don't want to compute\n");
|
|
boinc_sleep(1);
|
|
}
|
|
// wait until client says we can possibly compute
|
|
while (1) {
|
|
ca_state = get_ca_state();
|
|
if (ca_state != CA_COULD_COMPUTE) {
|
|
fprintf(stderr, "sleep - waiting for COULD_COMPUTE\n");
|
|
boinc_sleep(1);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
// tell the client we want to compute
|
|
ac_state = AC_WANT_COMPUTE;
|
|
set_ac_state(ac_state);
|
|
int n = NCOMP;
|
|
while (true) {
|
|
// compute only if client says so
|
|
ca_state = get_ca_state();
|
|
fprintf(stderr, "CA state: %d\n", ca_state);
|
|
if (ca_state == CA_COMPUTING) {
|
|
fprintf(stderr, "computing 1 sec\n");
|
|
compute_one_sec();
|
|
n--;
|
|
if (n == 0) {
|
|
fprintf(stderr, "done computing\n");
|
|
break;
|
|
}
|
|
} else {
|
|
fprintf(stderr, "sleep - waiting for COMPUTING\n");
|
|
boinc_sleep(1);
|
|
}
|
|
}
|
|
}
|
|
}
|