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:
parent
b5436616a3
commit
0ec4af2233
@ -44,7 +44,6 @@ class BitmapManager {
|
||||
void DeleteBitmap(ServerBitmap* bitmap);
|
||||
protected:
|
||||
BList fBitmapList;
|
||||
area_id fBitmapArea;
|
||||
int8* fBuffer;
|
||||
TokenHandler fTokenizer;
|
||||
BLocker fLock;
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user