blob: 1db30805c0d4a11a4a848e0d16809e44c044f806 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 include/proto/task.h
3 Functions for task management.
4
Willy Tarreau4726f532009-03-07 17:25:21 +01005 Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
Willy Tarreaubaaee002006-06-26 02:48:02 +02006
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 _PROTO_TASK_H
23#define _PROTO_TASK_H
24
25
26#include <sys/time.h>
Willy Tarreaue3ba5f02006-06-29 18:54:54 +020027
28#include <common/config.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020029#include <common/memory.h>
Willy Tarreau96bcfd72007-04-29 10:41:56 +020030#include <common/mini-clist.h>
31#include <common/standard.h>
32
Willy Tarreaue3ba5f02006-06-29 18:54:54 +020033#include <types/task.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020034
Willy Tarreau91e99932008-06-30 07:51:00 +020035extern unsigned int run_queue; /* run queue size */
36extern unsigned int niced_tasks; /* number of niced tasks in the run queue */
Willy Tarreauc6ca1a02007-05-13 19:43:47 +020037extern struct pool_head *pool2_task;
Willy Tarreauce44f122008-07-05 18:16:19 +020038extern struct task *last_timer; /* optimization: last queued timer */
Willy Tarreauc6ca1a02007-05-13 19:43:47 +020039
Willy Tarreau9789f7b2008-06-24 08:17:16 +020040/* perform minimal initializations, report 0 in case of error, 1 if OK. */
Willy Tarreauc6ca1a02007-05-13 19:43:47 +020041int init_task();
Willy Tarreau96bcfd72007-04-29 10:41:56 +020042
Willy Tarreau4726f532009-03-07 17:25:21 +010043/* return 0 if task is in run queue, otherwise non-zero */
44static inline int task_in_rq(struct task *t)
45{
46 return t->rq.node.leaf_p != NULL;
47}
48
49/* return 0 if task is in wait queue, otherwise non-zero */
50static inline int task_in_wq(struct task *t)
51{
52 return t->wq.node.leaf_p != NULL;
53}
54
Willy Tarreaufdccded2008-08-29 18:19:04 +020055/* puts the task <t> in run queue with reason flags <f>, and returns <t> */
Willy Tarreau4df82062008-08-29 15:26:14 +020056struct task *__task_wakeup(struct task *t);
Willy Tarreaufdccded2008-08-29 18:19:04 +020057static inline struct task *task_wakeup(struct task *t, unsigned int f)
Willy Tarreau4df82062008-08-29 15:26:14 +020058{
Willy Tarreau4726f532009-03-07 17:25:21 +010059 if (likely(!task_in_rq(t)))
Willy Tarreaufdccded2008-08-29 18:19:04 +020060 __task_wakeup(t);
61 t->state |= f;
62 return t;
Willy Tarreau4df82062008-08-29 15:26:14 +020063}
Willy Tarreaubaaee002006-06-26 02:48:02 +020064
Willy Tarreau4726f532009-03-07 17:25:21 +010065/*
66 * Unlink the task from the wait queue, and possibly update the last_timer
67 * pointer. A pointer to the task itself is returned. The task *must* already
68 * be in the wait queue before calling this function. If unsure, use the safer
69 * task_unlink_wq() function.
Willy Tarreaubaaee002006-06-26 02:48:02 +020070 */
Willy Tarreau4726f532009-03-07 17:25:21 +010071static inline struct task *__task_unlink_wq(struct task *t)
72{
73 eb32_delete(&t->wq);
74 if (last_timer == t)
75 last_timer = NULL;
76 return t;
77}
78
79static inline struct task *task_unlink_wq(struct task *t)
Willy Tarreaubaaee002006-06-26 02:48:02 +020080{
Willy Tarreau4726f532009-03-07 17:25:21 +010081 if (likely(task_in_wq(t)))
82 __task_unlink_wq(t);
Willy Tarreau96bcfd72007-04-29 10:41:56 +020083 return t;
Willy Tarreaubaaee002006-06-26 02:48:02 +020084}
85
86/*
Willy Tarreau4726f532009-03-07 17:25:21 +010087 * Unlink the task from the run queue. The run_queue size and number of niced
88 * tasks are updated too. A pointer to the task itself is returned. The task
89 * *must* already be in the wait queue before calling this function. If unsure,
90 * use the safer task_unlink_rq() function.
Willy Tarreaubaaee002006-06-26 02:48:02 +020091 */
Willy Tarreau4726f532009-03-07 17:25:21 +010092static inline struct task *__task_unlink_rq(struct task *t)
Willy Tarreaubaaee002006-06-26 02:48:02 +020093{
Willy Tarreau4726f532009-03-07 17:25:21 +010094 eb32_delete(&t->rq);
95 run_queue--;
96 if (likely(t->nice))
97 niced_tasks--;
Willy Tarreauce44f122008-07-05 18:16:19 +020098 return t;
99}
Willy Tarreau9789f7b2008-06-24 08:17:16 +0200100
Willy Tarreau4726f532009-03-07 17:25:21 +0100101static inline struct task *task_unlink_rq(struct task *t)
102{
103 if (likely(task_in_rq(t)))
104 __task_unlink_rq(t);
105 return t;
106}
107
Willy Tarreauce44f122008-07-05 18:16:19 +0200108/*
109 * Unlinks the task and adjusts run queue stats.
110 * A pointer to the task itself is returned.
111 */
112static inline struct task *task_delete(struct task *t)
113{
Willy Tarreau4726f532009-03-07 17:25:21 +0100114 task_unlink_wq(t);
115 task_unlink_rq(t);
Willy Tarreau9789f7b2008-06-24 08:17:16 +0200116 return t;
117}
118
119/*
120 * Initialize a new task. The bare minimum is performed (queue pointers and state).
121 * The task is returned.
122 */
123static inline struct task *task_init(struct task *t)
124{
Willy Tarreau4726f532009-03-07 17:25:21 +0100125 t->wq.node.leaf_p = NULL;
126 t->rq.node.leaf_p = NULL;
Willy Tarreaufdccded2008-08-29 18:19:04 +0200127 t->state = TASK_SLEEPING;
Willy Tarreau91e99932008-06-30 07:51:00 +0200128 t->nice = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200129 return t;
130}
131
132/*
133 * frees a task. Its context must have been freed since it will be lost.
134 */
135static inline void task_free(struct task *t)
136{
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200137 pool_free2(pool2_task, t);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200138}
139
Willy Tarreau4726f532009-03-07 17:25:21 +0100140/* Place <task> into the wait queue, where it may already be. If the expiration
141 * timer is infinite, the task is dequeued.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200142 */
Willy Tarreau4726f532009-03-07 17:25:21 +0100143void task_queue(struct task *task);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200144
145/*
146 * This does 4 things :
147 * - wake up all expired tasks
148 * - call all runnable tasks
149 * - call maintain_proxies() to enable/disable the listeners
Willy Tarreaud825eef2007-05-12 22:35:00 +0200150 * - return the date of next event in <next> or eternity.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200151 */
152
Willy Tarreau0c303ee2008-07-07 00:09:58 +0200153void process_runnable_tasks(int *next);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200154
Willy Tarreau58b458d2008-06-29 22:40:23 +0200155/*
156 * Extract all expired timers from the timer queue, and wakes up all
157 * associated tasks. Returns the date of next event (or eternity).
158 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +0200159void wake_expired_tasks(int *next);
Willy Tarreau58b458d2008-06-29 22:40:23 +0200160
Willy Tarreaubaaee002006-06-26 02:48:02 +0200161
162#endif /* _PROTO_TASK_H */
163
164/*
165 * Local variables:
166 * c-indent-level: 8
167 * c-basic-offset: 8
168 * End:
169 */