20 #include "pedigree/kernel/utilities/Buffer.h" 21 #include "pedigree/kernel/LockGuard.h" 22 #include "pedigree/kernel/utilities/utility.h" 25 #include "pedigree/kernel/process/Thread.h" 28 template <
class T,
bool allowShortOperation>
30 : m_BufferSize(bufferSize), m_DataSize(0), m_Lock(false),
31 m_WriteCondition(), m_ReadCondition(), m_Segments(), m_MonitorTargets(),
32 m_bCanRead(true), m_bCanWrite(true)
36 template <
class T,
bool allowShortOperation>
48 for (
auto pTarget : m_MonitorTargets)
51 if (pTarget->pSemaphore)
53 pTarget->pSemaphore->release();
58 m_MonitorTargets.clear();
62 template <
class T,
bool allowShortOperation>
68 if (!m_Lock.tryAcquire())
80 size_t countSoFar = 0;
91 size_t bytesAvailable = m_BufferSize - m_DataSize;
109 m_WriteCondition.wait(m_Lock);
110 if (result.hasError())
118 size_t totalCount = bytesAvailable;
119 if (totalCount > count)
126 if (allowShortOperation && (totalCount > bytesAvailable))
128 totalCount = bytesAvailable;
129 count = bytesAvailable;
137 bool copiedData =
false;
140 size_t numberCopied = 0;
141 if (totalCount >= m_SegmentSize)
144 addSegment(buffer, m_SegmentSize);
145 numberCopied = m_SegmentSize;
147 else if (!m_Segments.count())
150 addSegment(buffer, totalCount);
151 numberCopied = totalCount;
156 Segment *pSegment = m_Segments.popBack();
157 if (pSegment->
size == m_SegmentSize)
159 m_Segments.pushBack(pSegment);
162 addSegment(buffer, totalCount);
163 numberCopied = totalCount;
168 T *start = &pSegment->
data[pSegment->
size];
169 size_t availableSpace = m_SegmentSize - pSegment->
size;
170 if (availableSpace > totalCount)
172 availableSpace = totalCount;
174 pedigree_std::copy(start, buffer, availableSpace);
177 pSegment->
size += availableSpace;
180 m_Segments.pushBack(pSegment);
183 if (availableSpace < totalCount)
187 &buffer[availableSpace],
188 totalCount - availableSpace);
192 numberCopied = totalCount;
196 countSoFar += numberCopied;
197 m_DataSize += numberCopied;
198 buffer += numberCopied;
199 totalCount -= numberCopied;
200 count -= numberCopied;
204 copiedData = numberCopied > 0;
214 m_ReadCondition.signal();
235 template <
class T,
bool allowShortOperation>
240 if (!m_Lock.tryAcquire())
252 size_t countSoFar = 0;
280 if (result.hasError())
288 size_t totalCount = count;
289 if (totalCount > m_DataSize)
291 totalCount = m_DataSize;
294 size_t numberCopied = 0;
295 while (m_Segments.count() && numberCopied < totalCount)
298 Segment *pSegment = m_Segments.popFront();
299 size_t countToRead = pSegment->
size - pSegment->
reader;
300 if ((numberCopied + countToRead) > totalCount)
302 countToRead = totalCount - numberCopied;
307 buffer, &pSegment->
data[pSegment->
reader], countToRead);
308 pSegment->
reader += countToRead;
313 m_Segments.pushFront(pSegment);
320 numberCopied += countToRead;
321 buffer += countToRead;
324 m_DataSize -= numberCopied;
325 countSoFar += numberCopied;
326 count -= numberCopied;
333 m_WriteCondition.signal();
357 template <
class T,
bool allowShortOperation>
364 m_ReadCondition.broadcast();
367 template <
class T,
bool allowShortOperation>
374 m_WriteCondition.broadcast();
377 template <
class T,
bool allowShortOperation>
381 bool previous = m_bCanWrite;
386 template <
class T,
bool allowShortOperation>
390 bool previous = m_bCanRead;
395 template <
class T,
bool allowShortOperation>
402 template <
class T,
bool allowShortOperation>
408 template <
class T,
bool allowShortOperation>
413 return m_bCanWrite && (m_DataSize < m_BufferSize);
424 while (m_bCanWrite && m_DataSize >= m_BufferSize)
427 if (result.hasError())
436 template <
class T,
bool allowShortOperation>
441 return m_bCanRead && (m_DataSize > 0);
452 while (m_bCanRead && !m_DataSize)
455 if (result.hasError())
465 template <
class T,
bool allowShortOperation>
471 for (
auto pSegment : m_Segments)
479 m_WriteCondition.signal();
482 template <
class T,
bool allowShortOperation>
488 m_MonitorTargets.pushBack(pTarget);
492 template <
class T,
bool allowShortOperation>
498 m_MonitorTargets.pushBack(pTarget);
502 template <
class T,
bool allowShortOperation>
507 for (
auto it = m_MonitorTargets.begin(); it != m_MonitorTargets.end(); ++it)
511 if (pMT->pThread == pThread)
514 m_MonitorTargets.erase(it);
515 it = m_MonitorTargets.begin();
516 if (it == m_MonitorTargets.end())
523 template <
class T,
bool allowShortOperation>
528 for (
auto it = m_MonitorTargets.begin(); it != m_MonitorTargets.end();)
532 if (pMT->pSemaphore == pSemaphore)
535 it = m_MonitorTargets.erase(it);
545 template <
class T,
bool allowShortOperation>
550 for (
auto it = m_MonitorTargets.begin(); it != m_MonitorTargets.end();)
554 if (pMT->pEvent == pEvent)
557 it = m_MonitorTargets.erase(it);
567 template <
class T,
bool allowShortOperation>
573 it != m_MonitorTargets.end(); it++)
581 else if (pMT->pSemaphore)
587 m_MonitorTargets.clear();
591 template <
class T,
bool allowShortOperation>
596 pedigree_std::copy(pNewSegment->
data, buffer, count);
597 pNewSegment->
size = count;
598 m_Segments.pushBack(pNewSegment);
void addSegment(const T *buffer, size_t count)
void cullMonitorTargets(Thread *pThread)
void monitor(Thread *pThread, Event *pEvent)
bool canWrite(bool block)
size_t read(T *buffer, size_t count, bool block=true)
bool sendEvent(Event *pEvent)
::Iterator< T, node_t > Iterator
size_t write(const T *buffer, size_t count, bool block=true)