tcp: Fix 64 bit build with debugging features enabled.
[haiku.git] / src / kits / media / ChunkCache.cpp
blob68de9df754a5adee10122b2f750c0034eafa394c
1 /*
2 * Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "ChunkCache.h"
9 #include <new>
10 #include <stdlib.h>
11 #include <string.h>
13 #include "debug.h"
15 // #pragma mark -
18 ChunkCache::ChunkCache(sem_id waitSem, size_t maxBytes)
20 BLocker("media chunk cache"),
21 fWaitSem(waitSem)
23 rtm_create_pool(&fRealTimePool, maxBytes, "media chunk cache");
24 fMaxBytes = rtm_available(fRealTimePool);
28 ChunkCache::~ChunkCache()
30 rtm_delete_pool(fRealTimePool);
34 status_t
35 ChunkCache::InitCheck() const
37 if (fRealTimePool == NULL)
38 return B_NO_MEMORY;
40 return B_OK;
44 void
45 ChunkCache::MakeEmpty()
47 ASSERT(IsLocked());
49 while (!fChunkCache.empty()) {
50 RecycleChunk(fChunkCache.front());
51 fChunkCache.pop();
54 release_sem(fWaitSem);
58 bool
59 ChunkCache::SpaceLeft() const
61 ASSERT(IsLocked());
63 if (fChunkCache.size() >= CACHE_MAX_ENTRIES) {
64 return false;
67 // If there is no more memory we are likely to fail soon after
68 return sizeof(chunk_buffer) + 2048 < rtm_available(fRealTimePool);
72 chunk_buffer*
73 ChunkCache::NextChunk(Reader* reader, void* cookie)
75 ASSERT(IsLocked());
77 chunk_buffer* chunk = NULL;
79 if (fChunkCache.empty()) {
80 TRACE("ChunkCache is empty, going direct to reader\n");
81 if (ReadNextChunk(reader, cookie)) {
82 return NextChunk(reader, cookie);
84 } else {
85 chunk = fChunkCache.front();
86 fChunkCache.pop();
88 release_sem(fWaitSem);
91 return chunk;
95 /* Moves the specified chunk to the unused list.
96 This means the chunk data can be overwritten again.
98 void
99 ChunkCache::RecycleChunk(chunk_buffer* chunk)
101 ASSERT(IsLocked());
103 rtm_free(chunk->buffer);
104 chunk->capacity = 0;
105 chunk->size = 0;
106 chunk->buffer = NULL;
107 fUnusedChunks.push_back(chunk);
111 bool
112 ChunkCache::ReadNextChunk(Reader* reader, void* cookie)
114 ASSERT(IsLocked());
116 // retrieve chunk buffer
117 chunk_buffer* chunk = NULL;
118 if (fUnusedChunks.empty()) {
119 // allocate a new one
120 chunk = (chunk_buffer*)rtm_alloc(fRealTimePool, sizeof(chunk_buffer));
121 if (chunk == NULL) {
122 ERROR("RTM Pool empty allocating chunk buffer structure");
123 return false;
126 chunk->size = 0;
127 chunk->capacity = 0;
128 chunk->buffer = NULL;
130 } else {
131 chunk = fUnusedChunks.front();
132 fUnusedChunks.pop_front();
135 const void* buffer;
136 size_t bufferSize;
137 chunk->status = reader->GetNextChunk(cookie, &buffer, &bufferSize,
138 &chunk->header);
139 if (chunk->status == B_OK) {
140 if (chunk->capacity < bufferSize) {
141 // adapt buffer size
142 rtm_free(chunk->buffer);
143 chunk->capacity = (bufferSize + 2047) & ~2047;
144 chunk->buffer = rtm_alloc(fRealTimePool, chunk->capacity);
145 if (chunk->buffer == NULL) {
146 rtm_free(chunk);
147 ERROR("RTM Pool empty allocating chunk buffer\n");
148 return false;
152 memcpy(chunk->buffer, buffer, bufferSize);
153 chunk->size = bufferSize;
156 fChunkCache.push(chunk);
157 return chunk->status == B_OK;