STXXL  1.4-dev
 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  * lib/io/linuxaio_request.cpp
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
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 STXXL_HAVE_LINUXAIO_FILE
17 
19 #include <stxxl/bits/verbose.h>
21 
22 #include <unistd.h>
23 #include <sys/syscall.h>
24 
26 
27 void linuxaio_request::completed(bool posted, bool canceled)
28 {
29  STXXL_VERBOSE_LINUXAIO("linuxaio_request[" << this << "] completed(" <<
30  posted << "," << canceled << ")");
31 
32  if (!canceled)
33  {
34  if (m_type == READ)
35  stats::get_instance()->read_finished();
36  else
37  stats::get_instance()->write_finished();
38  }
39  else if (posted)
40  {
41  if (m_type == READ)
42  stats::get_instance()->read_canceled(m_bytes);
43  else
44  stats::get_instance()->write_canceled(m_bytes);
45  }
46  request_with_state::completed(canceled);
47 }
48 
49 void linuxaio_request::fill_control_block()
50 {
51  linuxaio_file* af = dynamic_cast<linuxaio_file*>(m_file);
52 
53  memset(&cb, 0, sizeof(cb));
54  // indirection, so the I/O system retains a counting_ptr reference
55  cb.aio_data = reinterpret_cast<__u64>(new request_ptr(this));
56  cb.aio_fildes = af->file_des;
57  cb.aio_lio_opcode = (m_type == READ) ? IOCB_CMD_PREAD : IOCB_CMD_PWRITE;
58  cb.aio_reqprio = 0;
59  cb.aio_buf = static_cast<__u64>((unsigned long)(m_buffer));
60  cb.aio_nbytes = m_bytes;
61  cb.aio_offset = m_offset;
62 }
63 
64 //! Submits an I/O request to the OS
65 //! \returns false if submission fails
66 bool linuxaio_request::post()
67 {
68  STXXL_VERBOSE_LINUXAIO("linuxaio_request[" << this << "] post()");
69 
70  fill_control_block();
71  iocb* cb_pointer = &cb;
72  // io_submit might considerable time, so we have to remember the current
73  // time before the call.
74  double now = timestamp();
75  linuxaio_queue* queue = dynamic_cast<linuxaio_queue*>(
76  disk_queues::get_instance()->get_queue(m_file->get_queue_id())
77  );
78  long success = syscall(SYS_io_submit, queue->get_io_context(), 1, &cb_pointer);
79  if (success == 1)
80  {
81  if (m_type == READ)
82  stats::get_instance()->read_started(m_bytes, now);
83  else
84  stats::get_instance()->write_started(m_bytes, now);
85  }
86  else if (success == -1 && errno != EAGAIN)
87  STXXL_THROW_ERRNO(io_error, "linuxaio_request::post"
88  " io_submit()");
89 
90  return success == 1;
91 }
92 
93 //! Cancel the request
94 //!
95 //! Routine is called by user, as part of the request interface.
96 bool linuxaio_request::cancel()
97 {
98  STXXL_VERBOSE_LINUXAIO("linuxaio_request[" << this << "] cancel()");
99 
100  if (!m_file) return false;
101 
102  request_ptr req(this);
103  linuxaio_queue* queue = dynamic_cast<linuxaio_queue*>(
104  disk_queues::get_instance()->get_queue(m_file->get_queue_id())
105  );
106  return queue->cancel_request(req);
107 }
108 
109 //! Cancel already posted request
110 bool linuxaio_request::cancel_aio()
111 {
112  STXXL_VERBOSE_LINUXAIO("linuxaio_request[" << this << "] cancel_aio()");
113 
114  if (!m_file) return false;
115 
116  io_event event;
117  linuxaio_queue* queue = dynamic_cast<linuxaio_queue*>(
118  disk_queues::get_instance()->get_queue(m_file->get_queue_id())
119  );
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 
127 
128 #endif // #if STXXL_HAVE_LINUXAIO_FILE
129 // vim: et:ts=4:sw=4
bool cancel_request(request_ptr &req)
External FIFO queue container. Introduction to queue container: see STXXL Queue tutorial Design a...
Definition: queue.h:51
Implementation of file based on the Linux kernel interface for asynchronous I/O.
Definition: linuxaio_file.h:34
counting_ptr< request > request_ptr
A reference counting pointer for request.
Definition: request.h:113
#define STXXL_VERBOSE_LINUXAIO(msg)
void handle_events(io_event *events, long num_events, bool canceled)
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
aio_context_t get_io_context()
#define STXXL_THROW_ERRNO(exception_type, error_message)
Throws exception_type with &quot;Error in [function] : [error_message] : [errno message]&quot;.
double timestamp()
Returns number of seconds since the epoch, high resolution.
Definition: timer.h:44
Queue for linuxaio_file(s)
#define STXXL_END_NAMESPACE
Definition: namespace.h:17