xref: /plan9/sys/src/libc/9sys/nsec.c (revision 3128c8a0f7b81b6e6e0831d669ef15a24852fbd8)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
33468a491SDavid du Colombier #include <tos.h>
47dd7cddfSDavid du Colombier 
57dd7cddfSDavid du Colombier static uvlong order = 0x0001020304050607ULL;
67dd7cddfSDavid du Colombier 
77dd7cddfSDavid du Colombier static void
be2vlong(vlong * to,uchar * f)87dd7cddfSDavid du Colombier be2vlong(vlong *to, uchar *f)
97dd7cddfSDavid du Colombier {
107dd7cddfSDavid du Colombier 	uchar *t, *o;
117dd7cddfSDavid du Colombier 	int i;
127dd7cddfSDavid du Colombier 
137dd7cddfSDavid du Colombier 	t = (uchar*)to;
147dd7cddfSDavid du Colombier 	o = (uchar*)&order;
15d95be1c0SDavid du Colombier 	for(i = 0; i < sizeof order; i++)
167dd7cddfSDavid du Colombier 		t[o[i]] = f[i];
177dd7cddfSDavid du Colombier }
187dd7cddfSDavid du Colombier 
193468a491SDavid du Colombier static int fd = -1;
203468a491SDavid du Colombier static struct {
213468a491SDavid du Colombier 	int	pid;
223468a491SDavid du Colombier 	int	fd;
233468a491SDavid du Colombier } fds[64];
243468a491SDavid du Colombier 
257dd7cddfSDavid du Colombier vlong
nsec(void)267dd7cddfSDavid du Colombier nsec(void)
277dd7cddfSDavid du Colombier {
28d95be1c0SDavid du Colombier 	uchar b[8];
297dd7cddfSDavid du Colombier 	vlong t;
303468a491SDavid du Colombier 	int pid, i, f, tries;
317dd7cddfSDavid du Colombier 
323468a491SDavid du Colombier 	/*
333468a491SDavid du Colombier 	 * Threaded programs may have multiple procs
343468a491SDavid du Colombier 	 * with different fd tables, so we may need to open
353468a491SDavid du Colombier 	 * /dev/bintime on a per-pid basis
363468a491SDavid du Colombier 	 */
373468a491SDavid du Colombier 
383468a491SDavid du Colombier 	/* First, look if we've opened it for this particular pid */
39*3128c8a0SDavid du Colombier 	if((pid = _tos->pid) == 0)		/* 9vx bug, perhaps? */
40*3128c8a0SDavid du Colombier 		_tos->pid = pid = getpid();
413468a491SDavid du Colombier 	do{
423468a491SDavid du Colombier 		f = -1;
433468a491SDavid du Colombier 		for(i = 0; i < nelem(fds); i++)
443468a491SDavid du Colombier 			if(fds[i].pid == pid){
453468a491SDavid du Colombier 				f = fds[i].fd;
463468a491SDavid du Colombier 				break;
473468a491SDavid du Colombier 			}
483468a491SDavid du Colombier 		tries = 0;
493468a491SDavid du Colombier 		if(f < 0){
503468a491SDavid du Colombier 			/* If it's not open for this pid, try the global pid */
513468a491SDavid du Colombier 			if(fd >= 0)
523468a491SDavid du Colombier 				f = fd;
533468a491SDavid du Colombier 			else{
543468a491SDavid du Colombier 				/* must open */
553468a491SDavid du Colombier 				if((f = open("/dev/bintime", OREAD|OCEXEC)) < 0)
567dd7cddfSDavid du Colombier 					return 0;
573468a491SDavid du Colombier 				fd = f;
583468a491SDavid du Colombier 				for(i = 0; i < nelem(fds); i++)
593468a491SDavid du Colombier 					if(fds[i].pid == pid || fds[i].pid == 0){
603468a491SDavid du Colombier 						fds[i].pid = pid;
613468a491SDavid du Colombier 						fds[i].fd = f;
623468a491SDavid du Colombier 						break;
637dd7cddfSDavid du Colombier 					}
647dd7cddfSDavid du Colombier 			}
653468a491SDavid du Colombier 		}
663468a491SDavid du Colombier 		if(pread(f, b, sizeof b, 0) == sizeof b){
67d95be1c0SDavid du Colombier 			be2vlong(&t, b);
687dd7cddfSDavid du Colombier 			return t;
697dd7cddfSDavid du Colombier 		}
703468a491SDavid du Colombier 		close(f);
713468a491SDavid du Colombier 		if(i < nelem(fds))
723468a491SDavid du Colombier 			fds[i].fd = -1;
733468a491SDavid du Colombier 	}while(tries++ == 0);	/* retry once */
743468a491SDavid du Colombier 	USED(tries);
753468a491SDavid du Colombier 	return 0;
763468a491SDavid du Colombier }
77