exit.c 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <thread.h>
  4. #include "threadimpl.h"
  5. char *_threadexitsallstatus;
  6. Channel *_threadwaitchan;
  7. void
  8. threadexits(char *exitstr)
  9. {
  10. Proc *p;
  11. Thread *t;
  12. p = _threadgetproc();
  13. t = p->thread;
  14. t->moribund = 1;
  15. if(exitstr==nil)
  16. exitstr="";
  17. utfecpy(p->exitstr, p->exitstr+ERRMAX, exitstr);
  18. _sched();
  19. }
  20. void
  21. threadexitsall(char *exitstr)
  22. {
  23. Proc *p;
  24. int pid[64];
  25. int i, npid, mypid;
  26. if(exitstr == nil)
  27. exitstr = "";
  28. _threadexitsallstatus = exitstr;
  29. _threaddebug(DBGSCHED, "_threadexitsallstatus set to %p", _threadexitsallstatus);
  30. mypid = getpid();
  31. /*
  32. * signal others.
  33. * copying all the pids first avoids other threads
  34. * teardown procedures getting in the way.
  35. *
  36. * avoid mallocs since malloc can post a note which can
  37. * call threadexitsall...
  38. */
  39. for(;;){
  40. lock(&_threadpq.lock);
  41. npid = 0;
  42. for(p = _threadpq.head; p && npid < nelem(pid); p=p->next){
  43. if(p->threadint == 0 && p->pid != mypid){
  44. pid[npid++] = p->pid;
  45. p->threadint = 1;
  46. }
  47. }
  48. unlock(&_threadpq.lock);
  49. if(npid == 0)
  50. break;
  51. for(i=0; i<npid; i++)
  52. postnote(PNPROC, pid[i], "threadint");
  53. }
  54. /* leave */
  55. exits(exitstr);
  56. }
  57. Channel*
  58. threadwaitchan(void)
  59. {
  60. if(_threadwaitchan==nil)
  61. _threadwaitchan = chancreate(sizeof(Waitmsg*), 16);
  62. return _threadwaitchan;
  63. }