/src/haproxy/include/haproxy/task-t.h
Line | Count | Source |
1 | | /* |
2 | | * include/haproxy/task-t.h |
3 | | * Macros, variables and structures for task management. |
4 | | * |
5 | | * Copyright (C) 2000-2010 Willy Tarreau - w@1wt.eu |
6 | | * |
7 | | * This library is free software; you can redistribute it and/or |
8 | | * modify it under the terms of the GNU Lesser General Public |
9 | | * License as published by the Free Software Foundation, version 2.1 |
10 | | * exclusively. |
11 | | * |
12 | | * This library is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | | * Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public |
18 | | * License along with this library; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | | */ |
21 | | |
22 | | #ifndef _HAPROXY_TASK_T_H |
23 | | #define _HAPROXY_TASK_T_H |
24 | | |
25 | | #include <sys/time.h> |
26 | | |
27 | | #include <import/ebtree-t.h> |
28 | | |
29 | | #include <haproxy/api-t.h> |
30 | | #include <haproxy/show_flags-t.h> |
31 | | #include <haproxy/thread-t.h> |
32 | | |
33 | | /* values for task->state (32 bits). |
34 | | * Please also update the task_show_state() function below in case of changes. |
35 | | */ |
36 | 0 | #define TASK_SLEEPING 0x00000000 /* task sleeping */ |
37 | 0 | #define TASK_RUNNING 0x00000001 /* the task is currently running */ |
38 | | /* unused 0x00000002 */ |
39 | 0 | #define TASK_QUEUED 0x00000004 /* The task has been (re-)added to the run queue */ |
40 | | #define TASK_RT 0x00000008 /* This task always skips the priority queue */ |
41 | 0 | #define TASK_SELF_WAKING 0x00000010 /* task/tasklet found waking itself */ |
42 | 0 | #define TASK_KILLED 0x00000020 /* task/tasklet killed, may now be freed */ |
43 | 0 | #define TASK_HEAVY 0x00000080 /* this task/tasklet is extremely heavy */ |
44 | | |
45 | 0 | #define TASK_WOKEN_INIT 0x00000100 /* woken up for initialisation purposes */ |
46 | 0 | #define TASK_WOKEN_TIMER 0x00000200 /* woken up because of expired timer */ |
47 | 0 | #define TASK_WOKEN_IO 0x00000400 /* woken up because of completed I/O */ |
48 | 0 | #define TASK_WOKEN_SIGNAL 0x00000800 /* woken up by a system signal */ |
49 | 0 | #define TASK_WOKEN_MSG 0x00001000 /* woken up by another task's message (see also UEVT/USR1) */ |
50 | 0 | #define TASK_WOKEN_RES 0x00002000 /* woken up because of available resource */ |
51 | 0 | #define TASK_WOKEN_OTHER 0x00004000 /* woken up for an unspecified reason (see also UEVT/USR1) */ |
52 | | |
53 | | /* use this to check a task state or to clean it up before queueing */ |
54 | 0 | #define TASK_WOKEN_ANY (TASK_WOKEN_OTHER|TASK_WOKEN_INIT|TASK_WOKEN_TIMER| \ |
55 | 0 | TASK_WOKEN_IO|TASK_WOKEN_SIGNAL|TASK_WOKEN_MSG| \ |
56 | 0 | TASK_WOKEN_RES|TASK_WOKEN_WQ) |
57 | | |
58 | 0 | #define TASK_F_TASKLET 0x00008000 /* nature of this task: 0=task 1=tasklet */ |
59 | 0 | #define TASK_F_USR1 0x00010000 /* preserved user flag 1, application-specific, def:0 */ |
60 | 0 | #define TASK_F_UEVT1 0x00020000 /* one-shot user event type 1, application specific, def:0 */ |
61 | 0 | #define TASK_F_UEVT2 0x00040000 /* one-shot user event type 2, application specific, def:0 */ |
62 | 0 | #define TASK_F_WANTS_TIME 0x00080000 /* task/tasklet wants th_ctx->sched_call_date to be set */ |
63 | 0 | #define TASK_F_UEVT3 0x00100000 /* one-shot user event type 3, application specific, def:0 */ |
64 | 0 | #define TASK_WOKEN_WQ 0x00200000 /* The task has been waken up only to be put in the wait queue, because its expire changed */ |
65 | | /* unused: 0x400000..0x80000000 */ |
66 | | |
67 | | /* These flags are persistent across scheduler calls */ |
68 | | #define TASK_PERSISTENT (TASK_SELF_WAKING | TASK_KILLED | TASK_RT | \ |
69 | | TASK_HEAVY | TASK_F_TASKLET | TASK_F_USR1 | \ |
70 | | TASK_F_WANTS_TIME) |
71 | | |
72 | | /* This function is used to report state in debugging tools. Please reflect |
73 | | * below any single-bit flag addition above in the same order via the |
74 | | * __APPEND_FLAG macro. The new end of the buffer is returned. |
75 | | */ |
76 | | static forceinline char *task_show_state(char *buf, size_t len, const char *delim, uint flg) |
77 | 0 | { |
78 | 0 | #define _(f, ...) __APPEND_FLAG(buf, len, delim, flg, f, #f, __VA_ARGS__) |
79 | 0 | /* prologue */ |
80 | 0 | _(0); |
81 | 0 | /* flags */ |
82 | 0 | _(TASK_RUNNING, _(TASK_QUEUED, _(TASK_SELF_WAKING, |
83 | 0 | _(TASK_KILLED, _(TASK_HEAVY, _(TASK_WOKEN_INIT, |
84 | 0 | _(TASK_WOKEN_TIMER, _(TASK_WOKEN_IO, _(TASK_WOKEN_SIGNAL, |
85 | 0 | _(TASK_WOKEN_MSG, _(TASK_WOKEN_RES, _(TASK_WOKEN_OTHER, |
86 | 0 | _(TASK_F_TASKLET, _(TASK_F_USR1, _(TASK_WOKEN_WQ))))))))))))))); |
87 | 0 | /* epilogue */ |
88 | 0 | _(~0U); |
89 | 0 | return buf; |
90 | 0 | #undef _ |
91 | 0 | } Unexecuted instantiation: fuzz_hpack_decode.c:task_show_state Unexecuted instantiation: fuzz_h1_htx.c:task_show_state Unexecuted instantiation: chunk.c:task_show_state Unexecuted instantiation: debug.c:task_show_state Unexecuted instantiation: fd.c:task_show_state Unexecuted instantiation: h1_htx.c:task_show_state Unexecuted instantiation: haproxy.c:task_show_state Unexecuted instantiation: http.c:task_show_state Unexecuted instantiation: http_htx.c:task_show_state Unexecuted instantiation: htx.c:task_show_state Unexecuted instantiation: limits.c:task_show_state Unexecuted instantiation: listener.c:task_show_state Unexecuted instantiation: log.c:task_show_state Unexecuted instantiation: mworker.c:task_show_state Unexecuted instantiation: peers.c:task_show_state Unexecuted instantiation: pool.c:task_show_state Unexecuted instantiation: proto_sockpair.c:task_show_state Unexecuted instantiation: protocol.c:task_show_state Unexecuted instantiation: proxy.c:task_show_state Unexecuted instantiation: resolvers.c:task_show_state Unexecuted instantiation: ring.c:task_show_state Unexecuted instantiation: sample.c:task_show_state Unexecuted instantiation: server.c:task_show_state Unexecuted instantiation: session.c:task_show_state Unexecuted instantiation: signal.c:task_show_state Unexecuted instantiation: sink.c:task_show_state Unexecuted instantiation: sock.c:task_show_state Unexecuted instantiation: sock_inet.c:task_show_state Unexecuted instantiation: stats-proxy.c:task_show_state Unexecuted instantiation: stats.c:task_show_state Unexecuted instantiation: stconn.c:task_show_state Unexecuted instantiation: stick_table.c:task_show_state Unexecuted instantiation: stream.c:task_show_state Unexecuted instantiation: systemd.c:task_show_state Unexecuted instantiation: task.c:task_show_state Unexecuted instantiation: tcp_rules.c:task_show_state Unexecuted instantiation: tcpcheck.c:task_show_state Unexecuted instantiation: thread.c:task_show_state Unexecuted instantiation: tools.c:task_show_state Unexecuted instantiation: trace.c:task_show_state Unexecuted instantiation: uri_auth.c:task_show_state Unexecuted instantiation: vars.c:task_show_state Unexecuted instantiation: version.c:task_show_state Unexecuted instantiation: acl.c:task_show_state Unexecuted instantiation: action.c:task_show_state Unexecuted instantiation: activity.c:task_show_state Unexecuted instantiation: applet.c:task_show_state Unexecuted instantiation: arg.c:task_show_state Unexecuted instantiation: auth.c:task_show_state Unexecuted instantiation: backend.c:task_show_state Unexecuted instantiation: cfgparse-listen.c:task_show_state Unexecuted instantiation: cfgparse.c:task_show_state Unexecuted instantiation: channel.c:task_show_state Unexecuted instantiation: check.c:task_show_state Unexecuted instantiation: cli.c:task_show_state Unexecuted instantiation: clock.c:task_show_state Unexecuted instantiation: connection.c:task_show_state Unexecuted instantiation: counters.c:task_show_state Unexecuted instantiation: dgram.c:task_show_state Unexecuted instantiation: dns.c:task_show_state Unexecuted instantiation: dns_ring.c:task_show_state Unexecuted instantiation: dynbuf.c:task_show_state Unexecuted instantiation: errors.c:task_show_state Unexecuted instantiation: event_hdl.c:task_show_state Unexecuted instantiation: extcheck.c:task_show_state Unexecuted instantiation: filters.c:task_show_state Unexecuted instantiation: fix.c:task_show_state Unexecuted instantiation: flt_http_comp.c:task_show_state Unexecuted instantiation: freq_ctr.c:task_show_state Unexecuted instantiation: frontend.c:task_show_state Unexecuted instantiation: guid.c:task_show_state Unexecuted instantiation: h1.c:task_show_state Unexecuted instantiation: haterm.c:task_show_state Unexecuted instantiation: http_ana.c:task_show_state Unexecuted instantiation: http_ext.c:task_show_state Unexecuted instantiation: http_fetch.c:task_show_state Unexecuted instantiation: http_rules.c:task_show_state Unexecuted instantiation: lb_chash.c:task_show_state Unexecuted instantiation: lb_fas.c:task_show_state Unexecuted instantiation: lb_fwlc.c:task_show_state Unexecuted instantiation: lb_fwrr.c:task_show_state Unexecuted instantiation: lb_map.c:task_show_state Unexecuted instantiation: lb_ss.c:task_show_state Unexecuted instantiation: mailers.c:task_show_state Unexecuted instantiation: mqtt.c:task_show_state Unexecuted instantiation: mux_spop.c:task_show_state Unexecuted instantiation: pattern.c:task_show_state Unexecuted instantiation: payload.c:task_show_state Unexecuted instantiation: pipe.c:task_show_state Unexecuted instantiation: proto_rhttp.c:task_show_state Unexecuted instantiation: queue.c:task_show_state Unexecuted instantiation: regex.c:task_show_state Unexecuted instantiation: stats-file.c:task_show_state Unexecuted instantiation: stats-html.c:task_show_state Unexecuted instantiation: stats-json.c:task_show_state Unexecuted instantiation: cache.c:task_show_state Unexecuted instantiation: cfgcond.c:task_show_state Unexecuted instantiation: cfgparse-global.c:task_show_state Unexecuted instantiation: compression.c:task_show_state Unexecuted instantiation: fcgi-app.c:task_show_state Unexecuted instantiation: flt_spoe.c:task_show_state Unexecuted instantiation: proto_tcp.c:task_show_state Unexecuted instantiation: shctx.c:task_show_state Unexecuted instantiation: fuzz_http.c:task_show_state Unexecuted instantiation: fuzz_cfg_parser.c:task_show_state Unexecuted instantiation: fuzz_h1_parse.c:task_show_state |
92 | | |
93 | | /* these wakeup types are used to indicate how a task/tasklet was woken up, for |
94 | | * debugging purposes. |
95 | | */ |
96 | | enum { |
97 | | WAKEUP_TYPE_UNSET = 0, |
98 | | WAKEUP_TYPE_TASK_WAKEUP, |
99 | | WAKEUP_TYPE_TASK_INSTANT_WAKEUP, |
100 | | WAKEUP_TYPE_TASKLET_WAKEUP, |
101 | | WAKEUP_TYPE_TASKLET_WAKEUP_AFTER, |
102 | | WAKEUP_TYPE_TASK_SCHEDULE, |
103 | | WAKEUP_TYPE_TASK_QUEUE, |
104 | | WAKEUP_TYPE_APPCTX_WAKEUP, |
105 | | }; |
106 | | |
107 | | struct notification { |
108 | | struct list purge_me; /* Part of the list of signals to be purged in the |
109 | | case of the LUA execution stack crash. */ |
110 | | struct mt_list wake_me; /* thread safe signal list */ |
111 | | struct task *task; /* The task to be wake if an event occurs. */ |
112 | | __decl_thread(HA_SPINLOCK_T lock); |
113 | | }; |
114 | | |
115 | | #ifdef DEBUG_TASK |
116 | | /* prev_caller keeps a copy of the previous value of the <caller> field. */ |
117 | | #define TASK_DEBUG_STORAGE \ |
118 | | struct { \ |
119 | | const struct ha_caller *prev_caller; \ |
120 | | } debug |
121 | | #else |
122 | | #define TASK_DEBUG_STORAGE |
123 | | #endif |
124 | | |
125 | | /* This part is common between struct task and struct tasklet so that tasks |
126 | | * can be used as-is as tasklets. |
127 | | * |
128 | | * Note that the process() function must ALWAYS return the task/tasklet's |
129 | | * pointer if the task/tasklet remains valid, and return NULL if it has been |
130 | | * deleted. The scheduler relies on this to know if it should update its state |
131 | | * on return. |
132 | | * |
133 | | * Keep in mind that tasks can be cast to tasklets while in the final tasklet |
134 | | * queues, and will be listed via the tasklet's <list> instead of the task's |
135 | | * <rq>. However other fields (wq, common) must remain totally valid for the |
136 | | * task during this time. This explains why certain elements are present in |
137 | | * the common part even though pure tasklets do not need them. |
138 | | */ |
139 | | #define TASK_COMMON \ |
140 | | unsigned int state; /* task state : bitfield of TASK_ */ \ |
141 | | int tid; /* tid of task/tasklet. <0 = local for tasklet, unbound for task */ \ |
142 | | struct task *(*process)(struct task *t, void *ctx, unsigned int state); /* the function which processes the task */ \ |
143 | | void *context; /* the task's context */ \ |
144 | | const struct ha_caller *caller; /* call place of last wakeup(); 0 on init, -1 on free */ \ |
145 | | uint32_t wake_date; /* date of the last task wakeup */ \ |
146 | | unsigned int calls; /* number of times process was called */ \ |
147 | | TASK_DEBUG_STORAGE; \ |
148 | | short last_run; /* 16-bit now_ms of last run */ \ |
149 | | short nice; /* task prio from -1024 to +1024 */ \ |
150 | | int expire; /* next expiration date for this task, in ticks */ |
151 | | /* total: 36 or 48 bytes on 32/64 bit platforms */ |
152 | | |
153 | | /* The base for all tasks */ |
154 | | struct task { |
155 | | TASK_COMMON; /* must be at the beginning! */ |
156 | | struct eb32_node rq; /* ebtree node used to hold the task in the run queue */ |
157 | | /* WARNING: the struct task is often aliased as a struct tasklet when |
158 | | * it is NOT in the run queue. The tasklet has its struct list here |
159 | | * where rq starts and this works because both are exclusive. Never |
160 | | * ever reorder these fields without taking this into account! |
161 | | */ |
162 | | struct eb32_node wq; /* ebtree node used to hold the task in the wait queue */ |
163 | | }; |
164 | | |
165 | | /* lightweight tasks, without priority, mainly used for I/Os */ |
166 | | struct tasklet { |
167 | | TASK_COMMON; /* must be at the beginning! */ |
168 | | struct list list; |
169 | | /* WARNING: the struct task is often aliased as a struct tasklet when |
170 | | * it is not in the run queue. The task has its struct rq here where |
171 | | * list starts and this works because both are exclusive. Never ever |
172 | | * reorder these fields without taking this into account! |
173 | | */ |
174 | | }; |
175 | | |
176 | | /* Note: subscribing to these events is only valid after the caller has really |
177 | | * attempted to perform the operation, and failed to proceed or complete. |
178 | | */ |
179 | | enum sub_event_type { |
180 | | SUB_RETRY_RECV = 0x00000001, /* Schedule the tasklet when we can attempt to recv again */ |
181 | | SUB_RETRY_SEND = 0x00000002, /* Schedule the tasklet when we can attempt to send again */ |
182 | | }; |
183 | | |
184 | | /* Describes a set of subscriptions. Multiple events may be registered at the |
185 | | * same time. The callee should assume everything not pending for completion is |
186 | | * implicitly possible. It's illegal to change the tasklet if events are still |
187 | | * registered. |
188 | | */ |
189 | | struct wait_event { |
190 | | struct tasklet *tasklet; |
191 | | int events; /* set of enum sub_event_type above */ |
192 | | }; |
193 | | |
194 | | /* |
195 | | * The task callback (->process) is responsible for updating ->expire. It must |
196 | | * return a pointer to the task itself, except if the task has been deleted, in |
197 | | * which case it returns NULL so that the scheduler knows it must not check the |
198 | | * expire timer. The scheduler will requeue the task at the proper location. |
199 | | */ |
200 | | |
201 | | |
202 | | #endif /* _HAPROXY_TASK_T_H */ |
203 | | |
204 | | /* |
205 | | * Local variables: |
206 | | * c-indent-level: 8 |
207 | | * c-basic-offset: 8 |
208 | | * End: |
209 | | */ |