compat.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. #include <u.h>
  2. #include <libc.h>
  3. #include "compat.h"
  4. #include "error.h"
  5. #include "errstr.h"
  6. ulong kerndate;
  7. Proc **privup;
  8. char *eve;
  9. extern void *mainmem;
  10. void
  11. _assert(char *fmt)
  12. {
  13. panic("assert failed: %s", fmt);
  14. }
  15. int
  16. errdepth(int ed)
  17. {
  18. if(ed >= 0 && up->nerrlab != ed)
  19. panic("unbalanced error depth: expected %d got %d\n", ed, up->nerrlab);
  20. return up->nerrlab;
  21. }
  22. void
  23. newup(char *name)
  24. {
  25. up = smalloc(sizeof(Proc));
  26. up->user = eve;
  27. strncpy(up->name, name, KNAMELEN-1);
  28. up->name[KNAMELEN-1] = '\0';
  29. }
  30. void
  31. kproc(char *name, void (*f)(void *), void *a)
  32. {
  33. int pid;
  34. pid = rfork(RFPROC|RFMEM|RFNOWAIT);
  35. switch(pid){
  36. case -1:
  37. panic("can't make new thread: %r");
  38. case 0:
  39. break;
  40. default:
  41. return;
  42. }
  43. newup(name);
  44. if(!waserror())
  45. (*f)(a);
  46. _exits(nil);
  47. }
  48. void
  49. kexit(void)
  50. {
  51. _exits(nil);
  52. }
  53. void
  54. initcompat(void)
  55. {
  56. rfork(RFREND);
  57. privup = privalloc();
  58. kerndate = seconds();
  59. eve = getuser();
  60. newup("main");
  61. }
  62. int
  63. openmode(ulong o)
  64. {
  65. o &= ~(OTRUNC|OCEXEC|ORCLOSE);
  66. if(o > OEXEC)
  67. error(Ebadarg);
  68. if(o == OEXEC)
  69. return OREAD;
  70. return o;
  71. }
  72. void
  73. panic(char *fmt, ...)
  74. {
  75. char buf[512];
  76. char buf2[512];
  77. va_list va;
  78. va_start(va, fmt);
  79. vseprint(buf, buf+sizeof(buf), fmt, va);
  80. va_end(va);
  81. sprint(buf2, "panic: %s\n", buf);
  82. write(2, buf2, strlen(buf2));
  83. exits("error");
  84. }
  85. void*
  86. smalloc(ulong n)
  87. {
  88. void *p;
  89. p = mallocz(n, 1);
  90. if(p == nil)
  91. panic("out of memory");
  92. setmalloctag(p, getcallerpc(&n));
  93. return p;
  94. }
  95. long
  96. seconds(void)
  97. {
  98. return time(nil);
  99. }
  100. void
  101. error(char *err)
  102. {
  103. strncpy(up->error, err, ERRMAX);
  104. nexterror();
  105. }
  106. void
  107. nexterror(void)
  108. {
  109. longjmp(up->errlab[--up->nerrlab], 1);
  110. }
  111. int
  112. readstr(ulong off, char *buf, ulong n, char *str)
  113. {
  114. int size;
  115. size = strlen(str);
  116. if(off >= size)
  117. return 0;
  118. if(off+n > size)
  119. n = size-off;
  120. memmove(buf, str+off, n);
  121. return n;
  122. }
  123. void
  124. _rendsleep(ulong tag)
  125. {
  126. ulong value;
  127. for(;;){
  128. value = rendezvous(tag, 0x22a891b8);
  129. if(value == 0x7f7713f9)
  130. break;
  131. if(tag != ~0)
  132. panic("_rendsleep: rendezvous mismatch");
  133. }
  134. }
  135. void
  136. _rendwakeup(ulong tag)
  137. {
  138. ulong value;
  139. for(;;){
  140. value = rendezvous(tag, 0x7f7713f9);
  141. if(value == 0x22a891b8)
  142. break;
  143. if(tag != ~0)
  144. panic("_rendwakeup: rendezvous mismatch");
  145. }
  146. }
  147. void
  148. rendsleep(Rendez *r, int (*f)(void*), void *arg)
  149. {
  150. lock(&up->rlock);
  151. up->r = r;
  152. unlock(&up->rlock);
  153. lock(r);
  154. /*
  155. * if condition happened, never mind
  156. */
  157. if(up->intr || f(arg)){
  158. unlock(r);
  159. goto Done;
  160. }
  161. /*
  162. * now we are committed to
  163. * change state and call scheduler
  164. */
  165. if(r->p)
  166. panic("double sleep");
  167. r->p = up;
  168. unlock(r);
  169. _rendsleep((ulong)r);
  170. Done:
  171. lock(&up->rlock);
  172. up->r = 0;
  173. if(up->intr){
  174. up->intr = 0;
  175. unlock(&up->rlock);
  176. error(Eintr);
  177. }
  178. unlock(&up->rlock);
  179. }
  180. int
  181. rendwakeup(Rendez *r)
  182. {
  183. Proc *p;
  184. int rv;
  185. lock(r);
  186. p = r->p;
  187. rv = 0;
  188. if(p){
  189. r->p = nil;
  190. _rendwakeup((ulong)r);
  191. rv = 1;
  192. }
  193. unlock(r);
  194. return rv;
  195. }
  196. void
  197. rendintr(void *v)
  198. {
  199. Proc *p;
  200. p = v;
  201. lock(&p->rlock);
  202. p->intr = 1;
  203. if(p->r)
  204. rendwakeup(p->r);
  205. unlock(&p->rlock);
  206. }
  207. void
  208. rendclearintr(void)
  209. {
  210. lock(&up->rlock);
  211. up->intr = 0;
  212. unlock(&up->rlock);
  213. }