Skip to content

Commit

Permalink
Kernel: Deallocate memory in RingBuffer on destruction, more changes to
Browse files Browse the repository at this point in the history
how messages are stored. Delete unused scripts
  • Loading branch information
fido2020 committed Mar 2, 2021
1 parent 65ea239 commit 89f8045
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 47 deletions.
21 changes: 19 additions & 2 deletions Kernel/include/objects/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ class MessageEndpoint final : public KernelObject{

void Watch(KernelObjectWatcher& watcher, int events){
acquireLock(&waitingLock);
waiting.add_back(&watcher);
if(queue.Empty()){
waiting.add_back(&watcher);
} else {
watcher.Signal();
}
releaseLock(&waitingLock)
}

Expand All @@ -101,14 +105,27 @@ class MessageEndpoint final : public KernelObject{
uint8_t** buffer;
};

struct Message{
uint64_t id;
uint16_t size;
uint8_t data[];
};

inline Message* AllocateMessage(){
void* m = kmalloc(sizeof(Message) + maxMessageSize);

return reinterpret_cast<Message*>(m);
}

friend Pair<FancyRefPtr<MessageEndpoint>,FancyRefPtr<MessageEndpoint>> CreatePair();
uint16_t maxMessageSize = 8;
uint16_t messageQueueLimit = 128;
lock_t queueLock = 0;

Semaphore queueAvailablilitySemaphore = Semaphore(messageQueueLimit);

RawRingBuffer queue;
RingBuffer<Message*> queue;
RingBuffer<Message*> cache;

FancyRefPtr<MessageEndpoint> peer;

Expand Down
43 changes: 33 additions & 10 deletions Kernel/include/ringbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,23 @@ class RingBuffer{
dequeuePointer = buffer;
}

void Enqueue(const T* data){
virtual ~RingBuffer(){
delete buffer;
}

void Enqueue(const T& data){
acquireLock(&enqueueLock);
acquireLock(&dequeueLock);

memcpy(enqueuePointer++, data, sizeof(T));
*enqueuePointer++ = data;

if(enqueuePointer >= bufferEnd){
enqueuePointer = buffer;
enqueuePointer = buffer; // Wrap around to start
}

if(enqueuePointer == dequeuePointer){
Resize((bufferSize + 2) << 1);
// If after increasing the enqueue pointer it is equal to dequeue pointer then the queue is full
}

releaseLock(&enqueueLock);
Expand All @@ -57,14 +62,12 @@ class RingBuffer{
if(buffer + wrappedCount >= dequeuePointer){
Resize((bufferSize << 1) + count); // Ring buffer is full
}

memcpy(buffer, data + contiguousCount, sizeof(T) * wrappedCount);
}

memcpy(enqueuePointer, data, sizeof(T) * contiguousCount);

if(wrappedCount > 0){
memcpy(buffer, data + contiguousCount, sizeof(T) * wrappedCount);
}

size += count;
enqueuePointer = buffer + ((enqueuePointer + count - buffer) % bufferSize); // Calculate new enqueuePointer
}
Expand Down Expand Up @@ -116,6 +119,24 @@ class RingBuffer{
return contiguous + wrapped;
}

int Dequeue(T& data){
acquireLock(&dequeueLock);

if(dequeuePointer == enqueuePointer){
releaseLock(&dequeueLock);
return 0;
}

data = *dequeuePointer++;

if(dequeuePointer >= bufferEnd){
dequeuePointer = buffer;
}

releaseLock(&dequeueLock);
return 1;
}

void Drain() {
acquireLock(&enqueueLock);
acquireLock(&dequeueLock);
Expand Down Expand Up @@ -162,13 +183,15 @@ class RingBuffer{
bufferEnd = &buffer[bufferSize];

memcpy(bufferEnd - (oldBufferEnd - dequeuePointer), dequeuePointer, (oldBufferEnd - dequeuePointer) * sizeof(T));
dequeuePointer = bufferEnd - (oldBufferEnd - dequeuePointer);

if(dequeuePointer > enqueuePointer){
memcpy(buffer, oldBuffer, (enqueuePointer - oldBuffer) * sizeof(T));
enqueuePointer = buffer + (enqueuePointer - oldBuffer);
} else {
enqueuePointer = bufferEnd - (oldBufferEnd - enqueuePointer);
}

dequeuePointer = bufferEnd - (oldBufferEnd - dequeuePointer);
enqueuePointer = buffer + (enqueuePointer - oldBuffer);

kfree(oldBuffer);
}

Expand Down
8 changes: 5 additions & 3 deletions Kernel/src/arch/x86_64/syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -805,10 +805,12 @@ long SysGetVideoMode(RegisterContext* r){
}

long SysUName(RegisterContext* r){
char* str = (char*)SC_ARG0(r);
strcpy(str, Lemon::versionString);
if(Memory::CheckUsermodePointer(SC_ARG0(r), strlen(Lemon::versionString), Scheduler::GetCurrentProcess()->addressSpace)) {
strcpy((char*) SC_ARG0(r), Lemon::versionString);
return 0;
}

return 0;
return -EFAULT;
}

long SysReadDir(RegisterContext* r){
Expand Down
39 changes: 21 additions & 18 deletions Kernel/src/objects/message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,16 @@ int64_t MessageEndpoint::Read(uint64_t* id, uint16_t* size, uint8_t* data){

acquireLock(&queueLock);

queue.Dequeue(reinterpret_cast<uint8_t*>(id), sizeof(uint64_t));
queue.Dequeue(reinterpret_cast<uint8_t*>(size), sizeof(uint16_t));
Message* m;
if(queue.Dequeue(m) <= 0){
return 0;
}

if(*size){
size_t read = queue.Dequeue(data, *size);
if(read < *size){
Log::Warning("[MessageEndpoint] Draining message queue (expected %u bytes, only got %u) (id: %u size:, %hu)!", *size, read, *id, *size);
queue.Drain(); // Not all data has been written, drain the buffer
memcpy(data, m->data, m->size);
*size = m->size;
*id = m->id;

releaseLock(&queueLock);

if(!peer.get()){
return -ENOTCONN;
}
return 0;
}
}
cache.Enqueue(m);

releaseLock(&queueLock);

Expand Down Expand Up @@ -154,12 +147,22 @@ int64_t MessageEndpoint::Write(uint64_t id, uint16_t size, uint64_t data){
}

acquireLock(&peer->queueLock);
if(size) {
peer->queue.EnqueueObjects(id, size, Pair((uint8_t*)data, size));

Message* m;
if(peer->cache.Dequeue(m)){ // Check for a cached message allocaiton
m->size = size;
m->id = id;
memcpy(m->data, (uint8_t*)data, size);
} else {
peer->queue.EnqueueObjects(id, size);
m = AllocateMessage(); // Nothing left in cache, allocate a new message

m->size = size;
m->id = id;
memcpy(m->data, (uint8_t*)data, size);
}

peer->queue.Enqueue(m);

acquireLock(&peer->waitingLock);
while(peer->waiting.get_length() > 0){
peer->waiting.remove_at(0)->Signal();
Expand Down
9 changes: 0 additions & 9 deletions Scripts/build-nix/mount.sh

This file was deleted.

5 changes: 0 additions & 5 deletions Scripts/build-nix/unmount.sh

This file was deleted.

0 comments on commit 89f8045

Please sign in to comment.