/
kcont.h
167 lines (144 loc) · 6.39 KB
/
kcont.h
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/* $NetBSD: kcont.h,v 1.4 2005/12/11 12:25:20 christos Exp $ */
/*
* Copyright (c) 2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jonathan Stone, currently employed by Decru, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright 2003 Jonathan Stone.
* All rights reserved.
*/
#ifndef _SYS_KCONT_H_
#define _SYS_KCONT_H_
#include <sys/queue.h>
/*
* kcont -- Continuation-passing for BSD kernels.
*
* This module defines structures that implement a
* continuation-passing model in C which can be used as a
* ``callback''-like alternative to using a process context to
* tsleep() on an object address, waiting for some event or status
* change on that object. Since ANSI C provides neither
* lexically-nested functions nor heap allocation of activation
* records, we implement a continuation as a struct containing:
* 1. A function pointer, pointing to the continuation.
* 2. A object pointer: the object being "slept" upon.
* 3. An argument pointer: a pointer to private storage containing
* other arguments to the continuation function, including any
* additional state beyond the "slept-upon" object.
*/
typedef struct kc {
SIMPLEQ_ENTRY(kc) kc_next; /* next kc in object's callback list */
void (*kc_fn) (void * /*obj*/, void * /*env_arg*/, int /*status*/);
void *kc_env_arg; /* caller-supplied continuation argument */
void *kc_obj; /* saved object, used for deferred calls */
int kc_status; /* saved status, used for deferred calls */
ushort kc_ipl; /* IPL at which to call kc_func */
ushort kc_flags; /* Flags, private to kcont implementation */
} kc_t;
/* kc_flags values. */
#define KC_AUTOFREE 0x01 /* This struct kc * was malloc'ed by
* the kcont module; free it immediately
* after calling the continuation function.
*/
#define KC_DEFERRED 0x02 /* Deferral has already saved object, status */
/* kcont IPL values. */
#define KC_IPL_DEFER_PROCESS 0x00 /* Hand off continuation fn to a
* full process context (kthread).
*/
#define KC_IPL_DEFER_SOFTCLOCK 0x01
#define KC_IPL_DEFER_SOFTNET 0x02 /* Run continuation in an
* IPL_SOFTNET software callout. */
#define KC_IPL_DEFER_SOFTSERIAL 0x03
#define KC_IPL_IMMED 0x10 /*
* Execute continuation fn immediately,
* in the context of the object event,
* with no completion. Continuation
* assumed to be very quick.
*/
/*
* Head of a list of pending continuations.
* For example, for continuation-based buffer I/O,
* add a kcq_t to struct buf, and pass a struct kc *
* down through VFS and strategy layers.
*/
typedef SIMPLEQ_HEAD(kcqueue, kc) kcq_t;
/*
* Prepare a struct kc continuation using caller-supplied memory
*/
struct kc *kcont(struct kc *,
void (* /*fn*/)(void * /*obj*/, void */*arg*/, int /*sts*/),
void * /*env_arg*/, int /*continue_ipl*/);
/*
* Prepare a struct kc continuation using malloc'ed memory.
* The malloc'ed memory will be automatically freed after the continuation
* is finally called.
*/
struct kc *kcont_malloc(int /*allocmflags*/,
void (* /*fn*/)(void * /*obj*/, void */*arg*/, int /*sts*/),
void * /*env_arg*/, int /*continue_ipl*/);
/*
* Use a caller-supplied, already-constructed kcont to defer execution
* from the current context to some lower interrupt priority.
* Caller must supply the preallocated kcont (possibly via kcont_malloc()).
*/
void kcont_defer(struct kc * /*kc*/, void * /*obj*/,
int /*status*/);
/*
* Use a kcont to defer execution from the current context to some
* lower interrupt priority. Space is malloc'ed and freed as for
* kcont_malloc(). Deprecated; use kcont_defer() and kcont_malloc().
*/
void kcont_defer_malloc(int, /* mallocflags */
void (* /*fn*/)(void * /*obj*/, void */*arg*/, int /*sts*/),
void * /*obj*/,
void * /*env_arg*/, int /*status*/, int /*continue_ipl*/);
/*
* Enqueue a struct kc * into the kc_queue* field of some kernel struct.
* The struct kc * argument is typically passed as an argument to
* a function which requests an asynchronous operation on that kernel object.
* When the operation completes, or the object otherwise decides to
* invoke a wakeup() on itself, all continuations on the object's
* kcqueue will be called, either immediately or if a continuation
* requested it) after deferring to a kc_queue * served at
* software-interrupt priority.
*/
void kcont_enqueue(kcq_t * /*kcqueue*/, struct kc * /*kc*/);
/*
* Execute (or defer) all continuations on an object's kcqueue
* when an asynchronous operation completes. Runs through the
* struct kc_queue * of struct kcs, either running the continuations
* with the given object and status; or saving the object and status
* and deferring the kconts to a software-interrupt priority kc_queue.
*/
void kcont_run(kcq_t * /*kcq*/, void * /*obj*/,
int /*status*/, int /*cur_ipl*/);
/* Initialize kcont framework at boot time. */
void kcont_init(void);
#endif /* !_SYS_KCONT_H_ */