fork download
  1. #include <stdio.h>
  2.  
  3. #ifndef ASYNC_H
  4. #define ASYNC_H
  5.  
  6. #define async(...) int *_state_ = &(__VA_ARGS__); switch (*_state_) while (1) if (1) {*_state_ = 1; case 1: return 1;} else default:
  7. #define await(...) if (!(*_state_ = __LINE__)); else case __LINE__: switch (0) while (1) if (!(__VA_ARGS__)) return 0; else if (1) break; else default:
  8. #define yield if (0) case __LINE__:; else switch (0) while (1) if (1) {*_state_ = __LINE__; return 0;} else default:
  9. #define leave switch (0) while (1) if (1) {*_state_ = 1; return 1;} else default:
  10. #define until(...) while (!(__VA_ARGS__))
  11.  
  12. #endif
  13.  
  14. typedef union {
  15. struct {
  16. int n;
  17. int i;
  18. int state;
  19. };
  20. int result;
  21. } write_async_task;
  22.  
  23. int write_async(write_async_task *t) {
  24. async (t->state) {
  25. printf("write %d: start\n", t->n);
  26. await (t->i >= t->n) {
  27. printf("write %d: %d\n", t->n, t->i);
  28. ++t->i;
  29. }
  30. printf("write %d: end\n", t->n);
  31. leave t->result = t->i;
  32. }
  33. }
  34.  
  35. typedef struct {
  36. int jid;
  37. int n;
  38. int state;
  39. write_async_task write_task;
  40. } job_task;
  41.  
  42. int job(job_task *t) {
  43. async (t->state) {
  44. printf("job %d: before write\n", t->jid);
  45. t->write_task = (write_async_task){.n = t->n};
  46. await (write_async(&t->write_task));
  47. printf("job %d: written %d bytes\n", t->jid, t->write_task.result);
  48. }
  49. }
  50.  
  51. int main(void) {
  52. puts("program start");
  53. job_task j1 = {.jid = 1, .n = 3};
  54. job_task j2 = {.jid = 2, .n = 7};
  55. until (
  56. job(&j1) &
  57. job(&j2)
  58. );
  59. job_task jobs[] = {
  60. {.jid = 3, .n = 7},
  61. {.jid = 4, .n = 9},
  62. {.jid = 5, .n = 4},
  63. {.jid = 6, .n = 5}
  64. };
  65. int jobs_n = sizeof(jobs) / sizeof(jobs[0]);
  66. while (jobs_n > 0) {
  67. for (int i = 0; i < jobs_n; ++i) {
  68. if (job(&jobs[i])) {
  69. jobs[i--] = jobs[--jobs_n];
  70. }
  71. }
  72. }
  73. puts("program end");
  74. }
  75.  
Success #stdin #stdout 0s 4552KB
stdin
Standard input is empty
stdout
program start
job 1: before write
write 3: start
write 3: 0
job 2: before write
write 7: start
write 7: 0
write 3: 1
write 7: 1
write 3: 2
write 3: end
job 1: written 3 bytes
write 7: 2
write 7: 3
write 7: 4
write 7: 5
write 7: 6
write 7: end
job 2: written 7 bytes
job 3: before write
write 7: start
write 7: 0
job 4: before write
write 9: start
write 9: 0
job 5: before write
write 4: start
write 4: 0
job 6: before write
write 5: start
write 5: 0
write 7: 1
write 9: 1
write 4: 1
write 5: 1
write 7: 2
write 9: 2
write 4: 2
write 5: 2
write 7: 3
write 9: 3
write 4: 3
write 4: end
job 5: written 4 bytes
write 5: 3
write 7: 4
write 9: 4
write 5: 4
write 5: end
job 6: written 5 bytes
write 7: 5
write 9: 5
write 7: 6
write 7: end
job 3: written 7 bytes
write 9: 6
write 9: 7
write 9: 8
write 9: end
job 4: written 9 bytes
program end