Coverage Report

Created: 2024-08-19 11:27

/home/liu/actions-runner/_work/ccv/ccv/lib/nnc/co.h
Line
Count
Source (jump to first uncovered line)
1
#ifndef GUARD_co_h
2
#define GUARD_co_h
3
4
#include <stdlib.h>
5
#include <string.h>
6
#include <pthread.h>
7
8
#include "ccv.h"
9
10
typedef struct co_routine_s co_routine_t;
11
12
typedef struct {
13
  int active;
14
  int stream_await_count;
15
  co_routine_t* head;
16
  co_routine_t* tail;
17
  pthread_t thread;
18
  pthread_cond_t notify;
19
  pthread_cond_t wait;
20
  pthread_mutex_t mutex;
21
} co_scheduler_t;
22
23
typedef struct {
24
  int line;
25
  int done;
26
} co_state_t;
27
28
typedef co_state_t(*co_task_f)(struct co_routine_s* const self, void* const privates);
29
30
struct co_routine_s {
31
  int line;
32
  int done;
33
  int root;
34
  int other_size;
35
  co_scheduler_t* scheduler;
36
  co_routine_t* prev;
37
  co_routine_t* next;
38
  co_routine_t* notify_any;
39
  co_routine_t* const* others;
40
  co_routine_t* callee;
41
  co_routine_t* caller;
42
  co_task_f fn;
43
};
44
45
#define co_params_0(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,...) _0;_1;_2;_3;_4;_5;_6;_7;_8;_9;_10;_11;_12;_13;_14;_15;_16;_17;_18;_19;_20;_21;_22;_23;_24;_25;_26;_27;_28;_29;_30;_31;_32;_33;_34;_35;_36;_37;_38;_39;_40;_41;_42;_43;_44;_45;_46;_47;_48;_49;_50;_51;_52;_53;_54;_55;_56;_57;_58;_59;_60;_61;_62;_63;
46
47
#define co_params(...) co_params_0(__VA_ARGS__,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)
48
49
106k
#define co_escape(...) __VA_ARGS__
50
51
#define co_private(...) __VA_ARGS__
52
53
#define co_decl_1(_rettype, _func, _param) \
54
  co_state_t _func(co_routine_t* const _self_, void* const _privates_); \
55
  struct _func ## _param_s { \
56
    _rettype _co_ret; \
57
    struct { \
58
      co_params _param \
59
    } _co_params; \
60
  }; \
61
  size_t _func ## _stack_size(void);
62
63
#define co_decl_0(_func, _param) \
64
  co_state_t _func(co_routine_t* const _self, void* const _privates_); \
65
  struct _func ## _param_s { \
66
    struct { \
67
      co_params _param \
68
    } _co_params; \
69
  }; \
70
  size_t _func ## _stack_size(void);
71
72
#define co_decl_sel(_0, _1, _2, ...) _2
73
74
#define co_decl(_func_or_rettype, _param_or_func, ...) co_decl_sel(_0, ## __VA_ARGS__, co_decl_1, co_decl_0)(_func_or_rettype, _param_or_func, ## __VA_ARGS__)
75
76
#define co_task_1(_rettype, _func, _param, _private) \
77
  struct _func ## _private_s { \
78
    struct _func ## _param_s _co_params; \
79
    co_ ## _private \
80
  }; \
81
  size_t _func ## _stack_size(void) { return sizeof(struct _func ## _private_s); } \
82
  co_state_t _func(co_routine_t* const _self_, void* const _privates_) \
83
  { \
84
  struct _private_s { \
85
    struct _func ## _param_s _co_params; \
86
    co_ ## _private \
87
  }; \
88
  switch (_self_->line) { \
89
    case 0:
90
91
#define co_task_0(_func, _param, _private) \
92
79.5k
  struct _func ## _private_s { \
93
79.5k
    struct _func ## _param_s _co_params; \
94
79.5k
    co_ ## _private \
95
79.5k
  }; \
96
79.5k
  size_t _func ## _stack_size(void) 
{ return sizeof(struct _func ## _private_s); }53.0k
\
Unexecuted instantiation: _ccv_nnc_stream_context_add_callback_async_stack_size
_ccv_nnc_graph_exec_cases_of_coro_stack_size
Line
Count
Source
96
2
  size_t _func ## _stack_size(void) { return sizeof(struct _func ## _private_s); } \
_ccv_nnc_graph_wait_any_sub_tasks_stack_size
Line
Count
Source
96
2
  size_t _func ## _stack_size(void) { return sizeof(struct _func ## _private_s); } \
_ccv_nnc_graph_exec_run_loop_stack_size
Line
Count
Source
96
26.5k
  size_t _func ## _stack_size(void) { return sizeof(struct _func ## _private_s); } \
_ccv_nnc_graph_topsorted_run_coro_stack_size
Line
Count
Source
96
26.4k
  size_t _func ## _stack_size(void) { return sizeof(struct _func ## _private_s); } \
97
79.5k
  co_state_t _func(co_routine_t* const _self_, void* const _privates_) \
98
79.5k
  { \
99
79.5k
  struct _private_s { \
100
79.5k
    struct _func ## _param_s _co_params; \
101
79.5k
    co_ ## _private \
102
79.5k
  }; \
103
79.5k
  switch (_self_->line) { \
104
53.0k
    case 0:
105
106
53.0k
#define co_task_sel(_0, _1, _2, ...) _2
107
108
53.0k
#define co_task(_func_or_rettype, _param_or_func, _private_or_param, ...) co_task_sel(_0, ## __VA_ARGS__, co_task_1, co_task_0)(_func_or_rettype, _param_or_func, _private_or_param, ## __VA_ARGS__)
109
110
#define co_decl_task_1(_rettype, _func, _param, _private) \
111
  co_decl_1(_rettype, _func, _param) \
112
  co_task_1(_rettype, _func, _param, _private)
113
114
#define co_decl_task_0(_func, _param, _private) \
115
26.5k
  co_decl_0(_func, _param) \
116
26.5k
  co_task_0(_func, _param, _private)
117
118
26.5k
#define co_decl_task_sel(_0, _1, _2, ...) _2
119
120
26.5k
#define co_decl_task(_func_or_rettype, _param_or_func, _private_or_param, ...) co_decl_task_sel(_0, ## __VA_ARGS__, co_decl_task_1, co_decl_task_0)(_func_or_rettype, _param_or_func, _private_or_param, ## __VA_ARGS__)
121
122
53.0k
#define co_end() default: return (co_state_t){ __LINE__, 1 }; } }
123
124
2.86M
#define CO_P(_x) (((struct _private_s*)(_privates_))->_co_params._co_params._x)
125
4.21M
#define CO_V(_x) (((struct _private_s*)(_privates_))->_x)
126
127
52.9k
#define co_self() (_self_)
128
129
#define co_yield(_val) do { ((struct _private_s*)(_privates_))->_co_params._co_ret = _val; return (co_state_t){ __LINE__, 0 }; case __LINE__: ; } while (0)
130
131
#define co_return_1(_val) do { ((struct _private_s*)(_privates_))->_co_params._co_ret = _val; return (co_state_t){ __LINE__, 1 }; } while (0)
132
133
#define co_return_0() do { return (co_state_t){ __LINE__, 1 }; } while (0)
134
135
#define co_return_sel(_0, _1, _2, ...) _2
136
137
#define co_return(...) co_return_sel(_0, ## __VA_ARGS__, co_return_1, co_return_0)(__VA_ARGS__)
138
139
53.0k
#define co_init(_task, _func, _param) do { \
140
53.0k
  struct _func ## _param_s params = { \
141
53.0k
    ._co_params = { co_escape _param } \
142
53.0k
  }; \
143
53.0k
  _task->fn = _func; \
144
53.0k
  _task->line = 0; \
145
53.0k
  _task->done = 0; \
146
53.0k
  _task->root = 0; \
147
53.0k
  _task->other_size = 0; \
148
53.0k
  _task->notify_any = 0; \
149
53.0k
  _task->others = 0; \
150
53.0k
  _task->caller = 0; \
151
53.0k
  _task->callee = 0; \
152
53.0k
  if (sizeof(params) > 0) \
153
53.0k
    memcpy(_task + 1, &params, sizeof(params)); \
154
53.0k
} while (0)
155
156
53.0k
#define co_size(_func) (sizeof(co_routine_t) + _func ## _stack_size())
157
158
53.0k
#define co_new(_func, _param) ({ \
159
53.0k
  co_routine_t* const task = ccmalloc(co_size(_func)); \
160
53.0k
  co_init(task, _func, _param); \
161
53.0k
  task; \
162
53.0k
})
163
164
#define co_retval_2(_task, _rettype) *(_rettype*)(_task + 1)
165
166
#define co_retval_0() ((struct _private_s*)(_privates_))->_co_params._co_ret
167
168
#define co_retval_sel(_0, _1, _2, _3, ...) _3
169
170
#define co_retval(...) co_retval_sel(_0, ## __VA_ARGS__, co_retval_2, co_retval_1, co_retval_0)(__VA_ARGS__)
171
172
2
#define co_await_any(_tasks, _task_size) do { if (!_co_await_any(_self_, _tasks, _task_size)) { return (co_state_t){ __LINE__, 0 }; } case __LINE__: ; } while (0)
173
174
#define co_await_1(_task, _val) do { \
175
  co_await_any(&(_task), 1); \
176
  _val = co_retval(_task, typeof(_val)); \
177
} while (0)
178
179
#define co_await_0(_task) \
180
0
  co_await_any(&(_task), 1)
181
182
0
#define co_await_sel(_0, _1, _2, ...) _2
183
184
0
#define co_await(_task, ...) co_await_sel(_0, ## __VA_ARGS__, co_await_1, co_await_0)(_task, ## __VA_ARGS__)
185
186
#define co_apply_1(_func, _param, _val) do { \
187
  _self_->callee = co_new(_func, _param); \
188
  _co_apply(_self_, _self_->callee); \
189
  return (co_state_t){ __LINE__, 0 }; \
190
  case __LINE__: \
191
  _val = co_retval(&(_self_->callee), typeof(_val)); \
192
  co_free(_self_->callee); \
193
  _self_->callee = 0; \
194
} while (0)
195
196
26.5k
#define co_apply_0(_func, _param) do { \
197
26.5k
  _self_->callee = co_new(_func, _param); \
198
26.5k
  _co_apply(_self_, _self_->callee); \
199
26.5k
  return (co_state_t){ __LINE__, 0 }; \
200
26.5k
  case __LINE__: \
201
26.5k
  co_free(_self_->callee); \
202
26.5k
  _self_->callee = 0; \
203
26.5k
} while (0)
204
205
26.5k
#define co_apply_sel(_0, _1, _2, ...) _2
206
207
26.5k
#define co_apply(_func, _param, ...) co_apply_sel(_0, ## __VA_ARGS__, co_apply_1, co_apply_0)(_func, _param, ## __VA_ARGS__)
208
209
#define co_resume_1(_task, _val) do { \
210
  _co_resume(_self_, _task); \
211
  return (co_state_t){ __LINE__, 0 }; \
212
  case __LINE__: \
213
  _self_->callee = 0; \
214
  _val = co_retval(_task, typeof(_val)); \
215
} while (0)
216
217
4
#define co_resume_0(_task) do { \
218
4
  _co_resume(_self_, _task); \
219
4
  return (co_state_t){ __LINE__, 0 }; \
220
4
  case __LINE__: \
221
4
  _self_->callee = 0; \
222
4
} while (0)
223
224
4
#define co_resume_sel(_0, _1, _2, ...) _2
225
226
4
#define co_resume(_task, ...) co_resume_sel(_0, ## __VA_ARGS__, co_resume_1, co_resume_0)(_task, ## __VA_ARGS__)
227
228
void _co_prepend_task(co_scheduler_t* const scheduler, co_routine_t* const task);
229
void _co_apply(co_routine_t* const self, co_routine_t* const task);
230
void _co_resume(co_routine_t* const self, co_routine_t* const task);
231
int _co_await_any(co_routine_t* const self, co_routine_t* const* const tasks, const int task_size);
232
233
void co_free(co_routine_t* const task);
234
int co_is_done(const co_routine_t* const task);
235
co_scheduler_t* co_scheduler_new(void);
236
void co_scheduler_free(co_scheduler_t* const scheduler);
237
void co_schedule(co_scheduler_t* const scheduler, co_routine_t* const task);
238
int co_is_on_scheduler(co_scheduler_t* const scheduler);
239
int co_scheduler_is_active(co_scheduler_t* const scheduler);
240
241
#endif