From 5556dd55c72f3d631a40a3a2835ff9fb92e7c68e Mon Sep 17 00:00:00 2001 From: Ethereal Date: Mon, 21 Feb 2011 22:51:35 -0700 Subject: [PATCH] For zone sizes greater than one page, the wrapping appears to work correctly. At least, it is possible to send more than 50,000 packets of eight bytes each through the SHM. Personally, I would call that working . . . However, the reader seems to be hanging when the zone size is one page . . . --- .aesalon.conf | 4 +- modules/informer/src/collector/Informer.c | 62 ++++++++++++++++++++++--------- src/monitor/SHMReader.cpp | 30 ++++----------- 3 files changed, 54 insertions(+), 42 deletions(-) diff --git a/.aesalon.conf b/.aesalon.conf index 043511a..e26bf66 100644 --- a/.aesalon.conf +++ b/.aesalon.conf @@ -1,7 +1,7 @@ # Build configuration file for Aesalon. search "modules/"; -# Default zone size is 16KB. -zoneSize=4; +# Default zone size is 4KB. +zoneSize=1; # Allow a maximum of 32,768 zones. zoneUsePages=1; # By default, use only one zone reader (only one thread). diff --git a/modules/informer/src/collector/Informer.c b/modules/informer/src/collector/Informer.c index 10f0433..e2bfce0 100644 --- a/modules/informer/src/collector/Informer.c +++ b/modules/informer/src/collector/Informer.c @@ -144,31 +144,56 @@ static void *AI_SetupZone() { static void *AI_ReserveSpace(uint32_t size) { ZoneHeader *header = (ZoneHeader *)AI_Zone; uint32_t remaining; - if(header->head <= header->tail) { - remaining = ((AI_InformerData.shmHeader->zoneSize*AesalonPageSize) - ZoneDataOffset) - - (header->tail - header->head); - } - else { + /* Three cases for remaining check (and also below). + 1) head > tail (memory is in two chunks) + 2) head < tail (memory is in one chunk), tail+size >= zoneSize + 3) head < tail (memory is in one chunk), tail+size < zoneSize + */ + if(header->head > header->tail) { remaining = header->head - ZoneDataOffset - header->tail; } + else if(header->head <= header->tail + && (header->tail + size) < AI_InformerData.shmHeader->zoneSize*AesalonPageSize) { + + remaining = AI_InformerData.shmHeader->zoneSize*AesalonPageSize + - (header->tail - header->head) - ZoneDataOffset; + } + else if(header->head <= header->tail + && (header->tail + size) >= AI_InformerData.shmHeader->zoneSize*AesalonPageSize) { + + remaining = header->head - ZoneDataOffset; + } if(remaining < size) { header->overflow = size - remaining; sem_wait(&header->overflowSemaphore); } - /* If the head is less than (or equal to) the tail, then the used memory - is in one contiguous chunk, and the buffer has not wrapped yet. */ - if(header->head <= header->tail) { - printf("Increasing tail by %i\n", size); + if(header->head > header->tail) { + printf("Insertion case 1 . . .\n"); header->tail += size; - printf("New value: %i\n", header->tail); - return &AI_Zone[header->tail-size]; + return AI_Zone + header->tail - size; } - else { - printf("**** Second case, returning NULL.\n"); - return NULL; + else if(header->head <= header->tail + && (header->tail + size) < AI_InformerData.shmHeader->zoneSize*AesalonPageSize) { + + printf("Insertion case 2 . . .\n"); + + header->tail += size; + return AI_Zone + header->tail - size; + } + else if(header->head <= header->tail + && (header->tail + size) >= AI_InformerData.shmHeader->zoneSize*AesalonPageSize) { + + printf("Insertion case 3 . . .\n"); + + header->gapSize = AI_InformerData.shmHeader->zoneSize*AesalonPageSize - header->tail; + header->tail = ZoneDataOffset + size; + return AI_Zone + ZoneDataOffset; } + + printf("Something unforeseen occured. This should not have happened . . .\n"); + return NULL; } void __attribute__((constructor)) AI_Construct() { @@ -186,9 +211,12 @@ void __attribute__((constructor)) AI_Construct() { AI_ContinueCollection(self); - AI_StartPacket(16); - *(pid_t *)AI_PacketSpace(sizeof(pid_t)) = getpid(); - AI_EndPacket(); + ModuleID id = 0; + for(; ; id ++) { + usleep(100); + AI_StartPacket(id); + AI_EndPacket(); + } } void __attribute__((destructor)) AI_Destruct() { diff --git a/src/monitor/SHMReader.cpp b/src/monitor/SHMReader.cpp index 720b021..2704c37 100644 --- a/src/monitor/SHMReader.cpp +++ b/src/monitor/SHMReader.cpp @@ -69,17 +69,8 @@ int32_t SHMReader::zoneWithData() { SHM::ZoneHeader *zheader = reinterpret_cast(zone); - int value; - sem_getvalue(&zheader->packetSemaphore, &value); - Message(Debug, "Semaphore value: " << value); - if(sem_trywait(&zheader->packetSemaphore) == -1 && errno == EAGAIN) continue; - Message(Debug, "trywait on zone " << i << "'s packet semaphore succeeded."); - - sem_getvalue(&zheader->packetSemaphore, &value); - Message(Debug, "Semaphore value: " << value); - return i; } } @@ -95,31 +86,28 @@ void SHMReader::processRequest(ReadBroker &request) { SHM::ZoneHeader *header = reinterpret_cast(zone); - uint32_t start1 = header->head; + uint32_t start = header->head; uint32_t size1 = std::min( request.size(), - (m_header->zoneSize*AesalonPageSize - header->gapSize) - start1); + (m_header->zoneSize*AesalonPageSize - header->gapSize) - start); uint32_t size2 = request.size() - size1; - Message(Debug, "processRequest: sizes are " << size1 << " and " << size2); - Message(Debug, "\thead: " << header->head); - Message(Debug, "\ttail: " << header->tail); + Message(Debug, "Read start: " << start); + Message(Debug, "Read sizes: " << size1 << "/" << size2); /* The difficult case; the data is in two segments. */ if(size2 > 0) { request.resizeBuffer(request.size()); - memcpy(request.temporaryBuffer(), zone + start1, size1); + memcpy(request.temporaryBuffer(), zone + start, size1); memcpy(request.temporaryBuffer() + size1, zone + ZoneDataOffset, size2); header->gapSize = 0; request.setData(request.temporaryBuffer()); - header->head = size2; + header->head = size2 + ZoneDataOffset; } /* Otherwise, the simple case. */ else { - Message(Debug, "Simple case detected."); - Message(Debug, "\toffset: " << start1); - request.setData(zone + start1); + request.setData(zone + start); header->head += size1; } } @@ -129,10 +117,6 @@ uint8_t *SHMReader::getZone(uint32_t id) { return m_zoneList[id]; } - Message(Debug, - "Zone start/size: " << m_header->zonePageOffset + id*m_header->zoneSize << "/" << m_header->zoneSize); - Message(Debug, "ZoneDataOffset: " << ZoneDataOffset); - uint8_t *zone = static_cast(mapRegion(m_header->zonePageOffset + id*m_header->zoneSize, m_header->zoneSize)); -- 2.11.4.GIT