Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Have create_jbod() return a JbodPtr instead of Jbod* to avoid memleaks
[simgrid.git] / include / simgrid / plugins / jbod.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_PLUGIN_JBOD_HPP
7 #define SIMGRID_PLUGIN_JBOD_HPP
8 #include <simgrid/s4u/Host.hpp>
9 #include <simgrid/s4u/Io.hpp>
10
11 namespace simgrid::plugin {
12
13 class Jbod;
14 using JbodPtr = boost::intrusive_ptr<Jbod>;
15 class JbodIo;
16 using JbodIoPtr = boost::intrusive_ptr<JbodIo>;
17
18 class Jbod {
19 public:
20   enum class RAID {RAID0 = 0, RAID1 = 1, RAID4 = 4 , RAID5 = 5, RAID6 = 6};
21   s4u::Host* get_controller() const { return controller_; }
22   int get_parity_disk_idx() { return parity_disk_idx_; }
23   void update_parity_disk_idx() { parity_disk_idx_ = (parity_disk_idx_- 1) % num_disks_; }
24
25   int get_next_read_disk_idx() { return (++read_disk_idx_) % num_disks_; }
26
27   JbodIoPtr read_async(sg_size_t size);
28   sg_size_t read(sg_size_t size);
29
30   JbodIoPtr write_async(sg_size_t size);
31   sg_size_t write(sg_size_t size);
32
33   static JbodPtr create_jbod(s4u::NetZone* zone, const std::string& name, double speed, unsigned int num_disks,
34                              RAID raid_level, double read_bandwidth, double write_bandwidth);
35
36 protected:
37   void set_controller(s4u::Host* host) { controller_ = host; }
38   void set_num_disks(unsigned int num_disks) { num_disks_ = num_disks; }
39   void set_parity_disk_idx(unsigned int index) { parity_disk_idx_ = index; }
40   void set_read_disk_idx(int index) { read_disk_idx_ = index; }
41   void set_raid_level(RAID raid_level) { raid_level_ = raid_level; }
42
43 private:
44   s4u::Host* controller_;
45   unsigned int num_disks_;
46   RAID raid_level_;
47   unsigned int parity_disk_idx_;
48   int read_disk_idx_;
49   std::atomic_int_fast32_t refcount_{1};
50 #ifndef DOXYGEN
51   friend void intrusive_ptr_release(Jbod* jbod)
52   {
53     if (jbod->refcount_.fetch_sub(1, std::memory_order_release) == 1) {
54       std::atomic_thread_fence(std::memory_order_acquire);
55       delete jbod;
56     }
57   }
58   friend void intrusive_ptr_add_ref(Jbod* jbod) { jbod->refcount_.fetch_add(1, std::memory_order_relaxed); }
59 #endif
60 };
61
62 class JbodIo {
63   const Jbod* jbod_;
64   s4u::CommPtr transfer_;
65   s4u::ExecPtr parity_block_comp_;
66   std::vector<s4u::IoPtr> pending_ios_;
67   s4u::Io::OpType type_;
68   std::atomic_int_fast32_t refcount_{0};
69 public:
70
71   explicit JbodIo(const Jbod* jbod, const s4u::CommPtr transfer, const s4u::ExecPtr parity_block_comp,
72                   const std::vector<s4u::IoPtr>& pending_ios, s4u::Io::OpType type)
73     : jbod_(jbod), transfer_(transfer), parity_block_comp_(parity_block_comp), pending_ios_(pending_ios), type_(type)
74     {}
75
76   void wait();
77
78 #ifndef DOXYGEN
79   friend void intrusive_ptr_release(JbodIo* io)
80   {
81     if (io->refcount_.fetch_sub(1, std::memory_order_release) == 1) {
82       std::atomic_thread_fence(std::memory_order_acquire);
83       delete io;
84     }
85   }
86   friend void intrusive_ptr_add_ref(JbodIo* io) { io->refcount_.fetch_add(1, std::memory_order_relaxed); }
87 #endif
88 };
89
90 /* Refcounting functions */
91 XBT_PUBLIC void intrusive_ptr_release(const Jbod* io);
92 XBT_PUBLIC void intrusive_ptr_add_ref(const Jbod* io);
93 XBT_PUBLIC void intrusive_ptr_release(const JbodIo* io);
94 XBT_PUBLIC void intrusive_ptr_add_ref(const JbodIo* io);
95
96 } // namespace simgrid::plugin
97 #endif