diff --git a/kernel/src/Ipc/Ipc.cpp b/kernel/src/Ipc/Ipc.cpp index ff16866..ea4a7f5 100644 --- a/kernel/src/Ipc/Ipc.cpp +++ b/kernel/src/Ipc/Ipc.cpp @@ -134,6 +134,7 @@ namespace Ipc { } static HandleEntry g_handleTables[Sched::MaxProcesses][MaxHandlesPerProcess] = {}; + static uint64_t g_handleBitmaps[Sched::MaxProcesses][2] = {}; // 128-bit bitmap per process static SurfaceMap g_surfaceMaps[Sched::MaxProcesses][MaxSurfaceMapsPerProcess] = {}; static Stream g_streams[MaxStreams] = {}; @@ -331,15 +332,18 @@ namespace Ipc { } UdpDgramHeader hdr = {srcIp, srcPort, length}; - const uint8_t* hdrBytes = (const uint8_t*)&hdr; - for (uint32_t j = 0; j < sizeof(UdpDgramHeader); j++) { - g_sockets[i].udpRing[g_sockets[i].udpTail] = hdrBytes[j]; - g_sockets[i].udpTail = (g_sockets[i].udpTail + 1) % UdpRingSize; - } - for (uint16_t j = 0; j < length; j++) { - g_sockets[i].udpRing[g_sockets[i].udpTail] = data[j]; - g_sockets[i].udpTail = (g_sockets[i].udpTail + 1) % UdpRingSize; - } + uint32_t tail = g_sockets[i].udpTail; + uint32_t hdrLen = sizeof(UdpDgramHeader); + uint32_t first = (tail + hdrLen <= UdpRingSize) ? hdrLen : (UdpRingSize - tail); + memcpy(g_sockets[i].udpRing + tail, (const uint8_t*)&hdr, first); + if (first < hdrLen) memcpy(g_sockets[i].udpRing, ((const uint8_t*)&hdr) + first, hdrLen - first); + tail = (tail + hdrLen) % UdpRingSize; + + // Write data payload + uint32_t second = (tail + length <= UdpRingSize) ? length : (UdpRingSize - tail); + memcpy(g_sockets[i].udpRing + tail, data, second); + if (second < length) memcpy(g_sockets[i].udpRing, data + second, length - second); + g_sockets[i].udpTail = (tail + length) % UdpRingSize; g_sockets[i].udpCount += needed; g_sockets[i].socketLock.Release(); @@ -467,8 +471,23 @@ namespace Ipc { int InstallHandleForSlot(int slot, Object* object, HandleType type, uint32_t rights) { if (slot < 0 || slot >= Sched::MaxProcesses || object == nullptr) return -1; - for (int i = 0; i < MaxHandlesPerProcess; i++) { - if (g_handleTables[slot][i].used) continue; + uint64_t& bm0 = g_handleBitmaps[slot][0]; + uint64_t& bm1 = g_handleBitmaps[slot][1]; + // Find first zero bit in bitmap (free slot) + uint64_t bits0 = ~bm0; + uint64_t bits1 = ~bm1; + if (bits0) { + int i = __builtin_ctzll(bits0); + bm0 |= (1ULL << i); + g_handleTables[slot][i].used = true; + g_handleTables[slot][i].rights = rights; + g_handleTables[slot][i].type = type; + g_handleTables[slot][i].object = object; + RetainForHandle(object, type, rights); + return i; + } else if (bits1) { + int i = 64 + __builtin_ctzll(bits1); + bm1 |= (1ULL << (i - 64)); g_handleTables[slot][i].used = true; g_handleTables[slot][i].rights = rights; g_handleTables[slot][i].type = type; @@ -503,6 +522,10 @@ namespace Ipc { g_handleTables[slot][handle].type = HandleType::None; g_handleTables[slot][handle].object = nullptr; + // Clear bitmap bit + if (handle < 64) g_handleBitmaps[slot][0] &= ~(1ULL << handle); + else g_handleBitmaps[slot][1] &= ~(1ULL << (handle - 64)); + ReleaseForHandle(entry.object, entry.type, entry.rights); return 0; } @@ -606,11 +629,29 @@ namespace Ipc { } int count = 0; - while (count < maxLen && stream->count > 0) { - out[count++] = stream->buffer[stream->tail]; - stream->tail = (stream->tail + 1) % stream->capacity; - stream->count--; + uint32_t tail = stream->tail; + uint32_t cap = stream->capacity; + // Copy contiguous tail → end + int first = (stream->count < (size_t)(cap - tail)) ? stream->count : (cap - tail); + if (first > maxLen) first = maxLen; + if (first > 0) { + memcpy(out, stream->buffer + tail, first); + tail = (tail + first) % cap; + stream->count -= first; + count = first; } + // Copy remainder (wrapped) if needed and space permits + if (count < maxLen && stream->count > 0) { + int second = stream->count; + if (second > maxLen - count) second = maxLen - count; + if (second > 0) { + memcpy(out + count, stream->buffer + tail, second); + tail = (tail + second) % cap; + stream->count -= second; + count += second; + } + } + stream->tail = tail; stream->lock.Release(); NotifyObjectChanged((Object*)stream); @@ -627,11 +668,27 @@ namespace Ipc { } int written = 0; - while (written < len && stream->count < stream->capacity) { - stream->buffer[stream->head] = data[written++]; - stream->head = (stream->head + 1) % stream->capacity; - stream->count++; + uint32_t head = stream->head; + uint32_t cap = stream->capacity; + uint32_t space = cap - stream->count; + int first = ((uint32_t)len < space) ? ((head + (uint32_t)len <= cap) ? len : (cap - head)) : (cap - head); + if (first > 0) { + memcpy(stream->buffer + head, data, first); + head = (head + first) % cap; + stream->count += first; + written = first; } + if (written < len && stream->count < cap) { + int second = len - written; + if (second > (int)(cap - stream->count)) second = cap - stream->count; + if (second > 0) { + memcpy(stream->buffer + head, data + written, second); + head = (head + second) % cap; + stream->count += second; + written += second; + } + } + stream->head = head; stream->lock.Release(); if (written > 0) NotifyObjectChanged((Object*)stream); @@ -1227,22 +1284,22 @@ namespace Ipc { } UdpDgramHeader hdr = {}; - uint8_t* hdrBytes = (uint8_t*)&hdr; - for (uint32_t j = 0; j < sizeof(UdpDgramHeader); j++) { - hdrBytes[j] = socket->udpRing[socket->udpHead]; - socket->udpHead = (socket->udpHead + 1) % UdpRingSize; - } - socket->udpCount -= sizeof(UdpDgramHeader); + uint32_t head = socket->udpHead; + uint32_t hdrLen = sizeof(UdpDgramHeader); + uint32_t hfirst = (head + hdrLen <= UdpRingSize) ? hdrLen : (UdpRingSize - head); + memcpy(&hdr, socket->udpRing + head, hfirst); + if (hfirst < hdrLen) memcpy(((uint8_t*)&hdr) + hfirst, socket->udpRing, hdrLen - hfirst); + socket->udpHead = (head + hdrLen) % UdpRingSize; + socket->udpCount -= hdrLen; uint16_t copyLen = hdr.dataLen; if (copyLen > maxLen) copyLen = (uint16_t)maxLen; - for (uint16_t j = 0; j < copyLen; j++) { - buffer[j] = socket->udpRing[socket->udpHead]; - socket->udpHead = (socket->udpHead + 1) % UdpRingSize; - } - for (uint16_t j = copyLen; j < hdr.dataLen; j++) { - socket->udpHead = (socket->udpHead + 1) % UdpRingSize; - } + uint32_t dataHead = socket->udpHead; + uint32_t cfirst = (dataHead + copyLen <= UdpRingSize) ? copyLen : (UdpRingSize - dataHead); + memcpy(buffer, socket->udpRing + dataHead, cfirst); + if (cfirst < copyLen) memcpy(buffer + cfirst, socket->udpRing, copyLen - cfirst); + dataHead = (dataHead + hdr.dataLen) % UdpRingSize; + socket->udpHead = dataHead; socket->udpCount -= hdr.dataLen; socket->socketLock.Release(); diff --git a/programs/lib/libc/libc.c b/programs/lib/libc/libc.c index c392a25..0570e14 100644 --- a/programs/lib/libc/libc.c +++ b/programs/lib/libc/libc.c @@ -417,9 +417,9 @@ void *memchr(const void *s, int c, size_t n) { } size_t strlen(const char *s) { - size_t len = 0; - while (s[len]) len++; - return len; + const char *p = s; + while (*p) p++; + return p - s; } size_t strspn(const char *s, const char *accept) { @@ -441,8 +441,9 @@ size_t strcspn(const char *s, const char *reject) { } int strcmp(const char *a, const char *b) { - while (*a && *a == *b) { a++; b++; } - return (unsigned char)*a - (unsigned char)*b; + const char *pa = a, *pb = b; + while (*pa && *pa == *pb) { pa++; pb++; } + return (unsigned char)*pa - (unsigned char)*pb; } int strncmp(const char *a, const char *b, size_t n) { diff --git a/programs/lib/libc/obj/libc.o b/programs/lib/libc/obj/libc.o index 5b2a55f..866158a 100644 Binary files a/programs/lib/libc/obj/libc.o and b/programs/lib/libc/obj/libc.o differ