Improved AreaPool to have an initial size as well as well as a name that is

used for new area.
MemPool::AddToPool() now gracefully deals with NULL pointers (or a size of 0).
BitmapManager was deleting the area it transferred to AreaPool before - it
no longer needs an extra area, though.
Minor other cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13260 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2005-06-24 04:01:16 +00:00
parent b5436616a3
commit 0ec4af2233
6 changed files with 75 additions and 88 deletions

View File

@ -44,7 +44,6 @@ class BitmapManager {
void DeleteBitmap(ServerBitmap* bitmap);
protected:
BList fBitmapList;
area_id fBitmapArea;
int8* fBuffer;
TokenHandler fTokenizer;
BLocker fLock;

View File

@ -468,47 +468,44 @@ MemPool::ReleaseBuffer(void *buf)
// Add a region of memory to the buffer pool.
void
MemPool::AddToPool(void *buf, ssize_t len)
MemPool::AddToPool(void *buffer, ssize_t length)
{
struct bfhead *b = BFH(buf);
struct bhead *bn;
if (buffer == NULL || length <= 0)
return;
len &= ~(SizeQuant - 1);
length &= ~(SizeQuant - 1);
if (fPoolLength == 0)
{
fPoolLength = len;
}
else
if (len != fPoolLength)
{
if (fPoolLength == 0)
fPoolLength = length;
else if (length != fPoolLength)
fPoolLength = -1;
}
// Number of block acquisitions
fNumpget++;
// Number of blocks total
fNumpblk++;
assert(fNumpblk == fNumpget - fNumprel);
fNumpget++;
// Since the block is initially occupied by a single free buffer,
// it had better not be (much) larger than the largest buffer
// whose size we can store in bhead.bsize.
assert(len - sizeof(struct bhead) <= -((ssize_t) ESent + 1));
// Number of blocks total
fNumpblk++;
assert(fNumpblk == fNumpget - fNumprel);
// Clear the backpointer at the start of the block to indicate that
// there is no free block prior to this one. That blocks
// recombination when the first block in memory is released.
b->bh.prevfree = 0;
// Since the block is initially occupied by a single free buffer,
// it had better not be (much) larger than the largest buffer
// whose size we can store in bhead.bsize.
assert(length - sizeof(struct bhead) <= -((ssize_t) ESent + 1));
// Chain the new block to the free list.
assert(fFreeList.ql.blink->ql.flink == &fFreeList);
assert(fFreeList.ql.flink->ql.blink == &fFreeList);
b->ql.flink = &fFreeList;
b->ql.blink = fFreeList.ql.blink;
fFreeList.ql.blink = b;
b->ql.blink->ql.flink = b;
struct bfhead *b = BFH(buffer);
// Clear the backpointer at the start of the block to indicate that
// there is no free block prior to this one. That blocks
// recombination when the first block in memory is released.
b->bh.prevfree = 0;
// Chain the new block to the free list.
assert(fFreeList.ql.blink->ql.flink == &fFreeList);
assert(fFreeList.ql.flink->ql.blink == &fFreeList);
b->ql.flink = &fFreeList;
b->ql.blink = fFreeList.ql.blink;
fFreeList.ql.blink = b;
b->ql.blink->ql.flink = b;
// Create a dummy allocated buffer at the end of the pool. This dummy
// buffer is seen when a buffer at the end of the pool is released and
@ -518,14 +515,14 @@ MemPool::AddToPool(void *buf, ssize_t len)
// routines (this specific value is not counted on by the actual
// allocation and release functions).
len -= sizeof(struct bhead);
b->bh.bsize = (ssize_t) len;
length -= sizeof(struct bhead);
b->bh.bsize = length;
memset(((char *) b) + sizeof(struct bfhead), 0x55,(int) (len - sizeof(struct bfhead)));
memset(((char *)b) + sizeof(struct bfhead), 0x55, (int)(length - sizeof(struct bfhead)));
struct bhead *bn = BH(((char *) b) + length);
bn->prevfree = length;
bn = BH(((char *) b) + len);
bn->prevfree = (ssize_t) len;
// Definition of ESent assumes two's complement!
assert((~0) == -1);
bn->bsize = ESent;
@ -765,8 +762,12 @@ MemPool::ReleaseMem(void *buffer)
// #pragma mark -
AreaPool::AreaPool()
AreaPool::AreaPool(const char* name, size_t initialSize)
:
fName(name)
{
if (initialSize > 0)
AddToPool(AcquireMem(initialSize), initialSize);
}
@ -784,7 +785,7 @@ AreaPool::AcquireMem(ssize_t size)
// make size a multiple of B_PAGE_SIZE
size = (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
area = create_area("AreaPool_area", &address, B_ANY_ADDRESS, size,
area = create_area(fName, &address, B_ANY_ADDRESS, size,
B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
if (area < B_OK) {

View File

@ -1,13 +1,13 @@
/*
* Copyright 2001-2005, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
* Authors: John Walker <kelvin@fourmilab.ch>
* DarkWyrm <bpmagic@columbus.rr.com>
* Stephan Aßmus <superstippi@gmx.de>
*
* Authors:
* John Walker <kelvin@fourmilab.ch>
* DarkWyrm <bpmagic@columbus.rr.com>
* Stephan Aßmus <superstippi@gmx.de>
*
* BGET pool allocator
*
*/
#ifndef MEM_POOL_H
@ -93,12 +93,15 @@ class MemPool {
};
class AreaPool : public MemPool {
public:
AreaPool();
virtual ~AreaPool();
public:
AreaPool(const char* name, size_t initialSize = 0);
virtual ~AreaPool();
virtual void* AcquireMem(ssize_t size);
virtual void ReleaseMem(void* buffer);
virtual void* AcquireMem(ssize_t size);
virtual void ReleaseMem(void* buffer);
private:
const char* fName;
};
#endif

View File

@ -29,23 +29,13 @@ BitmapManager *gBitmapManager = NULL;
//! Sets up stuff to be ready to allocate space for bitmaps
BitmapManager::BitmapManager()
: fBitmapList(1024),
fBitmapArea(B_ERROR),
fBuffer(NULL),
fTokenizer(),
fLock("BitmapManager Lock"),
fMemPool()
:
fBitmapList(1024),
fBuffer(NULL),
fTokenizer(),
fLock("BitmapManager Lock"),
fMemPool("bitmap pool", BITMAP_AREA_SIZE)
{
// When create_area is passed the B_ANY_ADDRESS flag, the address of the area
// is stored in the pointer to a pointer.
fBitmapArea = create_area("bitmap_area", (void**)&fBuffer,
B_ANY_ADDRESS, BITMAP_AREA_SIZE,
B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
if (fBitmapArea < B_OK)
printf("PANIC: BitmapManager couldn't allocate area: %s\n", strerror(fBitmapArea));
fMemPool.AddToPool(fBuffer, BITMAP_AREA_SIZE);
}
//! Deallocates everything associated with the manager
@ -58,8 +48,6 @@ BitmapManager::~BitmapManager()
delete bitmap;
}
}
delete_area(fBitmapArea);
}
/*!
@ -93,12 +81,11 @@ BitmapManager::CreateBitmap(BRect bounds, color_space space, int32 flags,
bitmap->fBuffer = buffer;
bitmap->fToken = fTokenizer.GetToken();
bitmap->fInitialized = true;
// calculate area offset
area_info ai;
get_area_info(bitmap->fArea, &ai);
bitmap->fOffset = buffer - (uint8*)ai.address;
// calculate area offset
area_info info;
get_area_info(bitmap->fArea, &info);
bitmap->fOffset = buffer - (uint8*)info.address;
} else {
// Allocation failed for buffer or bitmap list
fMemPool.ReleaseBuffer(buffer);

View File

@ -91,7 +91,7 @@ ServerApp::ServerApp(port_id clientReplyPort, port_id clientLooperPort,
fCursorHidden(false),
fIsActive(false),
//fHandlerToken(handlerID),
fSharedMem(new AreaPool),
fSharedMem("shared memory"),
fQuitting(false)
{
if (fSignature == "")
@ -198,12 +198,8 @@ ServerApp::~ServerApp(void)
// there should be a way that this ServerApp be attached to a particular
// RootLayer to know which RootLayer's cursor to modify.
gDesktop->ActiveRootLayer()->GetCursorManager().RemoveAppCursors(fClientTeam);
STRACE(("#ServerApp %s:~ServerApp()\n", fSignature.String()));
delete fSharedMem;
STRACE(("ServerApp %s::~ServerApp(): Exiting\n", fSignature.String()));
STRACE(("ServerApp %s::~ServerApp(): Exiting\n", Signature()));
}
@ -587,7 +583,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// This is a very special case in the sense that when ServerMemIO is used for this
// purpose, it will be set to NOT automatically free the memory which it had
// requested. This is the server's job once the message has been dispatched.
fSharedMem->ReleaseBuffer(msgpointer);
fSharedMem.ReleaseBuffer(msgpointer);
break;
}
case AS_ACQUIRE_SERVERMEM:
@ -607,7 +603,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// TODO: I wonder if ACQUIRE_SERVERMEM should have a minimum size requirement?
void *sharedmem = fSharedMem->GetBuffer(memsize);
void *sharedmem = fSharedMem.GetBuffer(memsize);
if (memsize < 1 || sharedmem == NULL) {
fLink.StartMessage(SERVER_FALSE);
@ -653,7 +649,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
STRACE(("Successfully freed shared memory\n"));
void *sharedmem = ((int32*)areaInfo.address) + areaoffset;
fSharedMem->ReleaseBuffer(sharedmem);
fSharedMem.ReleaseBuffer(sharedmem);
break;
}

View File

@ -18,6 +18,7 @@
#include <PortLink.h>
#include "SubWindowList.h"
#include "BGet++.h"
class AreaPool;
class BMessage;
@ -72,7 +73,7 @@ public:
int32 CountPictures() const;
ServerPicture *FindPicture(int32 token) const;
AreaPool *AppAreaPool() { return fSharedMem; }
AreaPool *AppAreaPool() { return &fSharedMem; }
SubWindowList fAppSubWindowList;
@ -117,9 +118,9 @@ private:
// Used for BMessage target specification
// TODO: Is it still needed ? We aren't using it.
//int32 fHandlerToken;
AreaPool *fSharedMem;
AreaPool fSharedMem;
bool fQuitting;
};