void *srv_graph(void *v) { name_attach_t* pnat; char srv_name[BUFFER_SIZE] = SRV_NAME; char cmd[BUFFER_SIZE], param[BUFFER_SIZE]; int rcvid; frame_t frame; size_t i; iov_t *piov, header; FILE * pfcfg = fopen(FILE_NAME_CFG, "r"); if(NULL != pfcfg) { while(0 == feof(pfcfg)) { fscanf(pfcfg, "%s %s", cmd, param); if(0 == strcmp(cmd, "srv_name")) { strcpy(srv_name, param); } } fclose(pfcfg); } //log_start("srv_graph_log", "srv_graph_err"); pnat = name_attach(NULL, srv_name, NAME_FLAG_ATTACH_GLOBAL); SETIOV(&header, &frame, sizeof(frame_t)); while(true) { //log_update(); rcvid = MsgReceivev(pnat->chid, &header, 1, NULL); __ERROR_CONT(rcvid, -1, MSG_ERR_MSGREC); if(0 == rcvid) { switch(frame.header.code) { case _PULSE_CODE_DISCONNECT: printf("Client has gone\n"); break; case _PULSE_CODE_UNBLOCK: printf("_PULSE_CODE_UNBLOCK\n"); __ERROR_CHECK(MsgError(frame.header.value.sival_int, ETIME),-1,MSG_ERR_MSGERR); break; default: break; } } else { if (frame.header.type == _IO_CONNECT) { printf("Send OK\n"); frame_reply(rcvid, NULL); continue; } frame_datareceive(rcvid, &frame); frame_reply(rcvid, NULL); i=0; while(i<frame.size) { processtask(frame.ptask+i); ++i; } frame_destroy(&frame); } //log_stop(); } }
void *router(void *v) { wrk_info_t wrk_info = *(wrk_info_t*)v; int result, rcvid; iov_t *piov, header; frame_t frame; size_t i; SETIOV(&header, &frame, sizeof(frame_t)); while(true) { rcvid = MsgReceivev(wrk_info.chid, &header, 1, NULL); printf("rcvid %i\n", rcvid); __ERROR_CONT(rcvid, -1, MSG_ERR_MSGREC); if(0 == rcvid) { switch(frame.header.code) { case _PULSE_CODE_DISCONNECT: printf("Client has gone\n"); break; default: break; } } else { if (frame.header.type == _IO_CONNECT) { printf("Send OK\n"); frame_reply(rcvid, NULL); continue; } if(frame.protocol == STANDART) { __ERROR_CHECK(MsgError(rcvid, ENOTSUP),-1,MSG_ERR_MSGERR); continue; } printf("Thread %i, client %i\n", wrk_info.id, frame.cid); if(frame.protocol == NOREPLY) { for(i=0; i<wrk_info.pslave->amount; ++i) { if(FULL != wrk_info.pslave->pslave[i].status) { if(0 == sem_trywait(&wrk_info.pslave->pslave[i].sem)) { wrk_info.pslave->pslave[i].clientnow ++; if(wrk_info.pslave->pslave[i].clientnow == wrk_info.pslave->pslave[i].clientmax) { wrk_info.pslave->pslave[i].status = FULL; } sem_post(&wrk_info.pslave->pslave[i].sem); break; } } } if(i == wrk_info.pslave->amount) { __ERROR_CHECK(MsgError(rcvid, EAGAIN),-1,MSG_ERR_MSGERR); continue; } frame_datareceive(rcvid, &frame); frame_reply(rcvid, NULL); __ERROR_CHECK(frame_send(wrk_info.pslave->pslave[i].coid, &frame, NULL), -1, "sendv"); } } } }
int mmc_wait_command(SIM_HBA *hba) { SIM_MMC_EXT *ext; struct _pulse pulse; iov_t iov; int rcvid, intr=0, retry=0; ext = (SIM_MMC_EXT *)hba->ext; SETIOV(&iov, &pulse, sizeof(pulse)); while (1) { if ((rcvid = MsgReceivev(hba->chid, &iov, 1, NULL)) == -1) continue; intr = 0; switch (pulse.code) { case SIM_INTERRUPT: intr=ext->interrupt(hba, hba->cfg.IRQRegisters[0], ext->resp_type, ext->mmc_resp); InterruptUnmask(hba->cfg.IRQRegisters[0], hba->iid); break; case SIM_DMA_INTERRUPT: intr=ext->interrupt(hba, hba->cfg.IRQRegisters[0], ext->resp_type, ext->mmc_resp); if(hba->cfg.NumIRQs > 1) { InterruptUnmask(hba->cfg.IRQRegisters[1], ext->iid); } break; case SIM_TIMER: // Only check media if card detection interrupt is not supported if (!(ext->hccap & MMC_HCCAP_CD_INTR)) mmc_media_check(hba); if(!(ext->eflags & MMC_EFLAG_INSERTED)) return MMC_FAILURE; break; default: break; } if(intr & MMC_INTR_CARD){ mmc_media_check(hba); return MMC_FAILURE; } if((intr & MMC_INTR_COMMAND) && !(intr & MMC_INTR_ERROR)) return MMC_SUCCESS; if(retry++ >5) return MMC_FAILURE; } return MMC_FAILURE; }
int MsgReceiveAsync(int chid, const struct iovec *iov, unsigned parts) { return MsgReceivev(chid, iov, parts, NULL); }
void *worker(void *v) { wrk_info_t wrk_info = *(wrk_info_t*)v; int result; struct sigevent clientevent, timeoutevent; struct sigaction timeoutact; iov_t *piov, header; frame_t frame; timer_t timer; syncsig_t *psync = &wrk_info.psync[wrk_info.id]; struct itimerspec timeout, stoptimeout; struct timespec slp; slp.tv_nsec = 10000000; slp.tv_sec = 0; timeout.it_interval.tv_sec = 0; timeout.it_interval.tv_nsec = 0; timeout.it_value.tv_sec = 0; timeout.it_value.tv_nsec = 0; stoptimeout = timeout; sem_init(&psync->sem, 0, 1); SETIOV(&header, &frame, sizeof(frame_t)); SIGEV_SIGNAL_VALUE_INIT(&timeoutevent, SIGUSR1, psync); //SIGEV_SIGNAL_INIT(&timeoutevent, SIGUSR1) ; __ERROR_CHECK(timer_create(CLOCK_MONOTONIC, &timeoutevent, &timer),-1,"timer_create"); __ERROR_CHECK(signal(SIGUSR1, wrk_sigusr1),-1,"signal"); //timeoutact.sa_handler = &wrk_sigusr1; //sigaction(SIGUSR1, &timeoutact, NULL); while(true) { psync->rcvid = -1; wrk_info.psync[wrk_info.id].status = READY; psync->rcvid = MsgReceivev(wrk_info.chid, &header, 1, NULL); __ERROR_CONT(psync->rcvid, -1, MSG_ERR_MSGREC); wrk_info.psync[wrk_info.id].status = WORK; if(0 == psync->rcvid) { switch(frame.header.code) { case _PULSE_CODE_DISCONNECT: printf("Client has gone\n"); break; case _PULSE_CODE_UNBLOCK: printf("_PULSE_CODE_UNBLOCK\n"); for(size_t i=0; i<wrk_info.wrk_amount; ++i) { if(wrk_info.psync[i].rcvid == frame.header.value.sival_int) { if(wrk_info.psync[i].status != SEND) { __ERROR_CHECK(MsgError(frame.header.value.sival_int, ETIME),-1,MSG_ERR_MSGERR); } break; } } break; default: break; } } else { if (frame.header.type == _IO_CONNECT) { printf("Send OK\n"); frame_reply(psync->rcvid, NULL); continue; } wrk_info.proute[frame.cid] = wrk_info.id; timeout.it_value = frame.timeout; //printf("%u %u\n", timeout.it_value.tv_sec, timeout.it_value.tv_nsec); sem_wait(&psync->sem); if(frame.protocol != REPLY) { __ERROR_CHECK(timer_settime(timer, 0, &timeout, NULL),-1,"timer_settime"); } //printf("Thread %i, client %i\n", wrk_info.id, frame.cid); frame_datareceive(psync->rcvid, &frame); sem_post(&psync->sem); //sleep(1); nanosleep( &slp, NULL); if(frame.protocol == NOREPLY) { SIGEV_PULSE_INIT( &clientevent, frame.coid, SIGEV_PULSE_PRIO_INHERIT, PULSE_CODE_DATA_READY, 0); frame_reply(psync->rcvid, NULL); } if(frame.protocol != REPLY) { frame_repinit(&frame, &wrk_info.pcash[frame.cid].framerep); for(size_t i=0; i<frame.size; ++i) { processtask(frame.ptask+i, wrk_info.pcash[frame.cid].framerep.ptask+i, &wrk_info.pcash[frame.cid].spline); } __ERROR_CHECK(timer_settime(timer, 0, &stoptimeout, NULL),-1,"timer_settime"); } wrk_info.psync[wrk_info.id].status = SEND; if(frame.protocol == NOREPLY) { result = -1; for(int i=0; i<3 && result == -1; ++i) { result = MsgDeliverEvent(psync->rcvid, &clientevent); __ERROR_CHECK(result, -1, "MsgDeliverEvent"); } } else { frame_reply(psync->rcvid, &wrk_info.pcash[frame.cid].framerep); frame_destroy(&wrk_info.pcash[frame.cid].framerep); } } } }
static void *interrupt_thread( void *p ) { int ret; int intr; int intr_id; struct sigevent event; struct _pulse pulse; iov_t iov; int rcvid; int chid; int coid; int count; uint64_t rdata; uint16_t target; uint64_t clk; int pool_id; intr = (int)p; rdata = 0; target = 512; ret = ThreadCtl( _NTO_TCTL_IO, 0 ); if( ret != 0 ) { slogf( _SLOGC_CHAR, _SLOG_CRITICAL, "random: Unable to gain IO privs: %s", strerror( errno ) ); return NULL; } chid = ChannelCreate( 0 ); if( chid == -1 ) { slogf( _SLOGC_CHAR, _SLOG_CRITICAL, "random: ChannelCreate() failed: %s", strerror( errno ) ); return NULL; } coid = ConnectAttach( 0, 0, chid, _NTO_SIDE_CHANNEL, 0 ); if( coid == -1 ) { slogf( _SLOGC_CHAR, _SLOG_CRITICAL, "random: ConnectAttach() failed: %s", strerror( errno ) ); return NULL; } ret = yarrow_add_source( Yarrow, &pool_id ); if( ret != 0 ) { slogf( _SLOGC_CHAR, _SLOG_CRITICAL, "random: Unable to get pool_id for interrupt %d thread.", intr ); return NULL; } event.sigev_notify = SIGEV_PULSE; event.sigev_coid = coid; event.sigev_code = 1; event.sigev_priority = 15; intr_id = InterruptAttachEvent( intr, &event, _NTO_INTR_FLAGS_TRK_MSK ); if( intr_id == -1 ) { slogf( _SLOGC_CHAR, _SLOG_CRITICAL, "random: Unable to attach event to intr %d: %s", intr, strerror( errno ) ); return NULL; } /* This is how many interrupts we are gonna get */ if( Yarrow ) { yarrow_output( Yarrow, (uint8_t *)&rdata, sizeof( rdata ) ); target = rdata & 0x1FF; } count = 0; SETIOV( &iov, &pulse, sizeof( pulse ) ); while( 1 ) { rcvid = MsgReceivev( chid, &iov, 1, NULL ); if( rcvid == -1 ) { if( errno == ESRCH ) return NULL; continue; } switch( pulse.code ) { case 1: InterruptUnmask( intr, intr_id ); count++; if( count >= target ) { ClockTime( CLOCK_REALTIME, NULL, &clk ); clk = clk ^ rdata; if( Yarrow ) { yarrow_input( Yarrow, (uint8_t *)&clk, sizeof( clk ), pool_id, 8 ); yarrow_output( Yarrow, (uint8_t *)&rdata, sizeof( rdata ) ); } target = rdata & 0x1FF; count = 0; } break; default: if( rcvid ) MsgError( rcvid, ENOTSUP ); } } return NULL; }