• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

P_AIO.h

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 /****************************************************************************
00025 
00026   Async Disk IO operations.
00027 
00028 
00029 
00030  ****************************************************************************/
00031 #ifndef _P_AIO_h_
00032 #define _P_AIO_h_
00033 
00034 #include "P_EventSystem.h"
00035 #include "I_AIO.h"
00036 
00037 // for debugging
00038 // #define AIO_STATS 1
00039 
00040 #undef  AIO_MODULE_VERSION
00041 #define AIO_MODULE_VERSION        makeModuleVersion(AIO_MODULE_MAJOR_VERSION,\
00042                                                     AIO_MODULE_MINOR_VERSION,\
00043                                                     PRIVATE_MODULE_HEADER)
00044 
00045 TS_INLINE int
00046 AIOCallback::ok()
00047 {
00048   return (off_t) aiocb.aio_nbytes == (off_t) aio_result;
00049 }
00050 
00051 #if AIO_MODE == AIO_MODE_NATIVE
00052 
00053 extern Continuation *aio_err_callbck;
00054 
00055 struct AIOCallbackInternal: public AIOCallback
00056 {
00057   int io_complete(int event, void *data);
00058   AIOCallbackInternal()
00059   {
00060     memset ((char *) &(this->aiocb), 0, sizeof(this->aiocb));
00061     SET_HANDLER(&AIOCallbackInternal::io_complete);
00062   }
00063 };
00064 
00065 TS_INLINE int
00066 AIOCallbackInternal::io_complete(int event, void *data)
00067 {
00068   (void) event;
00069   (void) data;
00070 
00071   if (!ok() && aio_err_callbck)
00072     eventProcessor.schedule_imm(aio_err_callbck, ET_CALL, AIO_EVENT_DONE);
00073   mutex = action.mutex;
00074   MUTEX_LOCK(lock, mutex, this_ethread());
00075   if (!action.cancelled)
00076     action.continuation->handleEvent(AIO_EVENT_DONE, this);
00077   return EVENT_DONE;
00078 }
00079 
00080 TS_INLINE int
00081 AIOVec::mainEvent(int /* event */, Event *) {
00082   ++completed;
00083   if (completed < size)
00084     return EVENT_CONT;
00085   else if (completed == size) {
00086     MUTEX_LOCK(lock, action.mutex, this_ethread());
00087     if (!action.cancelled)
00088       action.continuation->handleEvent(AIO_EVENT_DONE, first);
00089     delete this;
00090     return EVENT_DONE;
00091   }
00092   ink_assert(!"AIOVec mainEvent err");
00093   return EVENT_ERROR;
00094 }
00095 
00096 #else /* AIO_MODE != AIO_MODE_NATIVE */
00097 
00098 struct AIO_Reqs;
00099 
00100 struct AIOCallbackInternal: public AIOCallback
00101 {
00102   AIOCallback *first;
00103   AIO_Reqs *aio_req;
00104   ink_hrtime sleep_time;
00105   int io_complete(int event, void *data);
00106   AIOCallbackInternal()
00107   {
00108     const size_t to_zero = sizeof(AIOCallbackInternal)
00109       - (size_t) & (((AIOCallbackInternal *) 0)->aiocb);
00110     // coverity[overrun-buffer-arg]
00111     memset((char *) &(this->aiocb), 0, to_zero);
00112     SET_HANDLER(&AIOCallbackInternal::io_complete);
00113     // we do a memset() on AIOCallback and AIOCallbackInternal, so it sets all the members to 0
00114     // coverity[uninit_member]
00115   }
00116 };
00117 
00118 TS_INLINE int
00119 AIOCallbackInternal::io_complete(int event, void *data)
00120 {
00121   (void) event;
00122   (void) data;
00123   if (!action.cancelled)
00124     action.continuation->handleEvent(AIO_EVENT_DONE, this);
00125   return EVENT_DONE;
00126 }
00127 
00128 struct AIO_Reqs
00129 {
00130   Que(AIOCallback, link) aio_todo;       /* queue for holding non-http requests */
00131   Que(AIOCallback, link) http_aio_todo;  /* queue for http requests */
00132   /* Atomic list to temporarily hold the request if the
00133      lock for a particular queue cannot be acquired */
00134   InkAtomicList aio_temp_list;
00135   ink_mutex aio_mutex;
00136   ink_cond aio_cond;
00137   int index;                    /* position of this struct in the aio_reqs array */
00138   volatile int pending;         /* number of outstanding requests on the disk */
00139   volatile int queued;          /* total number of aio_todo and http_todo requests */
00140   volatile int filedes;         /* the file descriptor for the requests */
00141   volatile int requests_queued;
00142 };
00143 
00144 #endif // AIO_MODE == AIO_MODE_NATIVE
00145 #ifdef AIO_STATS
00146 class AIOTestData:public Continuation
00147 {
00148 public:
00149   int num_req;
00150   int num_temp;
00151   int num_queue;
00152   ink_hrtime start;
00153 
00154   int ink_aio_stats(int event, void *data);
00155 
00156   AIOTestData():Continuation(new_ProxyMutex()), num_req(0), num_temp(0), num_queue(0)
00157   {
00158     start = ink_get_hrtime();
00159     SET_HANDLER(&AIOTestData::ink_aio_stats);
00160   }
00161 };
00162 #endif
00163 
00164 enum aio_stat_enum
00165 {
00166   AIO_STAT_READ_PER_SEC,
00167   AIO_STAT_KB_READ_PER_SEC,
00168   AIO_STAT_WRITE_PER_SEC,
00169   AIO_STAT_KB_WRITE_PER_SEC,
00170   AIO_STAT_COUNT
00171 };
00172 extern RecRawStatBlock *aio_rsb;
00173 
00174 #endif

Generated by  doxygen 1.7.1