haiku/src/servers/app/RegionPool.cpp
Stephan Aßmus 39c9925fcf * implemented a BRegion pool per WindowLayer which is supposed
to cut down on BRegion related allocations, cannot really tell
  if it speeds things up
* used the new BRegion pool in WindowLayer and ViewLayer whereever
  a BRegion was used on the stack
* fixed the debugging stuff in MultiLocker - it will get you into
  the debugger if you
    - try to nest read locks
    - try to write lock when your are a reader already
    - don't match up nested locks when your a writer
    -> but only if you #define DEBUG 1 in the .cpp, is off by default now
* went over WindowLayer, ServerWindow, Desktop and a few other places
  and fixed the locking for use with the MultiLocker, the "a reader can
  not become a writer" is especially tricky, feel free to review the
  changes
* activated the MultiLocker, I tested this quite a bit, if there are
  problems simply turn on DEBUG and you should drop into the debugger
  right where the problem is... hope all is good


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17046 a95241bf-73f2-0310-859d-f6bbb57e9c96
2006-04-07 19:14:25 +00:00

104 lines
1.7 KiB
C++

/*
* Copyright (c) 2006, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "RegionPool.h"
#include <new>
#include <stdio.h>
#if DEBUG_LEAK
#include <debugger.h>
#endif
#include <Region.h>
using std::nothrow;
RegionPool::RegionPool()
: fAvailable(4)
#if DEBUG_LEAK
,fUsed(4)
#endif
{
}
RegionPool::~RegionPool()
{
#if DEBUG_LEAK
if (fUsed.CountItems() > 0)
debugger("RegionPool::~RegionPool() - some regions still in use!");
#endif
int32 count = fAvailable.CountItems();
for (int32 i = 0; i < count; i++)
delete (BRegion*)fAvailable.ItemAtFast(i);
}
BRegion*
RegionPool::GetRegion()
{
BRegion* region = (BRegion*)fAvailable.RemoveItem(
fAvailable.CountItems() - 1);
if (!region) {
region = new (nothrow) BRegion();
if (!region) {
// whoa
fprintf(stderr, "RegionPool::GetRegion() - "
"no memory!\n");
}
}
#if DEBUG_LEAK
fUsed.AddItem(region);
#endif
return region;
}
BRegion*
RegionPool::GetRegion(const BRegion& other)
{
BRegion* region;
int32 count = fAvailable.CountItems();
if (count > 0) {
region = (BRegion*)fAvailable.RemoveItem(count - 1);
*region = other;
} else {
region = new (nothrow) BRegion(other);
if (!region) {
// whoa
fprintf(stderr, "RegionPool::GetRegion() - "
"no memory!\n");
}
}
#if DEBUG_LEAK
fUsed.AddItem(region);
#endif
return region;
}
void
RegionPool::Recycle(BRegion* region)
{
if (!fAvailable.AddItem(region)) {
// at least don't leak the region...
fprintf(stderr, "RegionPool::Recycle() - "
"no memory!\n");
delete region;
} else {
// prepare for next usage
region->MakeEmpty();
}
#if DEBUG_LEAK
fUsed.RemoveItem(region);
#endif
}