xref: /unit/src/nxt_work_queue.h (revision 2084:7d479274f334)
1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) NGINX, Inc.
5  */
6 
7 #ifndef _NXT_WORK_QUEUE_H_INCLUDED_
8 #define _NXT_WORK_QUEUE_H_INCLUDED_
9 
10 
11 typedef struct nxt_work_s  nxt_work_t;
12 
13 struct nxt_task_s {
14     nxt_thread_t  *thread;
15     nxt_log_t     *log;
16     uint32_t      ident;
17     nxt_work_t    *next_work;
18 
19     /* TODO: exception_handler, prev/next task, subtasks. */
20 };
21 
22 
23 #define nxt_task_next_ident()                                                 \
24     ((uint32_t) nxt_atomic_fetch_add(&nxt_task_ident, 1) & 0x3FFFFFFF)
25 
26 
27 /*
28  * A work handler with just the obj and data arguments instead
29  * of pointer to a possibly large a work struct allows to call
30  * the handler not only via a work queue but also directly.
31  * The only obj argument is enough for the most cases except the
32  * source filters, so the data argument has been introduced and
33  * is used where appropriate.
34  */
35 //typedef void (*nxt_work_handler_t)(nxt_task_t *task, void *obj, void *data);
36 
37 
38 struct nxt_work_s {
39     nxt_work_t                  *next;
40     nxt_work_handler_t          handler;
41     nxt_task_t                  *task;
42     void                        *obj;
43     void                        *data;
44 };
45 
46 
47 typedef struct nxt_work_queue_chunk_s  nxt_work_queue_chunk_t;
48 
49 struct nxt_work_queue_chunk_s {
50     nxt_work_queue_chunk_t      *next;
51     nxt_work_t                  work;
52 };
53 
54 
55 typedef struct {
56     nxt_work_t                  *next;
57     nxt_work_t                  *spare;
58     nxt_work_queue_chunk_t      *chunk;
59     size_t                      chunk_size;
60 } nxt_work_queue_cache_t;
61 
62 
63 typedef struct nxt_work_queue_s  nxt_work_queue_t;
64 
65 struct nxt_work_queue_s {
66     nxt_work_t                  *head;
67     nxt_work_t                  *tail;
68     nxt_work_queue_cache_t      *cache;
69 #if (NXT_DEBUG)
70     const char                  *name;
71     int32_t                     pid;
72     nxt_tid_t                   tid;
73 #endif
74 };
75 
76 
77 typedef struct {
78     nxt_thread_spinlock_t       lock;
79     nxt_work_t                  *head;
80     nxt_work_t                  *tail;
81     nxt_work_queue_cache_t      cache;
82 } nxt_locked_work_queue_t;
83 
84 
85 NXT_EXPORT void nxt_work_queue_cache_create(nxt_work_queue_cache_t *cache,
86     size_t chunk_size);
87 NXT_EXPORT void nxt_work_queue_cache_destroy(nxt_work_queue_cache_t *cache);
88 
89 NXT_EXPORT void nxt_work_queue_add(nxt_work_queue_t *wq,
90     nxt_work_handler_t handler, nxt_task_t *task, void *obj, void *data);
91 NXT_EXPORT nxt_work_handler_t nxt_work_queue_pop(nxt_work_queue_t *wq,
92     nxt_task_t **task, void **obj, void **data);
93 
94 
95 #define nxt_work_set(_work, _handler, _task, _obj, _data)                     \
96     do {                                                                      \
97         nxt_work_t  *work = _work;                                            \
98                                                                               \
99         work->handler = _handler;                                             \
100         work->task = _task;                                                   \
101         work->obj = _obj;                                                     \
102         work->data = _data;                                                   \
103     } while (0)
104 
105 #if (NXT_DEBUG)
106 
107 NXT_EXPORT void nxt_work_queue_name(nxt_work_queue_t *wq, const char *name);
108 NXT_EXPORT void nxt_work_queue_thread_adopt(nxt_work_queue_t *wq);
109 
110 #else
111 
112 #define nxt_work_queue_name(_wq, _name)
113 
114 #define nxt_work_queue_thread_adopt(_wq)
115 
116 #endif
117 
118 
119 NXT_EXPORT void nxt_locked_work_queue_add(nxt_locked_work_queue_t *lwq,
120     nxt_work_t *work);
121 NXT_EXPORT nxt_work_handler_t nxt_locked_work_queue_pop(
122     nxt_locked_work_queue_t *lwq, nxt_task_t **task, void **obj, void **data);
123 NXT_EXPORT void nxt_locked_work_queue_move(nxt_thread_t *thr,
124     nxt_locked_work_queue_t *lwq, nxt_work_queue_t *wq);
125 
126 
127 #endif /* _NXT_WORK_QUEUE_H_INCLUDED_ */
128