DiskThreadsIOStrategy.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
3  *
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.
7  */
8 
9 /* DEBUG: section 79 Squid-side Disk I/O functions. */
10 
11 #include "squid.h"
12 #include "DiskThreadsDiskFile.h"
13 #include "DiskThreadsIOStrategy.h"
14 #include "fde.h"
15 #include "mgr/Registration.h"
16 #include "SquidConfig.h"
17 #include "StatCounters.h"
18 #include "Store.h"
19 
20 /* squidaio_ctrl_t uses explicit alloc()/freeOne().
21  * XXX: convert to MEMPROXY_CLASS() API
22  */
23 #include "mem/Pool.h"
24 
25 void
27 {
28  if (initialised)
29  return;
30 
31  initialised = true;
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  */
38 
40 }
41 
42 void
44 {
45  Mgr::RegisterAction("squidaio_counts", "Async IO Function Counters",
46  aioStats, 0, 1);
47 }
48 
49 void
51 {
52  if (!initialised)
53  return;
54 
56 
57  initialised = false;
58 }
59 
60 int
62 {
63  squidaio_result_t *resultp;
64  squidaio_ctrl_t *ctrlp;
65  int retval = 0;
66 
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 
80  case _AIO_OP_OPENDIR:
81  break;
82 
83  case _AIO_OP_OPEN:
85  break;
86 
87  case _AIO_OP_READ:
89  break;
90 
91  case _AIO_OP_WRITE:
93  break;
94 
95  case _AIO_OP_CLOSE:
97  break;
98 
99  case _AIO_OP_UNLINK:
101  break;
102 
103  case _AIO_OP_STAT:
105  break;
106  }
107 
108  if (ctrlp == NULL)
109  continue; /* XXX Should not happen */
110 
111  dlinkDelete(&ctrlp->node, &used_list);
112 
113  if (ctrlp->done_handler) {
114  AIOCB *done_callback = ctrlp->done_handler;
115  void *cbdata;
116  ctrlp->done_handler = NULL;
117 
118  if (cbdataReferenceValidDone(ctrlp->done_handler_data, &cbdata)) {
119  retval = 1; /* Return that we've actually done some work */
120  done_callback(ctrlp->fd, cbdata, ctrlp->bufp,
121  ctrlp->result.aio_return, ctrlp->result.aio_errno);
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 
141  delete ctrlp;
142  }
143 
144  return retval;
145 }
146 
147 /* Flush all pending I/O */
148 void
150 {
151  if (!initialised)
152  return; /* nothing to do then */
153 
154  /* Flush all pending operations */
155  debugs(32, 2, "aioSync: flushing pending I/O operations");
156 
157  do {
158  callback();
159  } while (squidaio_sync());
160 
161  debugs(32, 2, "aioSync: done");
162 }
163 
165  initialised(false)
166 {}
167 
168 void
170 {
171  storeAppendPrintf(sentry, "ASYNC IO Counters:\n");
172  storeAppendPrintf(sentry, " Operation\t# Requests\tNumber serviced\n");
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());
182  squidaio_stats(sentry);
183 }
184 
186 bool
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 
203 int
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 
216  debugs(47, 9, "DiskThreadsIOStrategy::load: load=" << loadav);
217 
218  return loadav;
219 }
220 
223 {
224  if (shedLoad()) {
225  return NULL;
226  }
227 
228  return new DiskThreadsDiskFile (path, this);
229 }
230 
231 bool
233 {
234  return false;
235 }
236 
237 void
239 {
240  ++statCounter.syscalls.disk.unlinks;
241  aioUnlink(path, NULL, NULL);
242 }
243 
#define cbdataReferenceValidDone(var, ptr)
Definition: cbdata.h:256
StatCounters statCounter
Definition: StatCounters.cc:12
#define assert(EX)
Definition: assert.h:17
Definition: cbdata.cc:60
uint64_t open_start
Definition: DiskThreads.h:125
int aioQueueSize(void)
Definition: async_io.cc:199
uint64_t unlink_finish
Definition: DiskThreads.h:137
squidaio_result_t result
Definition: DiskThreads.h:80
#define _AIO_READ
void squidaio_shutdown(void)
Definition: aiops.cc:333
dlink_node node
Definition: DiskThreads.h:84
uint64_t open_finish
Definition: DiskThreads.h:126
uint64_t close_start
Definition: DiskThreads.h:127
squidaio_result_t * squidaio_poll_done(void)
Definition: aiops.cc:905
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:123
struct StatCounters::@136 syscalls
void RegisterAction(char const *action, char const *desc, OBJH *handler, int pw_req_flag, int atomic)
Definition: Registration.cc:16
uint64_t close_finish
Definition: DiskThreads.h:128
uint64_t write_start
Definition: DiskThreads.h:130
virtual RefCount< DiskFile > newFile(char const *path)
struct StatCounters::@136::@139 disk
#define MAGIC2
Definition: DiskThreads.h:36
AIOCB * done_handler
Definition: DiskThreads.h:78
int squidaio_get_queue_len(void)
Definition: aiops.cc:967
uint64_t stat_start
Definition: DiskThreads.h:134
uint64_t cancel
Definition: DiskThreads.h:129
virtual void unlinkFile(char const *)
#define _AIO_OPEN
void aioClose(int fd)
Definition: async_io.cc:47
static DiskThreadsIOStrategy Instance
AIOCounts squidaio_counts
Definition: async_io.cc:18
void squidaio_xfree(void *p, int size)
Definition: aiops.cc:197
FREE * free_func
Definition: DiskThreads.h:83
#define PRIu64
Definition: types.h:120
uint64_t check_callback
Definition: DiskThreads.h:138
uint64_t write_finish
Definition: DiskThreads.h:131
static void aioStats(StoreEntry *sentry)
dlink_list used_list
Definition: async_io.cc:26
uint64_t stat_finish
Definition: DiskThreads.h:135
int squidaio_sync(void)
Definition: aiops.cc:955
virtual bool unlinkdUseful() const
uint64_t read_start
Definition: DiskThreads.h:132
void aioUnlink(const char *path, AIOCB *callback, void *callback_data)
Definition: async_io.cc:183
#define MAGIC1
Definition: DiskThreads.h:34
uint64_t read_finish
Definition: DiskThreads.h:133
void AIOCB(int fd, void *cbdata, const char *buf, int aio_return, int aio_errno)
Definition: DiskThreads.h:57
void * done_handler_data
Definition: DiskThreads.h:79
void squidaio_stats(StoreEntry *sentry)
Definition: aiops.cc:1003
enum _squidaio_request_type result_type
Definition: DiskThreads.h:64
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
Definition: store.cc:904
#define NULL
Definition: types.h:166
uint64_t unlink_start
Definition: DiskThreads.h:136
#define false
Definition: GnuRegex.c:233

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors