]> git.ipfire.org Git - thirdparty/squid.git/blame - src/DiskIO/DiskThreads/DiskThreadsIOStrategy.cc
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / DiskIO / DiskThreads / DiskThreadsIOStrategy.cc
CommitLineData
b9ae18aa 1/*
77b1029d 2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
26ac0430 3 *
bbc27441
AJ
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
b9ae18aa 7 */
8
bbc27441
AJ
9/* DEBUG: section 79 Squid-side Disk I/O functions. */
10
582c2af2 11#include "squid.h"
b9ae18aa 12#include "DiskThreadsDiskFile.h"
8822ebee
AR
13#include "DiskThreadsIOStrategy.h"
14#include "fde.h"
15#include "mgr/Registration.h"
4d5904f7 16#include "SquidConfig.h"
e4f1fdae 17#include "StatCounters.h"
b9ae18aa 18#include "Store.h"
8822ebee 19
ed6e9fb9
AJ
20/* squidaio_ctrl_t uses explicit alloc()/freeOne().
21 * XXX: convert to MEMPROXY_CLASS() API
22 */
23#include "mem/Pool.h"
24
b9ae18aa 25void
26DiskThreadsIOStrategy::init(void)
27{
28 if (initialised)
29 return;
30
b9ae18aa 31 initialised = true;
e65c313f 32
33 /*
34 * We'd like to call squidaio_init() here, but the configuration
35 * hasn't been parsed yet and we don't know how many cache_dirs
36 * there are, which means we don't know how many threads to start.
37 */
6fdc2d18 38
26ac0430 39 registerWithCacheManager();
b9ae18aa 40}
41
62ee09ca 42void
15fab853 43DiskThreadsIOStrategy::registerWithCacheManager(void)
62ee09ca 44{
8822ebee 45 Mgr::RegisterAction("squidaio_counts", "Async IO Function Counters",
d9fc6862 46 aioStats, 0, 1);
62ee09ca 47}
48
b9ae18aa 49void
50DiskThreadsIOStrategy::done(void)
51{
52 if (!initialised)
53 return;
54
d06925a4 55 squidaio_shutdown();
56
b9ae18aa 57 initialised = false;
58}
59
60int
61DiskThreadsIOStrategy::callback()
62{
63 squidaio_result_t *resultp;
64 squidaio_ctrl_t *ctrlp;
65 int retval = 0;
66
67 assert(initialised);
cb4185f1 68 ++squidaio_counts.check_callback;
b9ae18aa 69
70 for (;;) {
71 if ((resultp = squidaio_poll_done()) == NULL)
72 break;
73
74 ctrlp = (squidaio_ctrl_t *) resultp->data;
75
76 switch (resultp->result_type) {
77
78 case _AIO_OP_NONE:
79
b9ae18aa 80 case _AIO_OP_OPENDIR:
81 break;
82
83 case _AIO_OP_OPEN:
84 ++squidaio_counts.open_finish;
85 break;
86
87 case _AIO_OP_READ:
88 ++squidaio_counts.read_finish;
89 break;
90
91 case _AIO_OP_WRITE:
92 ++squidaio_counts.write_finish;
93 break;
94
95 case _AIO_OP_CLOSE:
96 ++squidaio_counts.close_finish;
97 break;
98
99 case _AIO_OP_UNLINK:
100 ++squidaio_counts.unlink_finish;
101 break;
102
103 case _AIO_OP_STAT:
104 ++squidaio_counts.stat_finish;
105 break;
106 }
107
108 if (ctrlp == NULL)
f53969cc 109 continue; /* XXX Should not happen */
b9ae18aa 110
111 dlinkDelete(&ctrlp->node, &used_list);
112
113 if (ctrlp->done_handler) {
350e2aec 114 AIOCB *done_callback = ctrlp->done_handler;
b9ae18aa 115 void *cbdata;
116 ctrlp->done_handler = NULL;
117
118 if (cbdataReferenceValidDone(ctrlp->done_handler_data, &cbdata)) {
f53969cc 119 retval = 1; /* Return that we've actually done some work */
350e2aec 120 done_callback(ctrlp->fd, cbdata, ctrlp->bufp,
0cc4a8bc 121 ctrlp->result.aio_return, ctrlp->result.aio_errno);
b9ae18aa 122 } else {
123 if (ctrlp->operation == _AIO_OPEN) {
124 /* The open operation was aborted.. */
125 int fd = ctrlp->result.aio_return;
126
127 if (fd >= 0)
128 aioClose(fd);
129 }
130 }
131 }
132
133 /* free data if requested to aioWrite() */
134 if (ctrlp->free_func)
135 ctrlp->free_func(ctrlp->bufp);
136
137 /* free temporary read buffer */
138 if (ctrlp->operation == _AIO_READ)
139 squidaio_xfree(ctrlp->bufp, ctrlp->len);
140
91ea1911 141 delete ctrlp;
b9ae18aa 142 }
143
144 return retval;
145}
146
147/* Flush all pending I/O */
148void
149DiskThreadsIOStrategy::sync()
150{
151 if (!initialised)
f53969cc 152 return; /* nothing to do then */
b9ae18aa 153
154 /* Flush all pending operations */
709873c3 155 debugs(32, 2, "aioSync: flushing pending I/O operations");
b9ae18aa 156
157 do {
158 callback();
159 } while (squidaio_sync());
160
709873c3 161 debugs(32, 2, "aioSync: done");
b9ae18aa 162}
163
e19994df 164DiskThreadsIOStrategy::DiskThreadsIOStrategy() :
91ea1911 165 initialised(false)
e19994df 166{}
b9ae18aa 167
168void
169DiskThreadsIOStrategy::aioStats(StoreEntry * sentry)
170{
171 storeAppendPrintf(sentry, "ASYNC IO Counters:\n");
22cec59e
AJ
172 storeAppendPrintf(sentry, " Operation\t# Requests\tNumber serviced\n");
173 storeAppendPrintf(sentry, " open\t%" PRIu64 "\t%" PRIu64 "\n", squidaio_counts.open_start, squidaio_counts.open_finish);
174 storeAppendPrintf(sentry, " close\t%" PRIu64 "\t%" PRIu64 "\n", squidaio_counts.close_start, squidaio_counts.close_finish);
175 storeAppendPrintf(sentry, " cancel\t%" PRIu64 "\t-\n", squidaio_counts.cancel);
176 storeAppendPrintf(sentry, " write\t%" PRIu64 "\t%" PRIu64 "\n", squidaio_counts.write_start, squidaio_counts.write_finish);
177 storeAppendPrintf(sentry, " read\t%" PRIu64 "\t%" PRIu64 "\n", squidaio_counts.read_start, squidaio_counts.read_finish);
178 storeAppendPrintf(sentry, " stat\t%" PRIu64 "\t%" PRIu64 "\n", squidaio_counts.stat_start, squidaio_counts.stat_finish);
179 storeAppendPrintf(sentry, " unlink\t%" PRIu64 "\t%" PRIu64 "\n", squidaio_counts.unlink_start, squidaio_counts.unlink_finish);
180 storeAppendPrintf(sentry, " check_callback\t%" PRIu64 "\t-\n", squidaio_counts.check_callback);
181 storeAppendPrintf(sentry, " queue\t%d\t-\n", squidaio_get_queue_len());
b0465494 182 squidaio_stats(sentry);
b9ae18aa 183}
184
b9ae18aa 185DiskThreadsIOStrategy DiskThreadsIOStrategy::Instance;
186bool
187DiskThreadsIOStrategy::shedLoad()
188{
189 /*
190 * we should detect some 'too many files open' condition and return
191 * NULL here.
192 */
193#ifdef MAGIC2
194
195 if (aioQueueSize() > MAGIC2)
196 return true;
197
198#endif
199
200 return false;
201}
202
203int
204DiskThreadsIOStrategy::load()
205{
206 int loadav;
207 int ql;
208
209 ql = aioQueueSize();
210
211 if (ql == 0)
212 loadav = 0;
213
214 loadav = ql * 1000 / MAGIC1;
215
bf8fe701 216 debugs(47, 9, "DiskThreadsIOStrategy::load: load=" << loadav);
b9ae18aa 217
218 return loadav;
219}
220
221DiskFile::Pointer
222DiskThreadsIOStrategy::newFile (char const *path)
223{
224 if (shedLoad()) {
225 return NULL;
226 }
227
43b6575c 228 return new DiskThreadsDiskFile(path);
b9ae18aa 229}
230
c521ad17
DK
231bool
232DiskThreadsIOStrategy::unlinkdUseful() const
233{
234 return false;
235}
236
b9ae18aa 237void
238DiskThreadsIOStrategy::unlinkFile(char const *path)
239{
e4f1fdae 240 ++statCounter.syscalls.disk.unlinks;
b9ae18aa 241 aioUnlink(path, NULL, NULL);
b9ae18aa 242}
f53969cc 243