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