1 | =head1 NAME |
1 | =head1 NAME |
2 | |
2 | |
3 | BDB::AIO - Asynchronous Berkeley DB access |
3 | BDB - Asynchronous Berkeley DB access |
4 | |
4 | |
5 | =head1 SYNOPSIS |
5 | =head1 SYNOPSIS |
6 | |
6 | |
7 | use BDB::AIO; |
7 | use BDB; |
8 | |
8 | |
9 | =head1 DESCRIPTION |
9 | =head1 DESCRIPTION |
10 | |
10 | |
11 | =head2 EXAMPLE |
11 | =head2 EXAMPLE |
12 | |
12 | |
… | |
… | |
55 | |
55 | |
56 | =back |
56 | =back |
57 | |
57 | |
58 | =cut |
58 | =cut |
59 | |
59 | |
60 | package BDB::AIO; |
60 | package BDB; |
61 | |
61 | |
62 | no warnings; |
62 | no warnings; |
63 | use strict 'vars'; |
63 | use strict 'vars'; |
64 | |
64 | |
65 | use base 'Exporter'; |
65 | use base 'Exporter'; |
… | |
… | |
72 | min_parallel max_parallel max_idle |
72 | min_parallel max_parallel max_idle |
73 | nreqs nready npending nthreads |
73 | nreqs nready npending nthreads |
74 | max_poll_time max_poll_reqs); |
74 | max_poll_time max_poll_reqs); |
75 | |
75 | |
76 | require XSLoader; |
76 | require XSLoader; |
77 | XSLoader::load ("BDB::AIO", $VERSION); |
77 | XSLoader::load ("BDB", $VERSION); |
78 | } |
78 | } |
79 | |
79 | |
80 | =head2 SUPPORT FUNCTIONS |
80 | =head2 SUPPORT FUNCTIONS |
81 | |
81 | |
82 | =head3 EVENT PROCESSING AND EVENT LOOP INTEGRATION |
82 | =head3 EVENT PROCESSING AND EVENT LOOP INTEGRATION |
83 | |
83 | |
84 | =over 4 |
84 | =over 4 |
85 | |
85 | |
86 | =item $fileno = BDB::AIO::poll_fileno |
86 | =item $fileno = BDB::poll_fileno |
87 | |
87 | |
88 | Return the I<request result pipe file descriptor>. This filehandle must be |
88 | Return the I<request result pipe file descriptor>. This filehandle must be |
89 | polled for reading by some mechanism outside this module (e.g. Event or |
89 | polled for reading by some mechanism outside this module (e.g. Event or |
90 | select, see below or the SYNOPSIS). If the pipe becomes readable you have |
90 | select, see below or the SYNOPSIS). If the pipe becomes readable you have |
91 | to call C<poll_cb> to check the results. |
91 | to call C<poll_cb> to check the results. |
92 | |
92 | |
93 | See C<poll_cb> for an example. |
93 | See C<poll_cb> for an example. |
94 | |
94 | |
95 | =item BDB::AIO::poll_cb |
95 | =item BDB::poll_cb |
96 | |
96 | |
97 | Process some outstanding events on the result pipe. You have to call this |
97 | Process some outstanding events on the result pipe. You have to call this |
98 | regularly. Returns the number of events processed. Returns immediately |
98 | regularly. Returns the number of events processed. Returns immediately |
99 | when no events are outstanding. The amount of events processed depends on |
99 | when no events are outstanding. The amount of events processed depends on |
100 | the settings of C<BDB::AIO::max_poll_req> and C<BDB::AIO::max_poll_time>. |
100 | the settings of C<BDB::max_poll_req> and C<BDB::max_poll_time>. |
101 | |
101 | |
102 | If not all requests were processed for whatever reason, the filehandle |
102 | If not all requests were processed for whatever reason, the filehandle |
103 | will still be ready when C<poll_cb> returns. |
103 | will still be ready when C<poll_cb> returns. |
104 | |
104 | |
105 | Example: Install an Event watcher that automatically calls |
105 | Example: Install an Event watcher that automatically calls |
106 | BDB::AIO::poll_cb with high priority: |
106 | BDB::poll_cb with high priority: |
107 | |
107 | |
108 | Event->io (fd => BDB::AIO::poll_fileno, |
108 | Event->io (fd => BDB::poll_fileno, |
109 | poll => 'r', async => 1, |
109 | poll => 'r', async => 1, |
110 | cb => \&BDB::AIO::poll_cb); |
110 | cb => \&BDB::poll_cb); |
111 | |
111 | |
112 | =item BDB::AIO::max_poll_reqs $nreqs |
112 | =item BDB::max_poll_reqs $nreqs |
113 | |
113 | |
114 | =item BDB::AIO::max_poll_time $seconds |
114 | =item BDB::max_poll_time $seconds |
115 | |
115 | |
116 | These set the maximum number of requests (default C<0>, meaning infinity) |
116 | These set the maximum number of requests (default C<0>, meaning infinity) |
117 | that are being processed by C<BDB::AIO::poll_cb> in one call, respectively |
117 | that are being processed by C<BDB::poll_cb> in one call, respectively |
118 | the maximum amount of time (default C<0>, meaning infinity) spent in |
118 | the maximum amount of time (default C<0>, meaning infinity) spent in |
119 | C<BDB::AIO::poll_cb> to process requests (more correctly the mininum amount |
119 | C<BDB::poll_cb> to process requests (more correctly the mininum amount |
120 | of time C<poll_cb> is allowed to use). |
120 | of time C<poll_cb> is allowed to use). |
121 | |
121 | |
122 | Setting C<max_poll_time> to a non-zero value creates an overhead of one |
122 | Setting C<max_poll_time> to a non-zero value creates an overhead of one |
123 | syscall per request processed, which is not normally a problem unless your |
123 | syscall per request processed, which is not normally a problem unless your |
124 | callbacks are really really fast or your OS is really really slow (I am |
124 | callbacks are really really fast or your OS is really really slow (I am |
… | |
… | |
129 | time. |
129 | time. |
130 | |
130 | |
131 | For interactive programs, values such as C<0.01> to C<0.1> should be fine. |
131 | For interactive programs, values such as C<0.01> to C<0.1> should be fine. |
132 | |
132 | |
133 | Example: Install an Event watcher that automatically calls |
133 | Example: Install an Event watcher that automatically calls |
134 | BDB::AIO::poll_cb with low priority, to ensure that other parts of the |
134 | BDB::poll_cb with low priority, to ensure that other parts of the |
135 | program get the CPU sometimes even under high AIO load. |
135 | program get the CPU sometimes even under high AIO load. |
136 | |
136 | |
137 | # try not to spend much more than 0.1s in poll_cb |
137 | # try not to spend much more than 0.1s in poll_cb |
138 | BDB::AIO::max_poll_time 0.1; |
138 | BDB::max_poll_time 0.1; |
139 | |
139 | |
140 | # use a low priority so other tasks have priority |
140 | # use a low priority so other tasks have priority |
141 | Event->io (fd => BDB::AIO::poll_fileno, |
141 | Event->io (fd => BDB::poll_fileno, |
142 | poll => 'r', nice => 1, |
142 | poll => 'r', nice => 1, |
143 | cb => &BDB::AIO::poll_cb); |
143 | cb => &BDB::poll_cb); |
144 | |
144 | |
145 | =item BDB::AIO::poll_wait |
145 | =item BDB::poll_wait |
146 | |
146 | |
147 | If there are any outstanding requests and none of them in the result |
147 | If there are any outstanding requests and none of them in the result |
148 | phase, wait till the result filehandle becomes ready for reading (simply |
148 | phase, wait till the result filehandle becomes ready for reading (simply |
149 | does a C<select> on the filehandle. This is useful if you want to |
149 | does a C<select> on the filehandle. This is useful if you want to |
150 | synchronously wait for some requests to finish). |
150 | synchronously wait for some requests to finish). |
151 | |
151 | |
152 | See C<nreqs> for an example. |
152 | See C<nreqs> for an example. |
153 | |
153 | |
154 | =item BDB::AIO::poll |
154 | =item BDB::poll |
155 | |
155 | |
156 | Waits until some requests have been handled. |
156 | Waits until some requests have been handled. |
157 | |
157 | |
158 | Returns the number of requests processed, but is otherwise strictly |
158 | Returns the number of requests processed, but is otherwise strictly |
159 | equivalent to: |
159 | equivalent to: |
160 | |
160 | |
161 | BDB::AIO::poll_wait, BDB::AIO::poll_cb |
161 | BDB::poll_wait, BDB::poll_cb |
162 | |
162 | |
163 | =item BDB::AIO::flush |
163 | =item BDB::flush |
164 | |
164 | |
165 | Wait till all outstanding AIO requests have been handled. |
165 | Wait till all outstanding AIO requests have been handled. |
166 | |
166 | |
167 | Strictly equivalent to: |
167 | Strictly equivalent to: |
168 | |
168 | |
169 | BDB::AIO::poll_wait, BDB::AIO::poll_cb |
169 | BDB::poll_wait, BDB::poll_cb |
170 | while BDB::AIO::nreqs; |
170 | while BDB::nreqs; |
171 | |
171 | |
172 | =head3 CONTROLLING THE NUMBER OF THREADS |
172 | =head3 CONTROLLING THE NUMBER OF THREADS |
173 | |
173 | |
174 | =item BDB::AIO::min_parallel $nthreads |
174 | =item BDB::min_parallel $nthreads |
175 | |
175 | |
176 | Set the minimum number of AIO threads to C<$nthreads>. The current |
176 | Set the minimum number of AIO threads to C<$nthreads>. The current |
177 | default is C<8>, which means eight asynchronous operations can execute |
177 | default is C<8>, which means eight asynchronous operations can execute |
178 | concurrently at any one time (the number of outstanding requests, |
178 | concurrently at any one time (the number of outstanding requests, |
179 | however, is unlimited). |
179 | however, is unlimited). |
180 | |
180 | |
181 | BDB::AIO starts threads only on demand, when an AIO request is queued and |
181 | BDB starts threads only on demand, when an AIO request is queued and |
182 | no free thread exists. Please note that queueing up a hundred requests can |
182 | no free thread exists. Please note that queueing up a hundred requests can |
183 | create demand for a hundred threads, even if it turns out that everything |
183 | create demand for a hundred threads, even if it turns out that everything |
184 | is in the cache and could have been processed faster by a single thread. |
184 | is in the cache and could have been processed faster by a single thread. |
185 | |
185 | |
186 | It is recommended to keep the number of threads relatively low, as some |
186 | It is recommended to keep the number of threads relatively low, as some |
… | |
… | |
189 | versions, 4-32 threads should be fine. |
189 | versions, 4-32 threads should be fine. |
190 | |
190 | |
191 | Under most circumstances you don't need to call this function, as the |
191 | Under most circumstances you don't need to call this function, as the |
192 | module selects a default that is suitable for low to moderate load. |
192 | module selects a default that is suitable for low to moderate load. |
193 | |
193 | |
194 | =item BDB::AIO::max_parallel $nthreads |
194 | =item BDB::max_parallel $nthreads |
195 | |
195 | |
196 | Sets the maximum number of AIO threads to C<$nthreads>. If more than the |
196 | Sets the maximum number of AIO threads to C<$nthreads>. If more than the |
197 | specified number of threads are currently running, this function kills |
197 | specified number of threads are currently running, this function kills |
198 | them. This function blocks until the limit is reached. |
198 | them. This function blocks until the limit is reached. |
199 | |
199 | |
… | |
… | |
203 | This module automatically runs C<max_parallel 0> at program end, to ensure |
203 | This module automatically runs C<max_parallel 0> at program end, to ensure |
204 | that all threads are killed and that there are no outstanding requests. |
204 | that all threads are killed and that there are no outstanding requests. |
205 | |
205 | |
206 | Under normal circumstances you don't need to call this function. |
206 | Under normal circumstances you don't need to call this function. |
207 | |
207 | |
208 | =item BDB::AIO::max_idle $nthreads |
208 | =item BDB::max_idle $nthreads |
209 | |
209 | |
210 | Limit the number of threads (default: 4) that are allowed to idle (i.e., |
210 | Limit the number of threads (default: 4) that are allowed to idle (i.e., |
211 | threads that did not get a request to process within 10 seconds). That |
211 | threads that did not get a request to process within 10 seconds). That |
212 | means if a thread becomes idle while C<$nthreads> other threads are also |
212 | means if a thread becomes idle while C<$nthreads> other threads are also |
213 | idle, it will free its resources and exit. |
213 | idle, it will free its resources and exit. |
… | |
… | |
218 | |
218 | |
219 | The default is probably ok in most situations, especially if thread |
219 | The default is probably ok in most situations, especially if thread |
220 | creation is fast. If thread creation is very slow on your system you might |
220 | creation is fast. If thread creation is very slow on your system you might |
221 | want to use larger values. |
221 | want to use larger values. |
222 | |
222 | |
223 | =item $oldmaxreqs = BDB::AIO::max_outstanding $maxreqs |
223 | =item $oldmaxreqs = BDB::max_outstanding $maxreqs |
224 | |
224 | |
225 | This is a very bad function to use in interactive programs because it |
225 | This is a very bad function to use in interactive programs because it |
226 | blocks, and a bad way to reduce concurrency because it is inexact: Better |
226 | blocks, and a bad way to reduce concurrency because it is inexact: Better |
227 | use an C<aio_group> together with a feed callback. |
227 | use an C<aio_group> together with a feed callback. |
228 | |
228 | |
… | |
… | |
238 | C<max_oustsanding> is mainly useful in simple scripts (with low values) or |
238 | C<max_oustsanding> is mainly useful in simple scripts (with low values) or |
239 | as a stop gap to shield against fatal memory overflow (with large values). |
239 | as a stop gap to shield against fatal memory overflow (with large values). |
240 | |
240 | |
241 | =head3 STATISTICAL INFORMATION |
241 | =head3 STATISTICAL INFORMATION |
242 | |
242 | |
243 | =item BDB::AIO::nreqs |
243 | =item BDB::nreqs |
244 | |
244 | |
245 | Returns the number of requests currently in the ready, execute or pending |
245 | Returns the number of requests currently in the ready, execute or pending |
246 | states (i.e. for which their callback has not been invoked yet). |
246 | states (i.e. for which their callback has not been invoked yet). |
247 | |
247 | |
248 | Example: wait till there are no outstanding requests anymore: |
248 | Example: wait till there are no outstanding requests anymore: |
249 | |
249 | |
250 | BDB::AIO::poll_wait, BDB::AIO::poll_cb |
250 | BDB::poll_wait, BDB::poll_cb |
251 | while BDB::AIO::nreqs; |
251 | while BDB::nreqs; |
252 | |
252 | |
253 | =item BDB::AIO::nready |
253 | =item BDB::nready |
254 | |
254 | |
255 | Returns the number of requests currently in the ready state (not yet |
255 | Returns the number of requests currently in the ready state (not yet |
256 | executed). |
256 | executed). |
257 | |
257 | |
258 | =item BDB::AIO::npending |
258 | =item BDB::npending |
259 | |
259 | |
260 | Returns the number of requests currently in the pending state (executed, |
260 | Returns the number of requests currently in the pending state (executed, |
261 | but not yet processed by poll_cb). |
261 | but not yet processed by poll_cb). |
262 | |
262 | |
263 | =back |
263 | =back |
264 | |
264 | |
265 | =cut |
265 | =cut |
266 | |
|
|
267 | # support function to convert a fd into a perl filehandle |
|
|
268 | sub _fd2fh { |
|
|
269 | return undef if $_[0] < 0; |
|
|
270 | |
|
|
271 | # try to generate nice filehandles |
|
|
272 | my $sym = "BDB::AIO::fd#$_[0]"; |
|
|
273 | local *$sym; |
|
|
274 | |
|
|
275 | open *$sym, "+<&=$_[0]" # usually works under any unix |
|
|
276 | or open *$sym, "<&=$_[0]" # cygwin needs this |
|
|
277 | or open *$sym, ">&=$_[0]" # or this |
|
|
278 | or return undef; |
|
|
279 | |
|
|
280 | *$sym |
|
|
281 | } |
|
|
282 | |
266 | |
283 | min_parallel 8; |
267 | min_parallel 8; |
284 | |
268 | |
285 | END { flush } |
269 | END { flush } |
286 | |
270 | |