/usr/include/bobcat/sharedmemory is in libbobcat-dev 4.04.00-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | #ifndef INCLUDED_BOBCAT_SHAREDMEMORY_
#define INCLUDED_BOBCAT_SHAREDMEMORY_
#include <ios>
#include <bobcat/fswap>
#include <bobcat/sharedpos>
#include <bobcat/exception>
namespace FBB
{
class SharedSegment;
struct SharedEnum__
{
enum SizeUnit
{
kB = 10,
MB = 20,
GB = 30
};
};
class SharedMemory: public virtual SharedEnum__
{
friend std::ostream &operator<<(std::ostream &out,
SharedMemory const &mem);
enum { PAGESIZE = 1 << 12 };
// updated by the non-default constructors.
int d_id = -1; // id of SharedSegment
SharedSegment *d_sharedSegment = 0; // points to the attached shared
// memory. This is NOT a pointer
// to dynamically allocated memory
// but a static_cast pointer to
// the attached shared data segment
SharedPos d_pos;
size_t d_lockCount = 0; // # of nested locks
char *d_data = 0; // pointer to shared memory data
public:
SharedMemory() = default;
SharedMemory(SharedMemory const &other) = delete;
SharedMemory(size_t maxSize, SizeUnit sizeUnit,
size_t access = 0600); // 2: creation mode;
SharedMemory(int id); // 3
~SharedMemory();
SharedMemory &operator=(SharedMemory &&tmp);
std::streamsize blockOffset() const;// offset matching offset(),
// relative to the current data
// block.
void clear(); // clear all existing data and reduce
// until only the segment at
// d_sharedSegment
size_t dataSegmentSize() const;
int get(); // get char from d_segmentData
// locks), or EOF
int id() const; // id of the d_sharedSegment segment
// after kill/remove: shared segment is unusable
void kill(); // delete all shared segments w/o locks
std::streamsize maxOffset() const;
std::streamsize nReadable() const; // beyond last readable byte
std::streamsize offset() const; // read/write offset relative to
// ios::beg
char *ptr(); // 0 if at maxOffset
int put(int ch); // put char at d_offset (locks),
// ch == EOF immediately returns EOF
// read len chars, return nRead or -1,
// locks
int read(char *data, std::streamsize len);
template <typename Type>
int read(Type *value); // 1.f
template <typename Type> // 2.f
int read(std::ios::off_type offset, Type *value,
std::ios::seekdir origin = std::ios::beg);
// after kill/remove: shared segment is unusable
void remove(); // delete all shared segments.
// returns -1 if inaccessible
std::ios::pos_type seek(std::ios::off_type offset,
std::ios::seekdir origin = std::ios::beg);
std::streamsize showmanyc();
void swap(SharedMemory &other);
bool truncate(std::streamsize offset); // nReadable is reduced to
// offset
// write len bytes at d_offset
// locks, returns #written or -1
int write(char const *data, std::streamsize len);
template <typename Type>
int write(Type const *value); // 1.f
template <typename Type> // 2.f
int write(std::ios::off_type offset, Type const *value,
std::ios::seekdir origin = std::ios::beg);
template <typename SharedType, typename ... Params>
SharedType *install(std::streamsize *offset, Params &&...params);
private:
std::ostream &insert(std::ostream &out) const;
// lockAll: d_lockCount should be 0.
void lockAll(); // lock all block[] mutexes
void unlockAll(); // unlock all block[] mutexes
void lock(size_t idx); // (recursively) lock block idx
void unlock(size_t idx); // unlock block idx
void clearAll(); // clear without locking
bool blockAvailable(size_t idx);
void map(); // 1 maps shared data to d_data
void map(size_t idx); // 2 only called by load
int writeBlock(char const *data, size_t len); // locks, returns
// #written or -1
int readBlock(char *data, size_t len); // same, but now reads
// both update offset
static size_t computeSegmentSize(
size_t *nBlocks,
long long maxMemory, SizeUnit sizeUnit);
void validate() const;
};
inline std::streamsize SharedMemory::blockOffset() const
{
return d_pos.blockOffset();
}
inline size_t SharedMemory::dataSegmentSize() const
{
return d_sharedSegment ? d_sharedSegment->segmentSize() : 0;
}
inline int SharedMemory::id() const
{
return d_id;
}
template <typename SharedType, typename ... Params>
SharedType *SharedMemory::install(std::streamsize *offsetPtr,
Params &&...params)
{
size_t segmentSize = dataSegmentSize();
if (segmentSize == 0)
throw Exception() << "SharedMemory::install: no memory";
// find a suitable offset for the shared memory object
size_t begin = blockOffset();
size_t end = (begin + sizeof(SharedType)) % segmentSize;
if (begin + sizeof(SharedType) != end)
seek((1 + offset() / segmentSize) * segmentSize);
// determine the object's offset and address
std::streamsize location = offset();
void *address = ptr();
// go to the object's last byte
if (address == 0 || seek(sizeof(SharedType) - 1) == -1)
throw Exception() << "SharedMemory::install: out of memory.";
// make sure shmem knows it exists by writing a byte at its last
// byte location
put(0);
if (offsetPtr)
*offsetPtr = location;
// install the object at 'address'
return new (address) SharedType(std::forward<Params>(params)...);
}
inline std::streamsize SharedMemory::maxOffset() const
{
return d_pos.maxOffset();
}
inline std::streamsize SharedMemory::nReadable() const
{
return d_sharedSegment ? d_sharedSegment->nReadable() : 0;
}
inline std::streamsize SharedMemory::offset() const
{
return d_pos.offset();
}
inline SharedMemory &SharedMemory::operator=(SharedMemory &&tmp)
{
swap(tmp);
return *this;
}
inline std::ostream &operator<<(std::ostream &out, SharedMemory const &mem)
{
return mem.insert(out);
}
template <typename Type>
inline int SharedMemory::read(Type *value)
{
return read(reinterpret_cast<char *>(value), sizeof(Type));
}
template <typename Type>
int SharedMemory::read(std::ios::off_type offset, Type *value,
std::ios::seekdir origin)
{
if (seek(offset, origin) == -1)
throw Exception() << "SharedMemory::read: seek to " << offset <<
"failed";
return read(value);
}
inline void SharedMemory::swap(SharedMemory &other)
{
FBB::fswap(*this, other);
}
template <typename Type>
inline int SharedMemory::write(Type const *value)
{
return write(reinterpret_cast<char const *>(value), sizeof(Type));
}
template <typename Type>
int SharedMemory::write(std::ios::off_type offset, Type const *value,
std::ios::seekdir origin)
{
if (seek(offset, origin) == -1)
throw Exception() << "SharedMemory::write: seek to " << offset <<
"failed";
return write(value);
}
} // FBB
#endif
|