static void maos_server(PARMS_T *parms){ if(maos_server_fd<0){ error("Invalid maos_server_fd\n"); EXIT; } warning("maos running in server mode\n"); int msglen; int sock=maos_server_fd; while(!streadint(sock, &msglen)){ int ret=0;/*acknowledgement of the command. 0: accepted. otherwise: not understood*/ int *msg=alloca(sizeof(int)*msglen); if(streadintarr(sock, msg, msglen)){ break; } switch(msg[0]){ case MAOS_ASSIGN_WFS:{/*Specifies which WFS to be handled*/ for(int iwfs=0; iwfs<parms->nwfs; iwfs++){ parms->wfs[iwfs].sock=msg[iwfs+1]?-1:0; } }break; case MAOS_ASSIGN_EVL:{/*Specifies which EVL to be handled*/ if(!parms->evl.sock){ parms->evl.sock=calloc(parms->evl.nevl, sizeof(int)); } for(int ievl=0; ievl<parms->evl.nevl; ievl++){ parms->evl.sock->p[ievl]=msg[ievl+1]?-1:0; } }break; case MAOS_ASSIGN_RECON:{/*Specifies whether recon should be handled*/ parms->recon.sock=msg[1]?-1:0; }break; case MAOS_ASSIGN_DONE:{/*Now start configuration*/ error("Not completed\n"); }break; default: ret=1; }/*switch*/ if(stwriteint(sock, ret)){ break; } } warning("maos_server exited\n"); //todo:listening on socket for commands. //maos client mode: start maos server mode via scheduler. }
static void maos_daemon(int sock){ //info2("maos_daemon is listening at %d\n", sock); thread_block_signal(); int cmd[2]; while(!streadintarr(sock, cmd, 2)){ //info2("maos_daemon got %d at %d\n", cmd[0], sock); switch(cmd[0]){ case MAOS_SERVER: { if(streadfd(sock, &maos_server_fd)){ warning("unable to read fd from %d\n", sock); maos_server_fd=-1; EXIT; }else{ warning("got fd=%d\n", maos_server_fd); } }break; case MAOS_DRAW: { int fd; if(streadfd(sock, &fd)){ warning("unable to read fd from %d\n", sock); continue; }else{ warning("got fd=%d\n", fd); } draw_add(fd); PARMS_T *parms=(PARMS_T*)global->parms;//cast away constness parms->plot.setup=1; parms->plot.run=1; if(global->setupdone){//already plotted. plot_setup(global->parms, global->powfs, global->aper, global->recon); } }break; default: warning("unknown cmd %d\n", cmd[0]); break; } } //info2("maos_daemon quit\n"); }
/** called by monitor to let a MAOS job remotely draw on this computer */ int scheduler_display(int ihost, int pid){ /*connect to scheduler with a new port. The schedule pass the other end of the port to drawdaemon so we can communicate with it.*/ int sock=connect_port(hosts[ihost], PORT, 0, 0); int ans=1; int cmd[2]={CMD_DISPLAY, pid}; if(stwriteintarr(sock, cmd, 2)){ warning("Failed to communicate to scheduler\n"); close(sock); } if(streadintarr(sock, cmd, 1)){ warning("Read response failed\n"); }else if(cmd[0]){ warning("The scheduler failed to talk to maos\n"); }else{ if(spawn_drawdaemon(sock)){ warning("spwn drawdaemon failed\n"); }else{ ans=0; } close(sock); } return ans; }
//respond to scheduler static int respond(int sock){ int cmd[3]; //read fixed length header info. if(streadintarr(sock, cmd, 3)){ return -1;//failed } int ihost=host_from_sock(sock); if(ihost>=0){ htime[ihost]=myclockd(); } int pid=cmd[2]; switch(cmd[0]){ case -1:{//server request shutdown info("disconnect from %s\n", hosts[ihost]); return -1; } break; case MON_VERSION: break; case MON_STATUS: { if(ihost<0){ warning("Host not found\n"); return -1; } PROC_T *p=proc_get(ihost,pid); if(!p){ p=proc_add(ihost,pid); } if(stread(sock, &p->status, sizeof(STATUS_T))){ return -1; } if(p->status.info==S_REMOVE){ proc_remove(ihost, pid); }else{ if(cmd[1]!=ihost && cmd[1]!=cmd[2]){ /*A new mean to replace the ID of a job.*/ p->pid=cmd[1]; } gdk_threads_add_idle((GSourceFunc)refresh, p); } } break; case MON_PATH: { if(ihost<0){ warning("Host not found\n"); return -1; } PROC_T *p=proc_get(ihost,pid); if(!p){ p=proc_add(ihost,pid); } if(streadstr(sock, &p->path)){ return -1; } char *tmp=NULL; while((tmp=strchr(p->path, '\n'))){ tmp[0]=' '; } } break; case MON_LOAD: { if(ihost<0){ warning("Host not found\n"); return -1; } usage_cpu[ihost]=(double)((pid>>16) & 0xFFFF)/100.; usage_mem[ihost]=(double)(pid & 0xFFFF)/100.; usage_cpu[ihost]=MAX(MIN(1,usage_cpu[ihost]),0); usage_mem[ihost]=MAX(MIN(1,usage_mem[ihost]),0); gdk_threads_add_idle((GSourceFunc)update_progress, GINT_TO_POINTER(ihost)); } break; case MON_ADDHOST: if(cmd[1]>-1 && cmd[1]<nhost){ pthread_t tmp; pthread_create(&tmp, NULL, (void*(*)(void*))add_host, GINT_TO_POINTER(cmd[1])); }else if(cmd[1]==-2){ return -2; } break; default: warning_time("Invalid cmd %d\n",cmd[0]); return -1; } return 0; }
//server for mvmfull_real int mvm_server(int sock){ int cmd[7]; if(streadintarr(sock, cmd, 7)){ return -1; } int nact=cmd[0]; int nsa=cmd[1]; int sastep=cmd[2]; int totpix=cmd[3]; int pixpsa=totpix; int nstep=cmd[4]; int nstep0=cmd[5]; int type=cmd[6]; dbg("type=%d, nact=%d, nsa=%d, sastep=%d, %s=%d, nstep=%d\n",type, nact, nsa, sastep, type==1?"pixpsa":"totpix", totpix, nstep); int *saind=NULL; if(type==1){//mvmfull_iwfs totpix=pixpsa*nsa; }else{//mvmfull_real saind=mymalloc((nsa+1),int); if(streadintarr(sock, saind, nsa+1)){ return -1; } } short *pix=mymalloc(totpix,short); if(type==1){ rand_t rseed; seed_rand(&rseed, 1); for(int i=0; i<totpix; i++){ pix[i]=(short)randu(&rseed); } }else{ if(stread(sock, pix, totpix*sizeof(short))){ return -1; } } smat *dmres=snew(nact, 1); int ready; streadint(sock, &ready); //wait for client to be ready. #if __linux__ struct timespec ct; clock_gettime(CLOCK_MONOTONIC, &ct); int readtime_ns=500000;//500 micro-second read out time. int frametime_ns=1250000;//frame time. int nsend=((nsa+sastep-1)/sastep);//number of segments sent along read out int int1_ns=readtime_ns/nsend;//interval between segment sending int int2_ns=frametime_ns-readtime_ns;//interval after last segment. #endif TIC;tic; for(int istep=-nstep0; istep<nstep; istep++){ //info("\rSend trigger "); #if __linux__ //scheduled start time of the frame. double tk0=(double)ct.tv_sec+(double)ct.tv_nsec*1.e-9; #else tic; #endif for(int isa=0; isa<nsa; isa+=sastep){ #if __linux__ if(clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ct, NULL)){ warning("clock_nanosleep is interrupted\n"); } if(isa==0){ tic; } #endif int nleft; if(type==1){ nleft=((nsa-isa)<sastep?(nsa-isa):sastep)*pixpsa; }else{ if(nsa<isa+sastep){//terminate nleft=totpix-saind[isa]; }else{ nleft=saind[isa+sastep]-saind[isa]; } } if(stwrite(sock, pix+(type==1?pixpsa*isa:saind[isa]), 2*nleft)){//2 byte data. warning("failed: %s\n", strerror(errno)); return -1; } #if __linux__ ct.tv_nsec+=int1_ns; while(ct.tv_nsec>=1000000000){ ct.tv_nsec-=1000000000; ct.tv_sec++; } #endif } if(stread(sock, dmres->p, sizeof(float)*nact)){ warning("read dmres failed: %s\n", strerror(errno)); return -1; } ready=(int)(toc3*1e6);//mvm is finished. #if __linux__ if(nstep<100){ dbg("tk=%.6f tic=%.6f, toc=%.6f, ready=%.6f\n", tk0, tk, myclockd(), ready*1e-6); } #endif if(stwriteint(sock, ready)){ warning("write ready failed: %s\n", strerror(errno)); return -1; } //set next frame start time. #if __linux__ ct.tv_nsec+=int2_ns; while(ct.tv_nsec>=1000000000){ ct.tv_nsec-=1000000000; ct.tv_sec++; } #endif if((istep & 0xFF) == 0xFF){ info("%d %d us.\n", istep, ready); } } info("\n"); return -1; }