nsec.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <tos.h>
  4. static uvlong order = 0x0001020304050607ULL;
  5. static void
  6. be2vlong(vlong *to, uchar *f)
  7. {
  8. uchar *t, *o;
  9. int i;
  10. t = (uchar*)to;
  11. o = (uchar*)&order;
  12. for(i = 0; i < sizeof order; i++)
  13. t[o[i]] = f[i];
  14. }
  15. static int fd = -1;
  16. static struct {
  17. int pid;
  18. int fd;
  19. } fds[64];
  20. vlong
  21. nsec(void)
  22. {
  23. uchar b[8];
  24. vlong t;
  25. int pid, i, f, tries;
  26. /*
  27. * Threaded programs may have multiple procs
  28. * with different fd tables, so we may need to open
  29. * /dev/bintime on a per-pid basis
  30. */
  31. /* First, look if we've opened it for this particular pid */
  32. pid = _tos->pid;
  33. do{
  34. f = -1;
  35. for(i = 0; i < nelem(fds); i++)
  36. if(fds[i].pid == pid){
  37. f = fds[i].fd;
  38. break;
  39. }
  40. tries = 0;
  41. if(f < 0){
  42. /* If it's not open for this pid, try the global pid */
  43. if(fd >= 0)
  44. f = fd;
  45. else{
  46. /* must open */
  47. if((f = open("/dev/bintime", OREAD|OCEXEC)) < 0)
  48. return 0;
  49. fd = f;
  50. for(i = 0; i < nelem(fds); i++)
  51. if(fds[i].pid == pid || fds[i].pid == 0){
  52. fds[i].pid = pid;
  53. fds[i].fd = f;
  54. break;
  55. }
  56. }
  57. }
  58. if(pread(f, b, sizeof b, 0) == sizeof b){
  59. be2vlong(&t, b);
  60. return t;
  61. }
  62. close(f);
  63. if(i < nelem(fds))
  64. fds[i].fd = -1;
  65. }while(tries++ == 0); /* retry once */
  66. USED(tries);
  67. return 0;
  68. }