diff --git a/Kernel/include/objects/message.h b/Kernel/include/objects/message.h index 3061ac24..7e4c9d16 100644 --- a/Kernel/include/objects/message.h +++ b/Kernel/include/objects/message.h @@ -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) } @@ -101,6 +105,18 @@ 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(m); + } + friend Pair,FancyRefPtr> CreatePair(); uint16_t maxMessageSize = 8; uint16_t messageQueueLimit = 128; @@ -108,7 +124,8 @@ class MessageEndpoint final : public KernelObject{ Semaphore queueAvailablilitySemaphore = Semaphore(messageQueueLimit); - RawRingBuffer queue; + RingBuffer queue; + RingBuffer cache; FancyRefPtr peer; diff --git a/Kernel/include/ringbuffer.h b/Kernel/include/ringbuffer.h index 4f208bd4..dd0e390b 100644 --- a/Kernel/include/ringbuffer.h +++ b/Kernel/include/ringbuffer.h @@ -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); @@ -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 } @@ -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); @@ -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); } diff --git a/Kernel/src/arch/x86_64/syscalls.cpp b/Kernel/src/arch/x86_64/syscalls.cpp index ec112e6f..604766c4 100755 --- a/Kernel/src/arch/x86_64/syscalls.cpp +++ b/Kernel/src/arch/x86_64/syscalls.cpp @@ -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){ diff --git a/Kernel/src/objects/message.cpp b/Kernel/src/objects/message.cpp index 1d5f2323..8f93f141 100644 --- a/Kernel/src/objects/message.cpp +++ b/Kernel/src/objects/message.cpp @@ -44,23 +44,16 @@ int64_t MessageEndpoint::Read(uint64_t* id, uint16_t* size, uint8_t* data){ acquireLock(&queueLock); - queue.Dequeue(reinterpret_cast(id), sizeof(uint64_t)); - queue.Dequeue(reinterpret_cast(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); @@ -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(); diff --git a/Scripts/build-nix/mount.sh b/Scripts/build-nix/mount.sh deleted file mode 100755 index 5591d327..00000000 --- a/Scripts/build-nix/mount.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -set -e 1 - -sudo mkdir /mnt/Lemon - -LOOPBACK_DEVICE=$(losetup --find --partscan --show Disks/Lemon.img) - -sudo mount ${LOOPBACK_DEVICE}p2 /mnt/Lemon \ No newline at end of file diff --git a/Scripts/build-nix/unmount.sh b/Scripts/build-nix/unmount.sh deleted file mode 100755 index 7e580714..00000000 --- a/Scripts/build-nix/unmount.sh +++ /dev/null @@ -1,5 +0,0 @@ - #!/bin/bash - -sudo umount /mnt/Lemon -sudo rm -rf /mnt/Lemon -sudo qemu-nbd -d /dev/nbd0