void isi_synctable_init() { allsync.limit = 128; allsync.count = 0; allsync.table = (struct isiNetSync**)isi_alloc(allsync.limit * sizeof(void*)); allsync.out = (uint8_t *)isi_alloc(2048); }
static int isi_initindex_dev(struct isiInfo *item) { item->busdev.limit = 1; item->busdev.count = 0; item->busdev.table = (struct isiConPoint*)isi_alloc(item->busdev.limit * sizeof(struct isiConPoint)); return 0; }
int isi_inittable(struct isiDevTable *t) { t->limit = 32; t->count = 0; t->table = (struct isiInfo**)isi_alloc(t->limit * sizeof(void*)); return 0; }
int isi_init_contable() { struct isiConTable *t = &allcon; t->limit = 32; t->count = 0; t->table = (struct isiConstruct**)isi_alloc(t->limit * sizeof(void*)); return 0; }
int isi_create_object(int objtype, struct objtype **out) { if(!out) return -1; struct objtype *ns; size_t objsize = 0; if(isi_get_type_size(objtype, &objsize)) return ISIERR_INVALIDPARAM; ns = (struct objtype*)isi_alloc(objsize); if(!ns) return ISIERR_NOMEM; memset(ns, 0, objsize); ns->id = ++maxsid; // TODO make "better" ID numbers? ns->objtype = objtype; isi_objtable_add(ns); *out = ns; return 0; }
int isi_premake_object(int objtype, struct isiConstruct **outcon, struct objtype **out) { uint32_t x; int i; int rs = 0; struct isiConstruct *con = NULL; if(!objtype || !out) return ISIERR_INVALIDPARAM; for(x = 0; x < allcon.count; x++) { if(allcon.table[x]->objtype == objtype) { con = allcon.table[x]; break; } } if(!con) return ISIERR_NOTFOUND; *outcon = con; struct objtype *ndev; i = isi_create_object(objtype, &ndev); if(i) return i; struct isiInfo *info = (struct isiInfo*)ndev; if(objtype < 0x2f00) { *out = ndev; return 0; } info->meta = con; info->rvproto = con->rvproto; info->svproto = con->svproto; info->c = &emptyobject; if(con->PreInit) { rs = con->PreInit(info); if(rs) { isi_delete_object(ndev); *out = 0; return rs; } } if(objtype > 0x2f00 && con->QuerySize) { size_t sz = 0; con->QuerySize(0, &sz); if(sz) { info->rvstate = isi_alloc(sz); } sz = 0; con->QuerySize(1, &sz); if(sz) { info->svstate = isi_alloc(sz); } } else { if(con->rvproto && con->rvproto->length) { info->rvstate = isi_alloc(con->rvproto->length); } if(con->svproto && con->svproto->length) { info->svstate = isi_alloc(con->svproto->length); } } if(con->Init) { rs = con->Init(info); if(rs) { isi_delete_object(ndev); *out = 0; return rs; } } *out = ndev; return 0; }
void isi_objtable_init() { allobj.limit = 256; allobj.count = 0; allobj.table = (struct objtype**)isi_alloc(allobj.limit * sizeof(void*)); }
int main(int argc, char**argv, char**envp) { uint32_t cux; uintptr_t gccq = 0; uintptr_t lucycles = 0; uintptr_t lucpus = 0; struct stats sts = {0, }; int paddlimit = 0; int premlimit = 0; isi_init_contable(); isi_register_objects(); isi_objtable_init(); isi_init_sestable(); isi_inittable(&alldev); isi_inittable(&allcpu); isi_synctable_init(); int i; uint32_t k; if( argc > 1 ) { i = parse_args(argc, argv); if(i) return i; } else { fprintf(stderr, gsc_usage, argv[0], argv[0]); return 0; } if(endf) { unsigned char * mflip; uint32_t rsize; loadbinfile(endf, 1, &mflip, &rsize); savebinfile(endf, 0, mflip, rsize); return 0; } struct sigaction hnler; hnler.sa_handler = sysfaulthdl; hnler.sa_flags = 0; if(redisaddr) { redis_make_session_lu(redisaddr); } if(!rqrun && !flagsvr) { fprintf(stderr, "At least -r or -s must be specified.\n"); return 0; } if(flagsvr) { if(!rqrun) enter_service(); makeserver(listenportnumber); } if(rqrun) { make_interactive(); isi_addcpu(); } sigaction(SIGINT, &hnler, NULL); sigaction(SIGTERM, &hnler, NULL); sigaction(SIGHUP, &hnler, NULL); sigaction(SIGPIPE, &hnler, NULL); fetchtime(<UTime); lucycles = 0; // how many cycles ran (debugging) cux = 0; // CPU index - currently never changes if(rqrun && allcpu.count && ((struct isiCPUInfo*)allcpu.table[cux])->ctl & ISICTL_DEBUG) { showdiag_dcpu(allcpu.table[cux], 1); } while(!haltnow) { struct isiCPUInfo * ccpu; struct isiInfo * ccpi; struct timespec CRun; ccpu = (struct isiCPUInfo*)(ccpi = allcpu.table[cux]); fetchtime(&CRun); if(!allcpu.count) { struct timespec stime = {0, 10000}; nanosleep(&stime, NULL); } else { int ccq = 0; int tcc = numberofcpus * 2; if(tcc < 20) tcc = 20; while(ccq < tcc && isi_time_lt(&ccpi->nrun, &CRun)) { sts.quanta++; ccpi->c->RunCycles(ccpi, CRun); //TODO some hardware may need to work at the same time lucycles += ccpu->cycl; if(rqrun && (ccpu->ctl & ISICTL_TRACE) && (ccpu->cycl)) { showdiag_dcpu(ccpi, 1); } ccpu->cycl = 0; fetchtime(&CRun); ccq++; } if(ccq >= tcc) gccq++; sts.cpusched++; fetchtime(&CRun); if(ccpi->updev.t && ccpi->updev.t->c->RunCycles) { ccpi->updev.t->c->RunCycles(ccpi->updev.t, CRun); } } fetchtime(&CRun); isi_run_sync(CRun); fetchtime(&CRun); if(CRun.tv_sec > LTUTime.tv_sec) { // roughly one second between status output if(rqrun && !flagdbg) { // interactive diag double clkdelta; float clkrate; if(allcpu.count) showdiag_dcpu(allcpu.table[0], 0); clkdelta = ((double)(CRun.tv_sec - LTUTime.tv_sec)) + (((double)CRun.tv_nsec) * 0.000000001); clkdelta-=(((double)LTUTime.tv_nsec) * 0.000000001); if(!lucpus) lucpus = 1; clkrate = ((((double)lucycles) * clkdelta) * 0.001) / numberofcpus; fprintf(stderr, "DC: %.4f sec, %d at % 9.3f kHz (% 8ld) [Q:% 8d, S:% 8d, SC:% 8d]\r", clkdelta, numberofcpus, clkrate, gccq, sts.quanta, sts.cpusched, sts.cpusched / numberofcpus ); if(allcpu.count) showdiag_up(4); } fetchtime(<UTime); if(gccq >= sts.cpusched / numberofcpus ) { if(numberofcpus > softcpumin) { numberofcpus--; if(rqrun) fprintf(stderr, "TODO: Offline a CPU\n"); premlimit--; paddlimit = 0; } } else { if(numberofcpus < softcpumax) { //fetchtime(&allcpus[numberofcpus].nrun); //isi_addtime(&allcpus[numberofcpus].nrun, quantum); numberofcpus++; if(rqrun) fprintf(stderr, "TODO: Online a CPU\n"); } } lucycles = 0; lucpus = 0; gccq = 0; memset(&sts, 0, sizeof(struct stats)); if(premlimit < 20) premlimit+=10; if(paddlimit < 20) paddlimit+=2; for(k = 0; k < allses.count; k++) { struct isiSession *ses = allses.table[k]; if(ses->LTick) ses->LTick(ses, CRun); } } if(allses.pcount != allses.count) { if(allses.ptable) { free(allses.ptable); allses.ptable = 0; } allses.pcount = allses.count; allses.ptable = (struct pollfd*)isi_alloc(sizeof(struct pollfd) * allses.pcount); if(!allses.ptable) { isilogerr("malloc poll table fails!"); } i = 0; for(k = 0; k < allses.count; k++) { allses.ptable[i].fd = allses.table[k]->sfd; allses.ptable[i].events = POLLIN; i++; } } if(allses.ptable) { i = poll(allses.ptable, allses.pcount, 0); } else { i = 0; } for(k = 0; k < allses.count; k++) { struct isiSession *ses = allses.table[k]; if(ses && ses->STick && (ses->cmdqstart != ses->cmdqend)) ses->STick(ses, CRun); } if(i > 0) { for(k = 0; k < allses.pcount; k++) { if(!allses.ptable[k].revents) continue; struct isiSession *ses = allses.table[k]; const char *etxt = 0; /* Here be dragons */ switch(allses.ptable[k].revents) { case POLLERR: etxt = "poll: FD error\n"; goto sessionerror; case POLLHUP: etxt = "poll: FD hangup\n"; goto sessionerror; case POLLNVAL: etxt = "poll: FD invalid\n"; goto sessionerror; default: if(allses.ptable[k].revents & POLLIN) { if(ses->sfd == allses.ptable[k].fd) { if(ses->Recv(ses, CRun)) goto sessionerror; } else { isilog(L_ERR, "netses: session ID error\n"); } } } continue; sessionerror: if(etxt) isilog(L_ERR, etxt); if(ses->sfd == allses.ptable[k].fd) { isi_delete_ses(ses); k = allses.pcount; } } } if(!flagdbg) { cux++; if(!(cux < allcpu.count)) { cux = 0; } } else { numberofcpus = 1; cux = 0; } if(haltnow) { break; } } if(flagsvr) { isilog(L_WARN, "closing connections\n"); while(allses.count) { isi_delete_ses(allses.table[0]); } } while(allobj.count) { isi_delete_object(allobj.table[0]); } if(rqrun) printf("\n\n\n\n"); return 0; }