]> git.ipfire.org Git - thirdparty/squid.git/blame - src/DiskIO/DiskThreads/DiskThreadsIOStrategy.cc
Renamed squid.h to squid-old.h and config.h to squid.h
[thirdparty/squid.git] / src / DiskIO / DiskThreads / DiskThreadsIOStrategy.cc
CommitLineData
b9ae18aa 1
2/*
262a0e14 3 * $Id$
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.
26ac0430 24 *
b9ae18aa 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.
26ac0430 29 *
b9ae18aa 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
f7f3304a 37#include "squid-old.h"
b9ae18aa 38
b9ae18aa 39#include "DiskThreadsDiskFile.h"
8822ebee
AR
40#include "DiskThreadsIOStrategy.h"
41#include "fde.h"
42#include "mgr/Registration.h"
e4f1fdae 43#include "StatCounters.h"
b9ae18aa 44/* for statfs */
45#include "Store.h"
8822ebee 46
b9ae18aa 47
b9ae18aa 48void
49DiskThreadsIOStrategy::init(void)
50{
51 if (initialised)
52 return;
53
04eb0689 54 squidaio_ctrl_pool = memPoolCreate("aio_ctrl", sizeof(squidaio_ctrl_t));
b9ae18aa 55
b9ae18aa 56 initialised = true;
e65c313f 57
58 /*
59 * We'd like to call squidaio_init() here, but the configuration
60 * hasn't been parsed yet and we don't know how many cache_dirs
61 * there are, which means we don't know how many threads to start.
62 */
6fdc2d18 63
26ac0430 64 registerWithCacheManager();
b9ae18aa 65}
66
62ee09ca 67void
15fab853 68DiskThreadsIOStrategy::registerWithCacheManager(void)
62ee09ca 69{
8822ebee 70 Mgr::RegisterAction("squidaio_counts", "Async IO Function Counters",
d9fc6862 71 aioStats, 0, 1);
62ee09ca 72}
73
b9ae18aa 74void
75DiskThreadsIOStrategy::done(void)
76{
77 if (!initialised)
78 return;
79
d06925a4 80 squidaio_shutdown();
81
b9ae18aa 82 delete squidaio_ctrl_pool;
83
84 squidaio_ctrl_pool = NULL;
85
86 initialised = false;
87}
88
89int
90DiskThreadsIOStrategy::callback()
91{
92 squidaio_result_t *resultp;
93 squidaio_ctrl_t *ctrlp;
94 int retval = 0;
95
96 assert(initialised);
97 squidaio_counts.check_callback++;
98
99 for (;;) {
100 if ((resultp = squidaio_poll_done()) == NULL)
101 break;
102
103 ctrlp = (squidaio_ctrl_t *) resultp->data;
104
105 switch (resultp->result_type) {
106
107 case _AIO_OP_NONE:
108
b9ae18aa 109 case _AIO_OP_OPENDIR:
110 break;
111
112 case _AIO_OP_OPEN:
113 ++squidaio_counts.open_finish;
114 break;
115
116 case _AIO_OP_READ:
117 ++squidaio_counts.read_finish;
118 break;
119
120 case _AIO_OP_WRITE:
121 ++squidaio_counts.write_finish;
122 break;
123
124 case _AIO_OP_CLOSE:
125 ++squidaio_counts.close_finish;
126 break;
127
128 case _AIO_OP_UNLINK:
129 ++squidaio_counts.unlink_finish;
130 break;
131
132 case _AIO_OP_STAT:
133 ++squidaio_counts.stat_finish;
134 break;
135 }
136
137 if (ctrlp == NULL)
138 continue; /* XXX Should not happen */
139
140 dlinkDelete(&ctrlp->node, &used_list);
141
142 if (ctrlp->done_handler) {
350e2aec 143 AIOCB *done_callback = ctrlp->done_handler;
b9ae18aa 144 void *cbdata;
145 ctrlp->done_handler = NULL;
146
147 if (cbdataReferenceValidDone(ctrlp->done_handler_data, &cbdata)) {
148 retval = 1; /* Return that we've actually done some work */
350e2aec 149 done_callback(ctrlp->fd, cbdata, ctrlp->bufp,
0cc4a8bc 150 ctrlp->result.aio_return, ctrlp->result.aio_errno);
b9ae18aa 151 } else {
152 if (ctrlp->operation == _AIO_OPEN) {
153 /* The open operation was aborted.. */
154 int fd = ctrlp->result.aio_return;
155
156 if (fd >= 0)
157 aioClose(fd);
158 }
159 }
160 }
161
162 /* free data if requested to aioWrite() */
163 if (ctrlp->free_func)
164 ctrlp->free_func(ctrlp->bufp);
165
166 /* free temporary read buffer */
167 if (ctrlp->operation == _AIO_READ)
168 squidaio_xfree(ctrlp->bufp, ctrlp->len);
169
dc47f531 170 squidaio_ctrl_pool->freeOne(ctrlp);
b9ae18aa 171 }
172
173 return retval;
174}
175
176/* Flush all pending I/O */
177void
178DiskThreadsIOStrategy::sync()
179{
180 if (!initialised)
181 return; /* nothing to do then */
182
183 /* Flush all pending operations */
709873c3 184 debugs(32, 2, "aioSync: flushing pending I/O operations");
b9ae18aa 185
186 do {
187 callback();
188 } while (squidaio_sync());
189
709873c3 190 debugs(32, 2, "aioSync: done");
b9ae18aa 191}
192
193DiskThreadsIOStrategy::DiskThreadsIOStrategy() : initialised (false) {}
194
195void
196DiskThreadsIOStrategy::aioStats(StoreEntry * sentry)
197{
198 storeAppendPrintf(sentry, "ASYNC IO Counters:\n");
199 storeAppendPrintf(sentry, "Operation\t# Requests\tNumber serviced\n");
200 storeAppendPrintf(sentry, "open\t%d\t%d\n", squidaio_counts.open_start, squidaio_counts.open_finish);
201 storeAppendPrintf(sentry, "close\t%d\t%d\n", squidaio_counts.close_start, squidaio_counts.close_finish);
202 storeAppendPrintf(sentry, "cancel\t%d\t-\n", squidaio_counts.cancel);
203 storeAppendPrintf(sentry, "write\t%d\t%d\n", squidaio_counts.write_start, squidaio_counts.write_finish);
204 storeAppendPrintf(sentry, "read\t%d\t%d\n", squidaio_counts.read_start, squidaio_counts.read_finish);
205 storeAppendPrintf(sentry, "stat\t%d\t%d\n", squidaio_counts.stat_start, squidaio_counts.stat_finish);
206 storeAppendPrintf(sentry, "unlink\t%d\t%d\n", squidaio_counts.unlink_start, squidaio_counts.unlink_finish);
207 storeAppendPrintf(sentry, "check_callback\t%d\t-\n", squidaio_counts.check_callback);
208 storeAppendPrintf(sentry, "queue\t%d\t-\n", squidaio_get_queue_len());
b0465494 209 squidaio_stats(sentry);
b9ae18aa 210}
211
b9ae18aa 212DiskThreadsIOStrategy DiskThreadsIOStrategy::Instance;
213bool
214DiskThreadsIOStrategy::shedLoad()
215{
216 /*
217 * we should detect some 'too many files open' condition and return
218 * NULL here.
219 */
220#ifdef MAGIC2
221
222 if (aioQueueSize() > MAGIC2)
223 return true;
224
225#endif
226
227 return false;
228}
229
230int
231DiskThreadsIOStrategy::load()
232{
233 int loadav;
234 int ql;
235
236 ql = aioQueueSize();
237
238 if (ql == 0)
239 loadav = 0;
240
241 loadav = ql * 1000 / MAGIC1;
242
bf8fe701 243 debugs(47, 9, "DiskThreadsIOStrategy::load: load=" << loadav);
b9ae18aa 244
245 return loadav;
246}
247
248DiskFile::Pointer
249DiskThreadsIOStrategy::newFile (char const *path)
250{
251 if (shedLoad()) {
252 return NULL;
253 }
254
255 return new DiskThreadsDiskFile (path, this);
256}
257
c521ad17
DK
258bool
259DiskThreadsIOStrategy::unlinkdUseful() const
260{
261 return false;
262}
263
b9ae18aa 264void
265DiskThreadsIOStrategy::unlinkFile(char const *path)
266{
e4f1fdae 267 ++statCounter.syscalls.disk.unlinks;
b9ae18aa 268 aioUnlink(path, NULL, NULL);
b9ae18aa 269}