Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
add Message queue abstraction
[simgrid.git] / include / simgrid / s4u / MessageQueue.hpp
1 /* Copyright (c) 2023. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #ifndef SIMGRID_S4U_MESSAGEQUEUE_HPP
7 #define SIMGRID_S4U_MESSAGEQUEUE_HPP
8
9 #include <simgrid/forward.h>
10 #include <simgrid/s4u/Mess.hpp>
11 #include <smpi/forward.hpp>
12
13 #include <string>
14
15 namespace simgrid::s4u {
16
17 class XBT_PUBLIC MessageQueue {
18 #ifndef DOXYGEN
19   friend Mess;
20   friend kernel::activity::MessageQueueImpl;
21 #endif
22
23   kernel::activity::MessageQueueImpl* const pimpl_;
24
25   explicit MessageQueue(kernel::activity::MessageQueueImpl * mqueue) : pimpl_(mqueue) {}
26   ~MessageQueue() = default;
27
28 protected:
29   kernel::activity::MessageQueueImpl* get_impl() const { return pimpl_; }
30
31 public:
32   /** @brief Retrieves the name of that message queue as a C++ string */
33   const std::string& get_name() const;
34   /** @brief Retrieves the name of that message queue as a C string */
35   const char* get_cname() const;
36
37   /** \static Retrieve the message queye associated to the given name. Message queues are created on demand. */
38   static MessageQueue* by_name(const std::string& name);
39
40   /** Returns whether the message queue contains queued messages */
41   bool empty() const;
42
43   /* Returns the number of queued messages */
44   size_t size() const;
45
46   /** Gets the first element in the queue (without dequeuing it), or nullptr if none is there */
47   kernel::activity::MessImplPtr front() const;
48
49   /** Creates (but don't start) a data transmission to that message queue */
50   MessPtr put_init();
51   /** Creates (but don't start) a data transmission to that message queue.
52    *
53    * Please note that if you send a pointer to some data, you must ensure that your data remains live until
54    * consumption, or the receiver will get a pointer to a garbled memory area.
55    */
56   MessPtr put_init(void* payload);
57   /** Creates and start a data transmission to that mailbox.
58    *
59    * Please note that if you send a pointer to some data, you must ensure that your data remains live until
60    * consumption, or the receiver will get a pointer to a garbled memory area.
61    */
62   MessPtr put_async(void* payload);
63
64   /** Blocking data transmission.
65    *
66    * Please note that if you send a pointer to some data, you must ensure that your data remains live until
67    * consumption, or the receiver will get a pointer to a garbled memory area.
68    */
69   void put(void* payload);
70   /** Blocking data transmission with timeout */
71   void put(void* payload, double timeout);
72
73   /** Creates (but don't start) a data reception onto that message queue. */
74   MessPtr get_init();
75   /** Creates and start an async data reception to that message queue */
76   template <typename T> MessPtr get_async(T** data);
77   /** Creates and start an async data reception to that mailbox. Since the data location is not provided, you'll have to
78    * use Mess::get_payload once the messaging operation terminates */
79   MessPtr get_async();
80
81   /** Blocking data reception */
82   template <typename T> T* get();
83   template <typename T> std::unique_ptr<T> get_unique() { return std::unique_ptr<T>(get<T>()); }
84
85   /** Blocking data reception with timeout */
86   template <typename T> T* get(double timeout);
87   template <typename T> std::unique_ptr<T> get_unique(double timeout) { return std::unique_ptr<T>(get<T>(timeout)); }
88 };
89
90 template <typename T> MessPtr MessageQueue::get_async(T** data)
91 {
92   MessPtr res = get_init()->set_dst_data(reinterpret_cast<void**>(data), sizeof(void*));
93   res->start();
94   return res;
95 }
96
97 template <typename T> T* MessageQueue::get()
98 {
99   T* res = nullptr;
100   get_async<T>(&res)->wait();
101   return res;
102 }
103
104 template <typename T> T* MessageQueue::get(double timeout)
105 {
106   T* res = nullptr;
107   get_async<T>(&res)->wait_for(timeout);
108   return res;
109 }
110 } // namespace simgrid::s4u
111
112 #endif /* SIMGRID_S4U_MESSAGEQUEUE_HPP */