static inline void newcore(subroutine foo, const int flags) { int fd[2]; pid_t pid; int core = nlaunched++; assert( socketpair(AF_LOCAL, SOCK_STREAM, 0, fd) != -1 && (pid = fork()) != -1 ); if( pid ) { MASTER("forked core %d pid %d pipe %d(master) -> %d(worker) seq %llx", core, pid, fd[0], fd[1], mem_seq); close(fd[1]); child[core].fd = fd[0]; child[core].seq = mem_seq; FD_SET(fd[0], &children); fdmax = IMax(fd[0], fdmax); return; } close(fd[0]); for( ; ; ) { RealType res[NCOMP]; seq_t seq = mem_seq; res[0] = res[1] = 0; foo(res, &flags); WORKER(core, "writing result(%ld)", sizeof res); writesock(fd[1], res, sizeof res); WORKER(core, "reading mem_hel(%p#%ld)", mem.h, mem.he - mem.h); if( !readsock(fd[1], mem.h, mem.he - mem.h) ) exit(0); WORKER(core, "seq %llx new %llx", seq, mem_seq); seq ^= mem_seq; if( SEQ_ANGLE(seq) ) { WORKER(core, "reading mem_angle(%p#%ld+%p#%ld)", mem.v, mem.ve - mem.v, mem.a, mem.ae - mem.a); readsock(fd[1], mem.v, mem.ve - mem.v); readsock(fd[1], mem.a, mem.ae - mem.a); restorecache_(); } if( SEQ_S(seq) ) { WORKER(core, "reading mem_s(%p#%ld)", mem.s, mem.se - mem.s); readsock(fd[1], mem.s, mem.se - mem.s); clearcache_(); } seq = mem_seq; } }
static inline void Child(cint fd, cint core) { dispatch d; while( readsock(fd, &d, sizeof d) == sizeof d ) { if( d.thissize ) { MemAlloc(d.thisptr, d.thissize); WORKER("reading This (%lu)", d.thissize); readsock(fd, d.thisptr, d.thissize); } WORKER("running %p on fd %d", d.thisptr, fd); d.worker(d.thisptr, d.thissize, core, fd); if( d.thissize ) free(d.thisptr); } }