Thrill  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
linuxaio_request.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * foxxll/io/linuxaio_request.cpp
3  *
4  * Part of FOXXLL. See http://foxxll.org
5  *
6  * Copyright (C) 2011 Johannes Singler <[email protected]>
7  * Copyright (C) 2014 Timo Bingmann <[email protected]>
8  *
9  * Distributed under the Boost Software License, Version 1.0.
10  * (See accompanying file LICENSE_1_0.txt or copy at
11  * http://www.boost.org/LICENSE_1_0.txt)
12  **************************************************************************/
13 
15 
16 #if FOXXLL_HAVE_LINUXAIO_FILE
17 
18 #include <sys/syscall.h>
19 #include <unistd.h>
20 
23 
24 namespace foxxll {
25 
26 void linuxaio_request::completed(bool posted, bool canceled)
27 {
28  LOG << "linuxaio_request[" << this << "] completed(" <<
29  posted << "," << canceled << ")";
30 
31  auto* stats = file_->get_file_stats();
32  const double duration = timestamp() - time_posted_;
33 
34  if (!canceled)
35  {
36  if (op_ == READ) {
37  stats->read_op_finished(bytes_, duration);
38  }
39  else {
40  stats->write_op_finished(bytes_, duration);
41  }
42  }
43  else if (posted)
44  {
45  if (op_ == READ)
46  stats->read_canceled(bytes_);
47  else
48  stats->write_canceled(bytes_);
49  }
50 
52 }
53 
54 void linuxaio_request::fill_control_block()
55 {
56  linuxaio_file* af = dynamic_cast<linuxaio_file*>(file_);
57 
58  memset(&cb_, 0, sizeof(cb_));
59  // indirection, I/O system retains a virtual counting_ptr reference
60  ReferenceCounter::inc_reference();
61  cb_.aio_data = reinterpret_cast<__u64>(this);
62  cb_.aio_fildes = af->file_des_;
63  cb_.aio_lio_opcode = (op_ == READ) ? IOCB_CMD_PREAD : IOCB_CMD_PWRITE;
64  cb_.aio_reqprio = 0;
65  cb_.aio_buf = static_cast<__u64>(reinterpret_cast<unsigned long>(buffer_));
66  cb_.aio_nbytes = bytes_;
67  cb_.aio_offset = offset_;
68 }
69 
70 //! Submits an I/O request to the OS
71 //! \returns false if submission fails
72 bool linuxaio_request::post()
73 {
74  LOG << "linuxaio_request[" << this << "] post()";
75 
76  fill_control_block();
77  iocb* cb_pointer = &cb_;
78  // io_submit might considerable time, so we have to remember the current
79  // time before the call.
80  time_posted_ = timestamp();
81  linuxaio_queue* queue = dynamic_cast<linuxaio_queue*>(
82  disk_queues::get_instance()->get_queue(file_->get_queue_id()));
83 
84  long success = syscall(SYS_io_submit, queue->get_io_context(), 1, &cb_pointer);
85  // At this point another thread may have already called complete(),
86  // so consider most values as invalidated!
87 
88  if (success == -1 && errno != EAGAIN)
90  io_error, "linuxaio_request::post"
91  " io_submit()"
92  );
93 
94  return success == 1;
95 }
96 
97 //! Cancel the request
98 //!
99 //! Routine is called by user, as part of the request interface.
100 bool linuxaio_request::cancel()
101 {
102  LOG << "linuxaio_request[" << this << "] cancel()";
103 
104  if (!file_) return false;
105 
106  request_ptr req(this);
107  linuxaio_queue* queue = dynamic_cast<linuxaio_queue*>(
108  disk_queues::get_instance()->get_queue(file_->get_queue_id()));
109  return queue->cancel_request(req);
110 }
111 
112 //! Cancel already posted request
113 bool linuxaio_request::cancel_aio(linuxaio_queue* queue)
114 {
115  LOG << "linuxaio_request[" << this << "] cancel_aio()";
116 
117  if (!file_) return false;
118 
119  io_event event;
120  long result = syscall(SYS_io_cancel, queue->get_io_context(), &cb_, &event);
121  if (result == 0) //successfully canceled
122  queue->handle_events(&event, 1, true);
123  return result == 0;
124 }
125 
126 } // namespace foxxll
127 
128 #endif // #if FOXXLL_HAVE_LINUXAIO_FILE
129 
130 /**************************************************************************/
tlx::counting_ptr< request > request_ptr
A reference counting pointer for request.
Definition: request.hpp:43
static double timestamp()
Returns number of seconds since the epoch, high resolution.
Definition: timer.hpp:36
void completed(bool canceled) override
#define FOXXLL_THROW_ERRNO(exception_type, error_message)
Throws exception_type with "Error in [function] : [error_message] : [errno message]".
static instance_pointer get_instance()
Definition: singleton.hpp:44
request_queue * get_queue(disk_id_type disk)
#define LOG
Default logging method: output if the local debug variable is true.
Definition: logger.hpp:141