2 * Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
7 #include "ChunkCache.h"
18 ChunkCache::ChunkCache(sem_id waitSem
, size_t maxBytes
)
20 BLocker("media chunk cache"),
23 rtm_create_pool(&fRealTimePool
, maxBytes
, "media chunk cache");
24 fMaxBytes
= rtm_available(fRealTimePool
);
28 ChunkCache::~ChunkCache()
30 rtm_delete_pool(fRealTimePool
);
35 ChunkCache::InitCheck() const
37 if (fRealTimePool
== NULL
)
45 ChunkCache::MakeEmpty()
49 while (!fChunkCache
.empty()) {
50 RecycleChunk(fChunkCache
.front());
54 release_sem(fWaitSem
);
59 ChunkCache::SpaceLeft() const
63 if (fChunkCache
.size() >= CACHE_MAX_ENTRIES
) {
67 // If there is no more memory we are likely to fail soon after
68 return sizeof(chunk_buffer
) + 2048 < rtm_available(fRealTimePool
);
73 ChunkCache::NextChunk(Reader
* reader
, void* cookie
)
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
);
85 chunk
= fChunkCache
.front();
88 release_sem(fWaitSem
);
95 /* Moves the specified chunk to the unused list.
96 This means the chunk data can be overwritten again.
99 ChunkCache::RecycleChunk(chunk_buffer
* chunk
)
103 rtm_free(chunk
->buffer
);
106 chunk
->buffer
= NULL
;
107 fUnusedChunks
.push_back(chunk
);
112 ChunkCache::ReadNextChunk(Reader
* reader
, void* cookie
)
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
));
122 ERROR("RTM Pool empty allocating chunk buffer structure");
128 chunk
->buffer
= NULL
;
131 chunk
= fUnusedChunks
.front();
132 fUnusedChunks
.pop_front();
137 chunk
->status
= reader
->GetNextChunk(cookie
, &buffer
, &bufferSize
,
139 if (chunk
->status
== B_OK
) {
140 if (chunk
->capacity
< bufferSize
) {
142 rtm_free(chunk
->buffer
);
143 chunk
->capacity
= (bufferSize
+ 2047) & ~2047;
144 chunk
->buffer
= rtm_alloc(fRealTimePool
, chunk
->capacity
);
145 if (chunk
->buffer
== NULL
) {
147 ERROR("RTM Pool empty allocating chunk buffer\n");
152 memcpy(chunk
->buffer
, buffer
, bufferSize
);
153 chunk
->size
= bufferSize
;
156 fChunkCache
.push(chunk
);
157 return chunk
->status
== B_OK
;