Thrill  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
linuxaio_queue.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  * foxxll/io/linuxaio_queue.hpp
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 
14 #ifndef FOXXLL_IO_LINUXAIO_QUEUE_HEADER
15 #define FOXXLL_IO_LINUXAIO_QUEUE_HEADER
16 
18 
19 #if FOXXLL_HAVE_LINUXAIO_FILE
20 
21 #include <linux/aio_abi.h>
22 
23 #include <atomic>
24 #include <list>
25 #include <mutex>
26 
28 
29 namespace foxxll {
30 
31 //! \addtogroup foxxll_reqlayer
32 //! \{
33 
34 //! Queue for linuxaio_file(s)
35 //!
36 //! Only one queue exists in a program, i.e. it is a singleton.
37 class linuxaio_queue : public request_queue_impl_worker
38 {
39  constexpr static bool debug = false;
40 
41  friend class linuxaio_request;
42 
43  using self_type = linuxaio_queue;
44 
45 private:
46  //! OS context_
47  aio_context_t context_;
48 
49  //! storing linuxaio_request* would drop ownership
50  using queue_type = std::list<request_ptr>;
51 
52  // "waiting" request have submitted to this queue, but not yet to the OS,
53  // those are "posted"
54  std::mutex waiting_mtx_;
55  queue_type waiting_requests_;
56 
57  //! max number of OS requests
58  int max_events_;
59  //! number of requests in waitings_requests
60  tlx::semaphore num_waiting_requests_, num_free_events_, num_posted_requests_;
61 
62  // two threads, one for posting, one for waiting
63  std::thread post_thread_, wait_thread_;
64  shared_state<thread_state> post_thread_state_, wait_thread_state_;
65 
66  // Why do we need two threads, one for posting, and one for waiting? Is
67  // one not enough?
68  // 1. User call cannot io_submit directly, since this tends to take
69  // considerable time sometimes
70  // 2. A single thread cannot wait for the user program to post requests
71  // and the OS to produce I/O completion events at the same time
72  // (IOCB_CMD_NOOP does not seem to help here either)
73 
74  static const priority_op priority_op_ = WRITE;
75 
76  static void * post_async(void* arg); // thread start callback
77  static void * wait_async(void* arg); // thread start callback
78  void post_requests();
79  void handle_events(io_event* events, long num_events, bool canceled);
80  void wait_requests();
81  void suspend();
82 
83  // needed by linuxaio_request
84  aio_context_t get_io_context() { return context_; }
85 
86 public:
87  //! Construct queue. Requests max number of requests simultaneously
88  //! submitted to disk, 0 means as many as possible
89  explicit linuxaio_queue(int desired_queue_length = 0);
90 
91  void add_request(request_ptr& req) final;
92  bool cancel_request(request_ptr& req) final;
93  void complete_request(request_ptr& req);
94  ~linuxaio_queue();
95 };
96 
97 //! \}
98 
99 } // namespace foxxll
100 
101 #endif // #if FOXXLL_HAVE_LINUXAIO_FILE
102 
103 #endif // !FOXXLL_IO_LINUXAIO_QUEUE_HEADER
104 
105 /**************************************************************************/
A simple semaphore implementation using C++11 synchronization methods.
Definition: semaphore.hpp:26
tlx::counting_ptr< request > request_ptr
A reference counting pointer for request.
Definition: request.hpp:43
static constexpr bool debug