co.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /* $Id$ */
  2. /* co.c - Routines to handle coroutines */
  3. #include "ocm_proc.h"
  4. static void search(), RESUMERR();
  5. void resume(id) identification id;
  6. /* Stops the current process, by saving its stack, and searches for the
  7. * process with identification 'id' in the group the running process
  8. * belongs to. If 'id' cannot be found then repeat these actions with
  9. * the running process' parent. If 'id' is found it is activated. It
  10. * is a fatal error if 'id' cannot be found.
  11. */
  12. {
  13. if (group!=nil) {
  14. register wordsize size;
  15. size=top_size(group->s_brk);
  16. (*group->active)->stack=alloc((unsigned) size);
  17. if (top_save(size, (*group->active)->stack))
  18. search(id);
  19. else {
  20. free((*group->active)->stack);
  21. load_betweens();
  22. }
  23. } else
  24. RESUMERR();
  25. }
  26. static void search(id) identification id;
  27. /* Searches for the process with identification 'id'.
  28. * If the process is found it is activated and its process tree is
  29. * traversed to find the running process.
  30. */
  31. {
  32. register struct process **aproc, *proc;
  33. for(;;) {
  34. aproc= &group->first;
  35. while (*aproc!=nil && (*aproc)->id!=id)
  36. aproc= &(*aproc)->next;
  37. if (*aproc!=nil) break;
  38. save_between(group);
  39. if ((group=group->up)==nil)
  40. RESUMERR();
  41. }
  42. group->active=aproc;
  43. proc= *aproc;
  44. highest_group=group;
  45. while (proc->down!=nil) {
  46. group=proc->down;
  47. proc= *group->active;
  48. }
  49. top_load(proc->stack);
  50. }
  51. static void delete_group(group) struct procgroup *group;
  52. /* Removes the whole group and sub-groups recursively from the running
  53. * process.
  54. */
  55. {
  56. register struct process *proc, *next;
  57. proc=group->first;
  58. while (proc!=nil) {
  59. if (proc->down!=nil)
  60. delete_group(proc->down);
  61. else
  62. free(proc->stack);
  63. next=proc->next;
  64. free( (void *) proc);
  65. proc=next;
  66. }
  67. delete_between(group);
  68. free( (void *) group);
  69. }
  70. void coend()
  71. {
  72. register struct process *proc, *next;
  73. register struct procgroup *junk;
  74. proc=group->first;
  75. while (proc!=nil) {
  76. if (proc!= *group->active) {
  77. if (proc->down!=nil)
  78. delete_group(proc->down);
  79. else
  80. free(proc->stack);
  81. }
  82. next=proc->next;
  83. free( (void *) proc);
  84. proc=next;
  85. }
  86. delete_between(group);
  87. junk=group;
  88. group=group->up;
  89. free( (void *) junk);
  90. if (group!=nil)
  91. (*group->active)->down=nil;
  92. }
  93. static void RESUMERR()
  94. {
  95. write(2, "RESUMERR\n", 9);
  96. abort();
  97. }