EventsListsShmemManager.h 4.29 KB
Newer Older
1
2
3
4
5
6
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
//     NScD Oak Ridge National Laboratory, European Spallation Source
//     & Institut Laue - Langevin
// SPDX - License - Identifier: GPL - 3.0 +
7
#pragma once
8
9
10
11
12

#include "boost/interprocess/containers/vector.hpp"
#include "boost/interprocess/managed_shared_memory.hpp"
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/offset_ptr.hpp>
13
#include <ostream>
14
15
16
17
18
19
20
21
22
23
24
25
26

#include "MantidParallel/DllConfig.h"

namespace ip = boost::interprocess;

namespace Mantid {
namespace Types {
namespace Event {
class TofEvent;
}
} // namespace Types

namespace Parallel {
27
namespace IO {
28
29

/** EventsListsShmemManager : Operates with event list in shared memory in
30
 * multiprocess environment; NOT an !!!OWNER of shared memory!!!
31
32
33
34
 * Initially the plan had been to crteate all shared memory segments in
 * main process in RAII style, but in the modern linux implementation you
 * can't create more than 1 NAMED shared memory segment in single process,
 * but we should use NAMED shared memory to fit other OS needs,
35
 * so in current implementation all segments are created by child processes
36
37
38
39
 * and destroyed by parent. This may be fixed in the future, then this class,
 * may be used for operating on segments from child processes.
 * EventsListsShmemManager base class for EventsListsShmemStorage,
 * that is the owner. Structure of storage:
40
41
42
43
 *    chunk_0 |pixel_0|   chunk_1 |pixel_0| ... chunk_N |pixel_0|
 *            |pixel_1|           |pixel_1|      ...    |pixel_1|
 *            ... ... ... ... ... ... ... ... ... ... ... ... ...
 *            |pixel_M|           |pixel_M|      ...    |pixel_M|
44
45
 *
 * Every chunk can partially store events for every pixel.
46
47
48
49

  @author Igor Gudich
  @date 2018
*/
50
51
52
53
54
55
56
57
58
59

using SegmentManager = ip::managed_shared_memory::segment_manager;
using VoidAllocator = ip::allocator<void, SegmentManager>;
using TofEventAllocator = ip::allocator<Types::Event::TofEvent, SegmentManager>;
using EventList = ip::vector<Types::Event::TofEvent, TofEventAllocator>;
using EventListAllocator = ip::allocator<EventList, SegmentManager>;
using EventLists = ip::vector<EventList, EventListAllocator>;
using EventListsAllocator = ip::allocator<EventLists, SegmentManager>;
using Chunks = ip::vector<EventLists, EventListsAllocator>;

60
61
62
63
64
65
class MANTID_PARALLEL_DLL EventsListsShmemManager {
public:
  // Constructor for client usage: "sets" Manager to the piece of shared memory
  // with existed GuardedEventLists in it
  EventsListsShmemManager(const std::string &segmentName,
                          const std::string &elName);
66

67
  virtual ~EventsListsShmemManager() = default;
68

69
  void appendEvent(std::size_t chunkN, std::size_t listN,
70
                   const Types::Event::TofEvent &event);
71
  template <typename InIter>
72
  void appendEvent(std::size_t chunkN, std::size_t listN, InIter from,
73
                   InIter to);
74

75
76
77
  std::size_t pixelCount() {
    return m_chunks && !m_chunks->empty() ? m_chunks->at(0).size() : 0;
  }
78

79
80
  MANTID_PARALLEL_DLL friend std::ostream &
  operator<<(std::ostream &os, const EventsListsShmemManager &manager);
81
82
83
84
85
86
87

protected:
  // Constructor for internal usage in  that just sets up the names, instance
  // for m_eventLists is defined later in derivated class constructor.
  EventsListsShmemManager(const std::string &segmentName,
                          const std::string &elName, int);

88
89
  const VoidAllocator &alloc() const;

90
91
92
93
  /// The name of shared memory segment to save the list of event
  const std::string m_segmentName;

  /// Allocator to mange shared memory
94
  std::unique_ptr<VoidAllocator> m_allocatorInstance;
95
96

  /// Event list shared storage name
97
  const std::string m_chunksName;
98

99
  /// Memory segment to store data
100
  std::unique_ptr<ip::managed_shared_memory> m_segment;
101

102
  /// Event list shared storage
103
  Chunks *m_chunks;
104
105
};

106
/// Appends the range of ToF events (from other container for example)
107
template <typename InIter>
108
void EventsListsShmemManager::appendEvent(std::size_t chunkN, std::size_t listN,
igudich's avatar
igudich committed
109
110
                                          InIter from, InIter to) {
  if (!m_chunks)
111
    throw("No event lists found.");
igudich's avatar
igudich committed
112
113
114
115
  auto &list = m_chunks->at(chunkN).at(listN);
  list.insert(list.end(), from, to);
}

116
} // namespace IO
117
118
} // namespace Parallel
} // namespace Mantid