MySQL 8.1.0
Source Code Documentation
task.h
Go to the documentation of this file.
1/* Copyright (c) 2012, 2023, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23#ifndef TASK_H
24#define TASK_H
25
26#include "xcom/xcom_profile.h"
27
28#include <assert.h>
29#include <errno.h>
30#ifndef XCOM_STANDALONE
31#include "my_compiler.h"
32#endif
33#include "xcom/simset.h"
34#include "xcom/task_arg.h"
35#include "xcom/x_platform.h"
36#include "xcom/xcom_common.h"
37
39#include "xcom/result.h"
40
41/** \file
42 Rudimentary task system in portable C, based on Tom Duff's switch-based
43 coroutine trick
44 and a stack of environment structs. (continuations?)
45 Nonblocking IO and event handling need to be rewritten for each new OS.
46*/
47
48#ifdef TASK_EVENT_TRACE
49void add_base_event(double when, char const *file, int state);
50#define ADD_BASE_EVENT \
51 { \
52 add_base_event(seconds(), __FILE__, __LINE__); \
53 add_event(EVENT_DUMP_PAD, string_arg(__func__)); \
54 }
55
56#define ADD_DBG(d, x) \
57 if (do_dbg(d)) { \
58 ADD_BASE_EVENT x; \
59 add_event(EVENT_DUMP_PAD, end_arg()); \
60 }
61
62#define ADD_EVENTS(x) ADD_DBG(D_BUG, x)
63
64#define ADD_T_EV(when, file, state, what)
65#define ADD_WAIT_EV(when, file, state, what, milli)
66
67#else
68#define ADD_EVENTS(x)
69#define ADD_DBG(d, x)
70#define ADD_T_EV(when, file, state, what)
71#define ADD_WAIT_EV(when, file, state, what, milli)
72#endif
73
74static inline void set_int_arg(task_arg *arg, int value) {
75 arg->type = a_int;
76 arg->val.i = value;
77}
78
79static inline int get_int_arg(task_arg arg) {
80 assert(arg.type == a_int);
81 return arg.val.i;
82}
83
84static inline void set_long_arg(task_arg *arg, long value) {
85 arg->type = a_long;
86 arg->val.l = value;
87}
88
89static inline long get_long_arg(task_arg arg) {
90 assert(arg.type == a_long);
91 return arg.val.l;
92}
93
94static inline void set_uint_arg(task_arg *arg, unsigned int value) {
95 arg->type = a_uint;
96 arg->val.u_i = value;
97}
98
99static inline unsigned int get_uint_arg(task_arg arg) {
100 assert(arg.type == a_uint);
101 return arg.val.u_i;
102}
103
104static inline void set_ulong_arg(task_arg *arg, unsigned long value) {
105 arg->type = a_ulong;
106 arg->val.u_l = value;
107}
108
109static inline void set_ulong_long_arg(task_arg *arg, unsigned long long value) {
110 arg->type = a_ulong_long;
111 arg->val.u_ll = value;
112}
113
114static inline unsigned long get_ulong_arg(task_arg arg) {
115 assert(arg.type == a_ulong);
116 return arg.val.u_l;
117}
118
119static inline unsigned long long get_ulong_long_arg(task_arg arg) {
120 assert(arg.type == a_ulong_long);
121 return arg.val.u_l;
122}
123
124static inline void set_float_arg(task_arg *arg, float value) {
125 arg->type = a_float;
126 arg->val.f = value;
127}
128
129static inline float get_float_arg(task_arg arg) {
130 assert(arg.type == a_float);
131 return arg.val.f;
132}
133
134static inline void set_double_arg(task_arg *arg, double value) {
135 arg->type = a_double;
136 arg->val.d = value;
137}
138
139static inline double get_double_arg(task_arg arg) {
140 assert(arg.type == a_double);
141 return arg.val.d;
142}
143
144static inline void set_string_arg(task_arg *arg, char const *value) {
145 arg->type = a_string;
146 arg->val.s = value;
147}
148
149static inline void set_void_arg(task_arg *arg, void *value) {
150 arg->type = a_void;
151 arg->val.v = value;
152}
153
154static inline char const *get_string_arg(task_arg arg) {
155 assert(arg.type == a_string);
156 return (char const *)arg.val.v;
157}
158
159static inline void *get_void_arg(task_arg arg) {
160 assert(arg.type == a_void);
161 return arg.val.v;
162}
163
164static inline task_arg int_arg(int i) {
165 task_arg retval;
166 set_int_arg(&retval, i);
167 return retval;
168}
169
170static inline task_arg uint_arg(unsigned int i) {
171 task_arg retval;
172 set_uint_arg(&retval, i);
173 return retval;
174}
175
176static inline task_arg ulong_arg(unsigned long l) {
177 task_arg retval;
178 set_ulong_arg(&retval, l);
179 return retval;
180}
181
182static inline task_arg ulong_long_arg(unsigned long long ll) {
183 task_arg retval;
184 set_ulong_long_arg(&retval, ll);
185 return retval;
186}
187
188static inline task_arg double_arg(double i) {
189 task_arg retval;
190 set_double_arg(&retval, i);
191 return retval;
192}
193
194static inline task_arg string_arg(char const *v) {
195 task_arg retval;
196 set_string_arg(&retval, v);
197 return retval;
198}
199
200static inline task_arg void_arg(void *v) {
201 task_arg retval;
202 set_void_arg(&retval, v);
203 return retval;
204}
205
206static inline task_arg end_arg() {
207 task_arg retval;
208 retval.type = a_end;
209 return retval;
210}
211
212/* Combined environment pointer and state variable */
213struct task_ptr {
214 int state;
215 void *ptr;
216};
217
218typedef struct task_ptr TaskAlign;
219
220struct task_env;
221
222/* All task functions have this signature */
223typedef int (*task_func)(task_arg arg);
224
225/* Increase this if tasks need bigger stacks, or use a linked list for the stack
226 */
227#define TASK_POOL_ELEMS 1000
228
229typedef enum terminate_enum {
230 RUN = 0,
231 KILL = 1,
232 TERMINATED = 2
234
235/* A complete task.
236 The buffer buf is used for a heap which grows upwards and a stack which grows
237 downwards.
238 The stack contains pointers to environment structs, which are allocated from
239 the heap.
240 */
241struct task_env {
242 linkage l; /* Used for runnable tasks and wait queues */
243 linkage all; /* Links all tasks */
244 int heap_pos; /* Index in time priority queue, necessary for efficient removal
245 */
247 terminate; /* Set this and activate task to make it terminate */
248 int refcnt; /* Number of references to task */
249 int taskret; /* Return value from task function */
250 task_func func; /* The task function */
251 task_arg arg; /* Argument passed to the task */
252 const char *name; /* The task name */
253 TaskAlign *where; /* High water mark in heap */
254 TaskAlign *stack_top; /* The stack top */
255 TaskAlign *sp; /* The current stack pointer */
256 double time; /* Time when the task should be activated */
257 TaskAlign buf[TASK_POOL_ELEMS]; /* Heap and stack */
258 int debug;
260 int interrupt; /* Set if timeout while waiting */
261};
262
263typedef struct task_env task_env;
264
265#define MAXTASKS 1000
266
267/* Priority queue of task_env */
269 int curn;
271};
272typedef struct task_queue task_queue;
273
274#define _ep ((struct env *)(stack->sp->ptr))
275
276#define TASK_ALLOC(pool, type) (task_allocate(pool, (unsigned int)sizeof(type)))
277
278#if 0
279#define TASK_DEBUG(x) \
280 if (stack->debug) { \
281 IFDBG(D_NONE, FN; STRLIT(x " task "); PTREXP((void *)stack); \
282 STRLIT(stack->name); NDBG(stack->sp->state, d)); \
283 }
284#else
285#define TASK_DEBUG(x)
286#endif
287
288/* Place cleanup code after this label */
289#define FINALLY \
290 task_cleanup:
291
292/* We have reached the top of the stack when sp == stack_top + 1 since the stack
293 * grows downwards */
294#define ON_STACK_TOP (stack->sp == stack->stack_top + 1)
295
296/* If we have climbed the stack to the top, check the terminate flag.
297 Execute cleanup code and exit this stack frame if terminate is set.
298 */
299#define TERM_CHECK \
300 if (ON_STACK_TOP && stack->terminate) goto task_cleanup
301
302#define TERMINATE goto task_cleanup
303
304/* Switch on task state. The first time, allocate a new stack frame and check
305 * for termination */
306#define TASK_BEGIN \
307 /* assert(ep); */ \
308 ADD_DBG( \
309 D_TASK, \
310 if (stack->sp->state) { \
311 add_event(EVENT_DUMP_PAD, string_arg("state")); \
312 add_event(EVENT_DUMP_PAD, int_arg(stack->sp->state)); \
313 } add_event(EVENT_DUMP_PAD, string_arg("TASK_BEGIN")); \
314 add_event(EVENT_DUMP_PAD, void_arg(stack));); \
315 TASK_DEBUG("TASK_BEGIN"); \
316 switch (stack->sp->state) { \
317 case 0: \
318 pushp(stack, TASK_ALLOC(stack, struct env)); \
319 ep = _ep; \
320 assert(ep); \
321 ep->init(); \
322 TERM_CHECK;
323
324/* This stack frame is finished, deallocate it and return 0 to signal exit */
325#define TASK_END \
326 ADD_DBG( \
327 D_TASK, \
328 if (stack->sp->state) { \
329 add_event(EVENT_DUMP_PAD, string_arg("state")); \
330 add_event(EVENT_DUMP_PAD, int_arg(stack->sp->state)); \
331 } add_event(EVENT_DUMP_PAD, string_arg("TASK_END")); \
332 add_event(EVENT_DUMP_PAD, void_arg(stack));); \
333 TASK_DEBUG("TASK_END"); \
334 stack->sp->state = 0; \
335 stack->where = (TaskAlign *)stack->sp->ptr; \
336 assert(stack->where); \
337 popp(stack); \
338 return 0; \
339 } \
340 return 0
341
342/* Assign a return value, execute cleanup code, and exit this stack frame */
343#define TASK_RETURN(x) \
344 { \
345 *ret = (x); \
346 goto task_cleanup; \
347 }
348
349#define TASK_DUMP_ERR \
350 if (errno || SOCK_ERRNO || task_errno) { \
351 IFDBG(D_NONE, FN; NDBG(errno, d); STREXP(strerror(errno)); \
352 NDBG(SOCK_ERRNO, d); STREXP(strerror(SOCK_ERRNO)); \
353 NDBG(task_errno, d); STREXP(strerror(task_errno))); \
354 }
355
356/* Assign -1 as exit code, execute cleanup code, and exit this stack frame */
357#define TASK_FAIL \
358 { \
359 *ret = (-1); \
360 TASK_DUMP_ERR; \
361 IFDBG(D_NONE, FN; STRLIT("TASK_FAIL")); \
362 ADD_DBG(D_TASK, add_event(EVENT_DUMP_PAD, string_arg("task failed"))); \
363 goto task_cleanup; \
364 }
365
366/* Capture the line number in the state variable, and return.
367 When called again (after the switch label), check for termination.
368*/
369#define TASK_YIELD \
370 { \
371 TASK_DEBUG("TASK_YIELD"); \
372 stack->sp->state = __LINE__; \
373 return 1; \
374 case __LINE__: \
375 TASK_DEBUG("RETURN FROM YIELD"); \
376 ep = _ep; \
377 assert(ep); \
378 TERM_CHECK; \
379 }
380
381#define TASK_DEACTIVATE \
382 { \
383 TASK_DEBUG("TASK_DEACTIVATE"); \
384 task_deactivate(stack); \
385 TASK_YIELD; \
386 }
387
388/* Put the task in the queue of tasks waiting for timeout, then yield.
389 Wait until current time + t seconds.
390 */
391#define TASK_DELAY(t) \
392 { \
393 TASK_DEBUG("TASK_DELAY"); \
394 task_delay_until(seconds() + t); \
395 TASK_YIELD; \
396 }
397
398/* Put the task in the queue of tasks waiting for timeout, then yield.
399 Wait until t.
400 */
401#define TASK_DELAY_UNTIL(t) \
402 { \
403 TASK_DEBUG("TASK_DELAY_UNTIL"); \
404 task_delay_until(t); \
405 TASK_YIELD; \
406 }
407
408/* Put the task in a wait queue, then yield */
409#define TASK_WAIT(queue) \
410 { \
411 TASK_DEBUG("TASK_WAIT"); \
412 task_wait(stack, queue); \
413 TASK_YIELD; \
414 }
415
416/* Put the task in a wait queue with timeout, then yield */
417#define TIMED_TASK_WAIT(queue, t) \
418 { \
419 TASK_DEBUG("TIMED_TASK_WAIT"); \
420 task_delay_until(seconds() + (t)); \
421 task_wait(stack, queue); \
422 TASK_YIELD; \
423 }
424
425/* A channel has a queue of data elements and a queue of waiting tasks */
426struct channel {
429};
430
431typedef struct channel channel;
432
433/* Channel construction */
434channel *channel_init(channel *c, unsigned int type);
435
436/* Put data in channel. No wait, since channels can never be full */
437void channel_put(channel *c, linkage *data); /* Append to queue */
439 linkage *data); /* Insert in front of queue */
440
441/* Wait until there is data in the channel, then extract and cast to type */
442#define CHANNEL_GET(channel, ptr, type) \
443 { \
444 while (link_empty(&(channel)->data)) { \
445 TASK_WAIT(&(channel)->queue); \
446 } \
447 *(ptr) = (type *)link_extract_first(&(channel)->data); \
448 IFDBG(D_TRANSPORT, FN; STRLIT("CHANNEL_GET "); PTREXP(*(ptr)); \
449 PTREXP(&((channel)->data))); \
450 }
451
452#define CHANNEL_PEEK(channel, ptr, type) \
453 { \
454 while (link_empty(&(channel)->data)) { \
455 TASK_WAIT(&(channel)->queue); \
456 } \
457 *(ptr) = (type *)link_first(&(channel)->data); \
458 }
459
460#define CHANNEL_GET_REVERSE(channel, ptr, type) \
461 { \
462 while (link_empty(&(channel)->data)) { \
463 TASK_WAIT(&(channel)->queue); \
464 } \
465 *(ptr) = (type *)link_extract_last(&(channel)->data); \
466 }
467
468/*
469 The first time, reset the state of the stack frame of the called function.
470 Keep calling the function until it returns 0, which signals exit.
471 Yield after each call.
472 */
473#define TASK_CALL(funcall) \
474 { \
475 reset_state(stack); \
476 TASK_DEBUG("BEFORE CALL"); \
477 do { \
478 stack->sp--; \
479 stack->taskret = funcall; \
480 stack->sp++; \
481 TERM_CHECK; \
482 if (stack->taskret) TASK_YIELD; \
483 } while (stack->taskret); \
484 TASK_DEBUG("AFTER CALL"); \
485 }
486
487/* Define the typeless struct which is the container for all variables in the
488 * stack frame */
489#define DECL_ENV struct env {
490/*Define a code block where we can init ENV variables. It only works nested
491 within DECL_ENV
492*/
493#define ENV_INIT void init() {
494/*Ends the default initialization block*/
495#define END_ENV_INIT }
496
497/* Define a pointer to the environment struct */
498#define END_ENV \
499 } \
500 ; \
501 [[maybe_unused]] struct env *ep
502
503/* Try to lock a fd for read or write.
504 Yield and spin until it succeeds.
505*/
506#define LOCK_FD(fd, op) \
507 { \
508 while (!lock_fd( \
509 fd, stack, \
510 op)) { /* Effectively a spin lock, but should not happen very often */ \
511 wait_io(stack, fd, op); \
512 TASK_YIELD; \
513 /* TASK_DELAY(1.0); */ \
514 } \
515 }
516
517/* Unlock a fd */
518#define UNLOCK_FD(fd, op) unlock_fd(fd, stack, op)
519
520#ifdef TASK_EVENT_TRACE
521enum { EVENT_DUMP_PAD = 1, EVENT_DUMP_HEX = 2 };
522
523struct task_event {
524 task_arg arg;
525 int flag;
526};
527
528typedef struct task_event task_event;
529
530void add_event(int flag, task_arg te);
531void add_task_event(double when, char const *file, int state, char const *what);
532void add_wait_event(double when, char const *file, int state, char const *what,
533 int milli);
534void dump_task_events();
535void reset_task_events();
536#endif
537
538/* The current task */
539extern task_env *stack;
540
541extern void *task_allocate(task_env *p, unsigned int bytes);
542extern void reset_state(task_env *p);
543extern void pushp(task_env *p, void *ptr);
544extern void popp(task_env *p);
545
546extern double seconds(); /* Return time as double */
547extern double task_now(); /* Return result of last call to seconds() */
548extern void task_delay_until(double time);
549
550/**
551 Return time in microseconds. Uses std::chrono::high_resolution_clock
552
553 @retval Number of microseconds since the Epoch, 1970-01-01 00:00:00 +0000
554 (UTC)
555*/
556unsigned long long int get_time_since_the_epoch();
557
558extern int unblock_fd(int fd);
559extern int block_fd(int fd);
560
562 void *buf, int n);
563
564extern result con_read(connection_descriptor const *rfd, void *buf, int n);
565extern result con_pipe_read(connection_descriptor const *rfd, void *buf, int n);
566
567extern int task_read(connection_descriptor const *con, void *buf, int n,
568 int64_t *ret,
569 connnection_read_method read_function = con_read);
570
572 void *buf, int n);
573result con_write(connection_descriptor const *wfd, void *buf, int n);
574result con_pipe_write(connection_descriptor const *wfd, void *buf, int n);
575
576extern int task_write(connection_descriptor const *con, void *buf, uint32_t n,
577 int64_t *ret);
578extern int is_locked(int fd);
579extern int lock_fd(int fd, task_env *t, int lock);
580extern int unlock_fd(int fd, task_env *t, int lock);
581
582extern void task_sys_init();
583extern task_env *task_new(task_func func, task_arg arg, const char *name,
584 int debug);
585#define xstr(s) #s
586/* #define task_new(func, arg) _task_new(func, arg, __FILE__":" xstr(__LINE__))
587 */
588extern void task_loop();
589extern void task_wait(task_env *t, linkage *queue);
590extern void task_wakeup(linkage *queue);
592extern void set_task(task_env **p, task_env *t);
593extern void task_terminate_all();
594extern void remove_and_wakeup(int i);
595extern int task_errno;
596extern int is_only_task();
599extern const char *task_name();
600extern task_env *wait_io(task_env *t, int fd, int op);
601
602extern result con_write(connection_descriptor const *wfd, void *buf, int n);
603extern result set_nodelay(int fd);
604
605extern task_env *timed_wait_io(task_env *t, int fd, int op, double timeout);
606
607extern xcom_proto const my_min_xcom_version; /* The minimum protocol version I
608 am able to understand */
609extern xcom_proto const
610 my_xcom_version; /* The maximum protocol version I am able to understand */
611
612#endif
static char * add_event(const char *var, LEX_CSTRING event, const char *data, size_t data_length)
Definition: audit_null.cc:305
static char buf[MAX_BUF]
Definition: conf_to_src.cc:72
const char * p
Definition: ctype-mb.cc:1234
static int flag
Definition: hp_test1.cc:39
Header for compiler-dependent features.
static QUEUE queue
Definition: myisampack.cc:209
Definition: buf0block_hint.cc:29
Definition: os0file.h:85
Provides atomic access in shared-exclusive modes.
Definition: shared_spin_lock.h:78
static bool timeout(bool(*wait_condition)())
Timeout function.
Definition: log0meb.cc:497
struct result result
Definition: result.h:33
required string type
Definition: replication_group_member_actions.proto:33
case opt name
Definition: sslopt-case.h:32
Definition: task.h:426
linkage queue
Definition: task.h:428
linkage data
Definition: task.h:427
Definition: node_connection.h:46
Definition: simset.h:35
Definition: result.h:29
Definition: task_arg.h:41
unsigned long u_l
Definition: task_arg.h:47
float f
Definition: task_arg.h:49
double d
Definition: task_arg.h:50
void * v
Definition: task_arg.h:52
long l
Definition: task_arg.h:45
unsigned int u_i
Definition: task_arg.h:46
char const * s
Definition: task_arg.h:51
arg_type type
Definition: task_arg.h:42
union task_arg::@17 val
unsigned long long u_ll
Definition: task_arg.h:48
int i
Definition: task_arg.h:44
Definition: task.h:241
task_func func
Definition: task.h:250
linkage l
Definition: task.h:242
TaskAlign * sp
Definition: task.h:255
int interrupt
Definition: task.h:260
int waitfd
Definition: task.h:259
TaskAlign * stack_top
Definition: task.h:254
task_arg arg
Definition: task.h:251
double time
Definition: task.h:256
linkage all
Definition: task.h:243
int taskret
Definition: task.h:249
int refcnt
Definition: task.h:248
int heap_pos
Definition: task.h:244
int debug
Definition: task.h:258
TaskAlign * where
Definition: task.h:253
terminate_enum terminate
Definition: task.h:247
const char * name
Definition: task.h:252
Definition: task.h:213
int state
Definition: task.h:214
void * ptr
Definition: task.h:215
Definition: task.h:268
int curn
Definition: task.h:269
task_env * x[MAXTASKS+1]
Definition: task.h:270
static double get_double_arg(task_arg arg)
Definition: task.h:139
int task_errno
Definition: task.cc:133
void task_sys_init()
Definition: task.cc:1287
void channel_put(channel *c, linkage *data)
Definition: task.cc:609
static void set_ulong_long_arg(task_arg *arg, unsigned long long value)
Definition: task.h:109
static void set_ulong_arg(task_arg *arg, unsigned long value)
Definition: task.h:104
#define MAXTASKS
Definition: task.h:265
static void set_int_arg(task_arg *arg, int value)
Definition: task.h:74
static task_arg string_arg(char const *v)
Definition: task.h:194
#define TASK_POOL_ELEMS
Definition: task.h:227
void task_wakeup(linkage *queue)
Definition: task.cc:584
static unsigned long long get_ulong_long_arg(task_arg arg)
Definition: task.h:119
task_env * task_deactivate(task_env *t)
Definition: task.cc:731
void popp(task_env *p)
Definition: task.cc:680
result con_write(connection_descriptor const *wfd, void *buf, int n)
Definition: task.cc:994
int unlock_fd(int fd, task_env *t, int lock)
result con_read(connection_descriptor const *rfd, void *buf, int n)
Definition: task.cc:906
static task_arg void_arg(void *v)
Definition: task.h:200
double seconds()
Definition: task.cc:309
static void set_float_arg(task_arg *arg, float value)
Definition: task.h:124
static task_arg uint_arg(unsigned int i)
Definition: task.h:170
static unsigned int get_uint_arg(task_arg arg)
Definition: task.h:99
static task_arg ulong_arg(unsigned long l)
Definition: task.h:176
void channel_put_front(channel *c, linkage *data)
Definition: task.cc:615
terminate_enum
Definition: task.h:229
@ TERMINATED
Definition: task.h:232
@ RUN
Definition: task.h:230
@ KILL
Definition: task.h:231
int(* task_func)(task_arg arg)
Definition: task.h:223
static task_arg int_arg(int i)
Definition: task.h:164
void task_delay_until(double time)
Definition: task.cc:568
task_env * task_terminate(task_env *t)
Definition: task.cc:734
task_env * timed_wait_io(task_env *t, int fd, int op, double timeout)
int task_write(connection_descriptor const *con, void *buf, uint32_t n, int64_t *ret)
Definition: task.cc:1040
int task_read(connection_descriptor const *con, void *buf, int n, int64_t *ret, connnection_read_method read_function=con_read)
Definition: task.cc:949
result con_pipe_read(connection_descriptor const *rfd, void *buf, int n)
Definition: task.cc:932
static void set_string_arg(task_arg *arg, char const *value)
Definition: task.h:144
static task_arg end_arg()
Definition: task.h:206
unsigned long long int get_time_since_the_epoch()
Return time in microseconds.
Definition: task.cc:384
int is_only_task()
Definition: task.cc:1135
result set_nodelay(int fd)
Definition: xcom_transport.cc:132
result(* connnection_read_method)(connection_descriptor const *rfd, void *buf, int n)
Definition: task.h:561
const char * task_name()
Definition: task.cc:1309
static task_arg ulong_long_arg(unsigned long long ll)
Definition: task.h:182
xcom_proto const my_xcom_version
Definition: xcom_transport.cc:81
result(* connnection_write_method)(connection_descriptor const *rfd, void *buf, int n)
Definition: task.h:571
channel * channel_init(channel *c, unsigned int type)
Definition: task.cc:603
int unblock_fd(int fd)
Definition: task.cc:1097
void reset_state(task_env *p)
Definition: task.cc:660
void remove_and_wakeup(int i)
Definition: task.cc:879
static void set_long_arg(task_arg *arg, long value)
Definition: task.h:84
static void * get_void_arg(task_arg arg)
Definition: task.h:159
void task_wait(task_env *t, linkage *queue)
Definition: task.cc:576
static void set_uint_arg(task_arg *arg, unsigned int value)
Definition: task.h:94
static task_arg double_arg(double i)
Definition: task.h:188
static int get_int_arg(task_arg arg)
Definition: task.h:79
result con_pipe_write(connection_descriptor const *wfd, void *buf, int n)
Definition: task.cc:1022
xcom_proto const my_min_xcom_version
Definition: xcom_transport.cc:79
static float get_float_arg(task_arg arg)
Definition: task.h:129
static long get_long_arg(task_arg arg)
Definition: task.h:89
double task_now()
Definition: task.cc:317
task_env * stack
Definition: task.cc:891
void task_loop()
Definition: task.cc:1156
void * task_allocate(task_env *p, unsigned int bytes)
Allocate bytes from pool, initialized to zero.
Definition: task.cc:642
void set_task(task_env **p, task_env *t)
Definition: task.cc:1303
task_env * task_activate(task_env *t)
Definition: task.cc:729
task_env * task_new(task_func func, task_arg arg, const char *name, int debug)
Definition: task.cc:621
int lock_fd(int fd, task_env *t, int lock)
task_env * wait_io(task_env *t, int fd, int op)
Definition: task.cc:893
int block_fd(int fd)
Definition: task.cc:1115
int is_locked(int fd)
static char const * get_string_arg(task_arg arg)
Definition: task.h:154
void task_terminate_all()
Definition: task.cc:747
static unsigned long get_ulong_arg(task_arg arg)
Definition: task.h:114
static void set_double_arg(task_arg *arg, double value)
Definition: task.h:134
static void set_void_arg(task_arg *arg, void *value)
Definition: task.h:149
void pushp(task_env *p, void *ptr)
Definition: task.cc:669
@ a_int
Definition: task_arg.h:28
@ a_double
Definition: task_arg.h:34
@ a_end
Definition: task_arg.h:37
@ a_ulong_long
Definition: task_arg.h:32
@ a_uint
Definition: task_arg.h:30
@ a_long
Definition: task_arg.h:29
@ a_void
Definition: task_arg.h:35
@ a_float
Definition: task_arg.h:33
@ a_string
Definition: task_arg.h:36
@ a_ulong
Definition: task_arg.h:31
int n
Definition: xcom_base.cc:508