Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
void isi_objtable_init()
{
	allobj.limit = 256;
	allobj.count = 0;
	allobj.table = (struct objtype**)isi_alloc(allobj.limit * sizeof(void*));
}
Ejemplo n.º 8
0
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(&LTUTime);
	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(&LTUTime);
			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;
}