* Cleanup, BufferManager now aggregates the buffer map as well as its locker

instead of allocating them separately, no functional change.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32153 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-08-06 08:55:02 +00:00
parent 86766d6aca
commit 696b8f43fb
3 changed files with 136 additions and 110 deletions
+96 -78
View File
@@ -2,167 +2,185 @@
* Copyright 2002, Marcus Overhagen. All rights reserved. * Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include <MediaDefs.h>
#include <Autolock.h>
#include "BufferManager.h" #include "BufferManager.h"
#include "SharedBufferList.h"
#include <Autolock.h>
#include "debug.h" #include "debug.h"
#include "SharedBufferList.h"
BufferManager::BufferManager() BufferManager::BufferManager()
: fSharedBufferList(_shared_buffer_list::Clone()), :
fNextBufferId(1), fSharedBufferList(_shared_buffer_list::Clone()),
fLocker(new BLocker("buffer manager locker")), fNextBufferID(1),
fBufferInfoMap(new Map<media_buffer_id, buffer_info>) fLocker("buffer manager locker")
{ {
fSharedBufferListId = area_for(fSharedBufferList); fSharedBufferListID = area_for(fSharedBufferList);
ASSERT(fSharedBufferList!=NULL);
ASSERT(fSharedBufferListId > 0);
} }
BufferManager::~BufferManager() BufferManager::~BufferManager()
{ {
fSharedBufferList->Unmap(); fSharedBufferList->Unmap();
delete fLocker;
delete fBufferInfoMap;
} }
area_id area_id
BufferManager::SharedBufferListID() BufferManager::SharedBufferListID()
{ {
return fSharedBufferListId; return fSharedBufferListID;
} }
status_t status_t
BufferManager::RegisterBuffer(team_id teamid, media_buffer_id bufferid, BufferManager::RegisterBuffer(team_id team, media_buffer_id bufferID,
size_t *size, int32 *flags, size_t *offset, area_id *area) size_t* _size, int32* _flags, size_t* _offset, area_id* _area)
{ {
BAutolock lock(fLocker); BAutolock lock(fLocker);
TRACE("RegisterBuffer team = %ld, bufferid = %ld\n", teamid, bufferid); TRACE("RegisterBuffer team = %ld, bufferid = %ld\n", team, bufferID);
buffer_info *info; buffer_info* info;
if (!fBufferInfoMap->Get(bufferid, &info)) { if (!fBufferInfoMap.Get(bufferID, &info)) {
ERROR("failed to register buffer! team = %ld, bufferid = %ld\n", teamid, bufferid); ERROR("failed to register buffer! team = %ld, bufferid = %ld\n", team,
bufferID);
return B_ERROR; return B_ERROR;
} }
info->teams.Insert(teamid); info->teams.Insert(team);
*area = info->area; *_area = info->area;
*offset = info->offset; *_offset = info->offset;
*size = info->size, *_size = info->size,
*flags = info->flags; *_flags = info->flags;
return B_OK; return B_OK;
} }
status_t status_t
BufferManager::RegisterBuffer(team_id teamid, size_t size, int32 flags, size_t offset, area_id area, BufferManager::RegisterBuffer(team_id team, size_t size, int32 flags,
media_buffer_id *bufferid) size_t offset, area_id area, media_buffer_id* _bufferID)
{ {
BAutolock lock(fLocker); BAutolock lock(fLocker);
TRACE("RegisterBuffer team = %ld, areaid = %ld, offset = %ld, size = %ld\n", teamid, area, offset, size); TRACE("RegisterBuffer team = %ld, area = %ld, offset = %ld, size = %ld\n",
team, area, offset, size);
void *adr; void* address;
area_id newarea; area_id clonedArea = clone_area("media_server cloned buffer", &address,
B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);
newarea = clone_area("media_server cloned buffer", &adr, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, area); if (clonedArea < 0) {
if (newarea <= B_OK) { ERROR("RegisterBuffer: failed to clone buffer! error = %#lx, team = "
ERROR("RegisterBuffer: failed to clone buffer! error = %#lx, team = %ld, areaid = %ld, offset = %ld, size = %ld\n", newarea, teamid, area, offset, size); "%ld, areaid = %ld, offset = %ld, size = %ld\n", clonedArea, team,
area, offset, size);
return B_ERROR; return B_ERROR;
} }
buffer_info info; buffer_info info;
info.id = fNextBufferID++;
*bufferid = fNextBufferId; info.area = clonedArea;
info.id = fNextBufferId;
info.area = newarea;
info.offset = offset; info.offset = offset;
info.size = size; info.size = size;
info.flags = flags; info.flags = flags;
info.teams.Insert(teamid); info.teams.Insert(team);
fBufferInfoMap->Insert(fNextBufferId, info);
TRACE("RegisterBuffer: done, bufferid = %ld\n", fNextBufferId); *_bufferID = info.id;
fBufferInfoMap.Insert(info.id, info);
TRACE("RegisterBuffer: done, bufferID = %ld\n", info.id);
fNextBufferId += 1;
return B_OK; return B_OK;
} }
status_t status_t
BufferManager::UnregisterBuffer(team_id teamid, media_buffer_id bufferid) BufferManager::UnregisterBuffer(team_id team, media_buffer_id bufferID)
{ {
BAutolock lock(fLocker); BAutolock lock(fLocker);
TRACE("UnregisterBuffer: team = %ld, bufferid = %ld\n", teamid, bufferid); TRACE("UnregisterBuffer: team = %ld, bufferid = %ld\n", team, bufferID);
buffer_info *info; buffer_info* info;
int index; if (!fBufferInfoMap.Get(bufferID, &info)) {
ERROR("UnregisterBuffer: failed to unregister buffer! team = %ld, "
if (!fBufferInfoMap->Get(bufferid, &info)) { "bufferid = %ld\n", team, bufferID);
ERROR("UnregisterBuffer: failed to unregister buffer! team = %ld, bufferid = %ld\n", teamid, bufferid);
return B_ERROR; return B_ERROR;
} }
index = info->teams.Find(teamid); int index = info->teams.Find(team);
if (index < 0) { if (index < 0) {
ERROR("UnregisterBuffer: failed to find team = %ld belonging to bufferid = %ld\n", teamid, bufferid); ERROR("UnregisterBuffer: failed to find team = %ld belonging to "
"bufferID = %ld\n", team, bufferID);
return B_ERROR; return B_ERROR;
} }
if (!info->teams.Remove(index)) { if (!info->teams.Remove(index)) {
ERROR("UnregisterBuffer: failed to remove team = %ld from bufferid = %ld\n", teamid, bufferid); ERROR("UnregisterBuffer: failed to remove team = %ld from bufferID "
"= %ld\n", team, bufferID);
return B_ERROR; return B_ERROR;
} }
TRACE("UnregisterBuffer: team = %ld removed from bufferid = %ld\n", teamid, bufferid);
TRACE("UnregisterBuffer: team = %ld removed from bufferID = %ld\n", team,
bufferID);
if (info->teams.IsEmpty()) { if (info->teams.IsEmpty()) {
if (!fBufferInfoMap.Remove(bufferID)) {
if (!fBufferInfoMap->Remove(bufferid)) { ERROR("UnregisterBuffer: failed to remove bufferID = %ld\n",
ERROR("UnregisterBuffer: failed to remove bufferid = %ld\n", bufferid); bufferID);
return B_ERROR; return B_ERROR;
} }
TRACE("UnregisterBuffer: bufferid = %ld removed\n", bufferid); TRACE("UnregisterBuffer: bufferID = %ld removed\n", bufferID);
} }
return B_OK; return B_OK;
} }
void void
BufferManager::CleanupTeam(team_id team) BufferManager::CleanupTeam(team_id team)
{ {
BAutolock lock(fLocker); BAutolock lock(fLocker);
buffer_info *info;
TRACE("BufferManager::CleanupTeam: team %ld\n", team); TRACE("BufferManager::CleanupTeam: team %ld\n", team);
for (fBufferInfoMap->Rewind(); fBufferInfoMap->GetNext(&info); ) { buffer_info* info;
team_id *otherteam; for (fBufferInfoMap.Rewind(); fBufferInfoMap.GetNext(&info); ) {
for (info->teams.Rewind(); info->teams.GetNext(&otherteam); ) { team_id* currentTeam;
if (team == *otherteam) { for (info->teams.Rewind(); info->teams.GetNext(&currentTeam); ) {
PRINT(1, "BufferManager::CleanupTeam: removing team %ld from buffer id %ld\n", team, info->id); if (team == *currentTeam) {
PRINT(1, "BufferManager::CleanupTeam: removing team %ld from "
"buffer id %ld\n", team, info->id);
info->teams.RemoveCurrent(); info->teams.RemoveCurrent();
} }
} }
if (info->teams.IsEmpty()) { if (info->teams.IsEmpty()) {
PRINT(1, "BufferManager::CleanupTeam: removing buffer id %ld that has no teams\n", info->id); PRINT(1, "BufferManager::CleanupTeam: removing buffer id %ld that "
fBufferInfoMap->RemoveCurrent(); "has no teams\n", info->id);
fBufferInfoMap.RemoveCurrent();
} }
} }
} }
void void
BufferManager::Dump() BufferManager::Dump()
{ {
BAutolock lock(fLocker); BAutolock lock(fLocker);
buffer_info *info;
printf("\n"); printf("\n");
printf("BufferManager: list of buffers follows:\n"); printf("BufferManager: list of buffers follows:\n");
for (fBufferInfoMap->Rewind(); fBufferInfoMap->GetNext(&info); ) {
printf(" buffer-id %ld, area-id %ld, offset %ld, size %ld, flags %#08lx\n", buffer_info *info;
info->id, info->area, info->offset, info->size, info->flags); for (fBufferInfoMap.Rewind(); fBufferInfoMap.GetNext(&info); ) {
printf(" buffer-id %ld, area-id %ld, offset %ld, size %ld, flags "
"%#08lx\n", info->id, info->area, info->offset, info->size,
info->flags);
printf(" assigned teams: "); printf(" assigned teams: ");
team_id *team;
team_id* team;
for (info->teams.Rewind(); info->teams.GetNext(&team); ) { for (info->teams.Rewind(); info->teams.GetNext(&team); ) {
printf("%ld, ", *team); printf("%ld, ", *team);
} }
+36 -28
View File
@@ -2,46 +2,54 @@
* Copyright 2002, Marcus Overhagen. All rights reserved. * Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
struct _shared_buffer_list;
#include <Locker.h>
#include <MediaDefs.h>
#include <TMap.h> #include <TMap.h>
#include <TList.h> #include <TList.h>
class BufferManager
{ struct _shared_buffer_list;
class BufferManager {
public: public:
BufferManager(); BufferManager();
~BufferManager(); ~BufferManager();
area_id SharedBufferListID(); area_id SharedBufferListID();
status_t RegisterBuffer(team_id teamid, media_buffer_id bufferid, status_t RegisterBuffer(team_id team,
size_t *size, int32 *flags, size_t *offset, area_id *area); media_buffer_id bufferID, size_t* _size,
int32* _flags, size_t* _offset, area_id* _area);
status_t RegisterBuffer(team_id teamid, size_t size, int32 flags, size_t offset, area_id area, status_t RegisterBuffer(team_id team, size_t size,
media_buffer_id *bufferid); int32 flags, size_t offset, area_id area,
media_buffer_id* _bufferID);
status_t UnregisterBuffer(team_id teamid, media_buffer_id bufferid); status_t UnregisterBuffer(team_id team,
media_buffer_id bufferID);
void CleanupTeam(team_id teamid);
void Dump(); void CleanupTeam(team_id team);
void Dump();
private: private:
struct buffer_info struct buffer_info {
{ media_buffer_id id;
media_buffer_id id; area_id area;
area_id area; size_t offset;
size_t offset; size_t size;
size_t size; int32 flags;
int32 flags; List<team_id> teams;
List<team_id> teams;
}; };
_shared_buffer_list * fSharedBufferList; _shared_buffer_list* fSharedBufferList;
area_id fSharedBufferListId; area_id fSharedBufferListID;
media_buffer_id fNextBufferId; media_buffer_id fNextBufferID;
BLocker * fLocker; BLocker fLocker;
Map<media_buffer_id, buffer_info> *fBufferInfoMap; Map<media_buffer_id, buffer_info> fBufferInfoMap;
}; };
+4 -4
View File
@@ -708,7 +708,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
request->info.offset, request->info.area, request->info.offset, request->info.area,
&reply.info.buffer); &reply.info.buffer);
} else { } else {
reply.info = request->info; //buffer id is kept reply.info = request->info; // buffer id is kept
status = gBufferManager->RegisterBuffer(request->team, status = gBufferManager->RegisterBuffer(request->team,
request->info.buffer, &reply.info.size, &reply.info.flags, request->info.buffer, &reply.info.size, &reply.info.flags,
&reply.info.offset, &reply.info.area); &reply.info.offset, &reply.info.area);
@@ -720,7 +720,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
case SERVER_UNREGISTER_BUFFER: case SERVER_UNREGISTER_BUFFER:
{ {
const server_unregister_buffer_command *cmd = reinterpret_cast< const server_unregister_buffer_command *cmd = reinterpret_cast<
const server_unregister_buffer_command *>(data); const server_unregister_buffer_command *>(data);
gBufferManager->UnregisterBuffer(cmd->team, cmd->bufferid); gBufferManager->UnregisterBuffer(cmd->team, cmd->bufferid);
break; break;
@@ -736,7 +736,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
rv = gMMediaFilesManager->RewindTypes( rv = gMMediaFilesManager->RewindTypes(
&types, &reply.count); &types, &reply.count);
if(reply.count>0) { if (reply.count > 0) {
// we create an area here, and pass it to the library, // we create an area here, and pass it to the library,
// where it will be deleted. // where it will be deleted.
char *start_addr; char *start_addr;
@@ -780,7 +780,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
&items, &reply.count); &items, &reply.count);
// we create an area here, and pass it to the library, // we create an area here, and pass it to the library,
// where it will be deleted. // where it will be deleted.
if(reply.count>0) { if (reply.count > 0) {
char *start_addr; char *start_addr;
size_t size = ((reply.count * B_MEDIA_NAME_LENGTH) size_t size = ((reply.count * B_MEDIA_NAME_LENGTH)
+ B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);