]> git.ipfire.org Git - thirdparty/squid.git/blame - src/DiskIO/DiskThreads/DiskThreadsIOStrategy.cc
Adding a comment that tests/testUfs will fail when 'heap' is the only
[thirdparty/squid.git] / src / DiskIO / DiskThreads / DiskThreadsIOStrategy.cc
CommitLineData
b9ae18aa 1
2/*
b3fb9070 3 * $Id: DiskThreadsIOStrategy.cc,v 1.11 2007/04/12 23:51:57 wessels Exp $
b9ae18aa 4 *
5 * DEBUG: section 79 Squid-side Disk I/O functions.
6 * AUTHOR: Robert Collins
7 *
8 * SQUID Web Proxy Cache http://www.squid-cache.org/
9 * ----------------------------------------------------------
10 *
11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
33 *
34 * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
35 */
36
37#include "squid.h"
38
62ee09ca 39#include "CacheManager.h"
b9ae18aa 40#include "DiskThreadsIOStrategy.h"
41#include "DiskThreadsDiskFile.h"
42/* for statfs */
43#include "Store.h"
44#include "fde.h"
45
b9ae18aa 46void
47DiskThreadsIOStrategy::init(void)
48{
49 if (initialised)
50 return;
51
04eb0689 52 squidaio_ctrl_pool = memPoolCreate("aio_ctrl", sizeof(squidaio_ctrl_t));
b9ae18aa 53
b9ae18aa 54 initialised = true;
e65c313f 55
56 /*
57 * We'd like to call squidaio_init() here, but the configuration
58 * hasn't been parsed yet and we don't know how many cache_dirs
59 * there are, which means we don't know how many threads to start.
60 */
b9ae18aa 61}
62
62ee09ca 63void
64DiskThreadsIOStrategy::registerWithCacheManager(CacheManager & manager)
65{
66 manager.registerAction("squidaio_counts", "Async IO Function Counters",
67 aioStats, 0, 1);
68}
69
b9ae18aa 70void
71DiskThreadsIOStrategy::done(void)
72{
73 if (!initialised)
74 return;
75
d06925a4 76 squidaio_shutdown();
77
b9ae18aa 78 delete squidaio_ctrl_pool;
79
80 squidaio_ctrl_pool = NULL;
81
82 initialised = false;
83}
84
85int
86DiskThreadsIOStrategy::callback()
87{
88 squidaio_result_t *resultp;
89 squidaio_ctrl_t *ctrlp;
90 int retval = 0;
91
92 assert(initialised);
93 squidaio_counts.check_callback++;
94
95 for (;;) {
96 if ((resultp = squidaio_poll_done()) == NULL)
97 break;
98
99 ctrlp = (squidaio_ctrl_t *) resultp->data;
100
101 switch (resultp->result_type) {
102
103 case _AIO_OP_NONE:
104
b9ae18aa 105 case _AIO_OP_OPENDIR:
106 break;
107
108 case _AIO_OP_OPEN:
109 ++squidaio_counts.open_finish;
110 break;
111
112 case _AIO_OP_READ:
113 ++squidaio_counts.read_finish;
114 break;
115
116 case _AIO_OP_WRITE:
117 ++squidaio_counts.write_finish;
118 break;
119
120 case _AIO_OP_CLOSE:
121 ++squidaio_counts.close_finish;
122 break;
123
124 case _AIO_OP_UNLINK:
125 ++squidaio_counts.unlink_finish;
126 break;
127
128 case _AIO_OP_STAT:
129 ++squidaio_counts.stat_finish;
130 break;
131 }
132
133 if (ctrlp == NULL)
134 continue; /* XXX Should not happen */
135
136 dlinkDelete(&ctrlp->node, &used_list);
137
138 if (ctrlp->done_handler) {
139 AIOCB *callback = ctrlp->done_handler;
140 void *cbdata;
141 ctrlp->done_handler = NULL;
142
143 if (cbdataReferenceValidDone(ctrlp->done_handler_data, &cbdata)) {
144 retval = 1; /* Return that we've actually done some work */
145 callback(ctrlp->fd, cbdata, ctrlp->bufp,
146 ctrlp->result.aio_return, ctrlp->result.aio_errno);
147 } else {
148 if (ctrlp->operation == _AIO_OPEN) {
149 /* The open operation was aborted.. */
150 int fd = ctrlp->result.aio_return;
151
152 if (fd >= 0)
153 aioClose(fd);
154 }
155 }
156 }
157
158 /* free data if requested to aioWrite() */
159 if (ctrlp->free_func)
160 ctrlp->free_func(ctrlp->bufp);
161
162 /* free temporary read buffer */
163 if (ctrlp->operation == _AIO_READ)
164 squidaio_xfree(ctrlp->bufp, ctrlp->len);
165
b9ae18aa 166 squidaio_ctrl_pool->free(ctrlp);
167 }
168
169 return retval;
170}
171
172/* Flush all pending I/O */
173void
174DiskThreadsIOStrategy::sync()
175{
176 if (!initialised)
177 return; /* nothing to do then */
178
179 /* Flush all pending operations */
180 debug(32, 1) ("aioSync: flushing pending I/O operations\n");
181
182 do {
183 callback();
184 } while (squidaio_sync());
185
186 debug(32, 1) ("aioSync: done\n");
187}
188
189DiskThreadsIOStrategy::DiskThreadsIOStrategy() : initialised (false) {}
190
191void
192DiskThreadsIOStrategy::aioStats(StoreEntry * sentry)
193{
194 storeAppendPrintf(sentry, "ASYNC IO Counters:\n");
195 storeAppendPrintf(sentry, "Operation\t# Requests\tNumber serviced\n");
196 storeAppendPrintf(sentry, "open\t%d\t%d\n", squidaio_counts.open_start, squidaio_counts.open_finish);
197 storeAppendPrintf(sentry, "close\t%d\t%d\n", squidaio_counts.close_start, squidaio_counts.close_finish);
198 storeAppendPrintf(sentry, "cancel\t%d\t-\n", squidaio_counts.cancel);
199 storeAppendPrintf(sentry, "write\t%d\t%d\n", squidaio_counts.write_start, squidaio_counts.write_finish);
200 storeAppendPrintf(sentry, "read\t%d\t%d\n", squidaio_counts.read_start, squidaio_counts.read_finish);
201 storeAppendPrintf(sentry, "stat\t%d\t%d\n", squidaio_counts.stat_start, squidaio_counts.stat_finish);
202 storeAppendPrintf(sentry, "unlink\t%d\t%d\n", squidaio_counts.unlink_start, squidaio_counts.unlink_finish);
203 storeAppendPrintf(sentry, "check_callback\t%d\t-\n", squidaio_counts.check_callback);
204 storeAppendPrintf(sentry, "queue\t%d\t-\n", squidaio_get_queue_len());
b0465494 205 squidaio_stats(sentry);
b9ae18aa 206}
207
b9ae18aa 208DiskThreadsIOStrategy DiskThreadsIOStrategy::Instance;
209bool
210DiskThreadsIOStrategy::shedLoad()
211{
212 /*
213 * we should detect some 'too many files open' condition and return
214 * NULL here.
215 */
216#ifdef MAGIC2
217
218 if (aioQueueSize() > MAGIC2)
219 return true;
220
221#endif
222
223 return false;
224}
225
226int
227DiskThreadsIOStrategy::load()
228{
229 int loadav;
230 int ql;
231
232 ql = aioQueueSize();
233
234 if (ql == 0)
235 loadav = 0;
236
237 loadav = ql * 1000 / MAGIC1;
238
ac332e9e 239 debug(47, 9) ("DiskThreadsIOStrategy::load: load=%d\n", loadav);
b9ae18aa 240
241 return loadav;
242}
243
244DiskFile::Pointer
245DiskThreadsIOStrategy::newFile (char const *path)
246{
247 if (shedLoad()) {
248 return NULL;
249 }
250
251 return new DiskThreadsDiskFile (path, this);
252}
253
254void
255DiskThreadsIOStrategy::unlinkFile(char const *path)
256{
257 statCounter.syscalls.disk.unlinks++;
b9ae18aa 258 aioUnlink(path, NULL, NULL);
b9ae18aa 259}