Now all shared structures properly reserve() memory.
shm.open();
shared = reinterpret_cast<Shared *>(shm.mem());
assert(shared);
+ const int mySharedSize =
+ Items2Bytes(shared->theMaxItemSize, shared->theCapacity);
+ assert(shared == reinterpret_cast<Shared *>(shm.reserve(mySharedSize)));
}
void
pageIndex(PageIndexId(id), capacity),
shm(id.termedBuf())
{
- shm.create(Shared::MemSize(capacity, pageSize));
+ const off_t mySharedSize = Shared::MemSize(capacity, pageSize);
+ shm.create(mySharedSize);
assert(shm.mem());
- shared = new (shm.mem()) Shared(capacity, pageSize);
+ shared = new (shm.reserve(mySharedSize)) Shared(capacity, pageSize);
}
Ipc::Mem::PagePool::PagePool(const String &id):
shm.open();
shared = reinterpret_cast<Shared *>(shm.mem());
assert(shared);
+ const off_t mySharedSize =
+ Shared::MemSize(shared->theCapacity, shared->thePageSize);
+ assert(shared == reinterpret_cast<Shared *>(shm.reserve(mySharedSize)));
}
void
Ipc::Mem::PageStack::PageStack(const String &id, const unsigned int capacity):
shm(id.termedBuf())
{
- shm.create(sizeof(Shared::Item) * capacity + sizeof(Shared));
+ const size_t mySharedSize = Shared::MemSize(capacity);
+ shm.create(mySharedSize);
assert(shm.mem());
- shared = new (shm.mem()) Shared(capacity);
+ shared = new (shm.reserve(mySharedSize)) Shared(capacity);
}
Ipc::Mem::PageStack::PageStack(const String &id): shm(id.termedBuf())
shm.open();
shared = reinterpret_cast<Shared *>(shm.mem());
assert(shared);
+ const off_t mySharedSize = Shared::MemSize(shared->theCapacity);
+ assert(shared == reinterpret_cast<Shared *>(shm.reserve(mySharedSize)));
}
void
for (Offset i = 0; i < theSize; ++i)
theItems[i] = i + 1; // skip page number zero to keep numbers positive
}
+
+size_t
+Ipc::Mem::PageStack::Shared::MemSize(const unsigned int capacity)
+{
+ return sizeof(Item) * capacity + sizeof(Shared);
+}
struct Shared {
Shared(const unsigned int aCapacity);
+ /// total shared memory size required to share
+ static size_t MemSize(const unsigned int capacity);
+
// these help iterate the stack in search of a free spot or a page
Offset next(const Offset idx) const { return (idx + 1) % theCapacity; }
Offset prev(const Offset idx) const { return (theCapacity + idx - 1) % theCapacity; }
void *
Ipc::Mem::Segment::reserve(size_t chunkSize)
{
+ Must(theMem);
// check for overflows
assert(static_cast<off_t>(chunkSize) >= 0);
assert(static_cast<off_t>(chunkSize) <= theSize);
assert(theReserved <= theSize - static_cast<off_t>(chunkSize));
- void *result = reinterpret_cast<char*>(mem()) + theReserved;
+ void *result = reinterpret_cast<char*>(theMem) + theReserved;
theReserved += chunkSize;
return result;
}
const String &name() { return theName; } ///< shared memory segment name
off_t size() { return theSize; } ///< shared memory segment size
- void *mem() { return theMem; } ///< pointer to mmapped shared memory segment
+ void *mem() { return reserve(0); } ///< pointer to the next chunk
void *reserve(size_t chunkSize); ///< reserve and return the next chunk
- // TODO: convert most mem() calls to reserve()
static void Unlink(const char *const id); ///< unlink the segment