open_toontown_panda3d/panda/src/gobj/simpleAllocator.h

143 lines
4.5 KiB
C++

// Filename: simpleAllocator.h
// Created by: drose (12May07)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef SIMPLEALLOCATOR_H
#define SIMPLEALLOCATOR_H
#include "pandabase.h"
#include "linkedListNode.h"
#include "pmutex.h"
#include "mutexHolder.h"
class SimpleAllocatorBlock;
////////////////////////////////////////////////////////////////////
// Class : SimpleAllocator
// Description : An implementation of a very simple block allocator.
// This class can allocate ranges of nonnegative
// integers within a specified upper limit; it uses a
// simple first-fit algorithm to find the next available
// space.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_GOBJ SimpleAllocator : public LinkedListNode {
PUBLISHED:
INLINE SimpleAllocator(size_t max_size, Mutex &lock);
virtual ~SimpleAllocator();
INLINE SimpleAllocatorBlock *alloc(size_t size);
INLINE bool is_empty() const;
INLINE size_t get_total_size() const;
INLINE size_t get_max_size() const;
INLINE void set_max_size(size_t max_size);
INLINE size_t get_contiguous() const;
INLINE SimpleAllocatorBlock *get_first_block() const;
void output(ostream &out) const;
void write(ostream &out) const;
protected:
SimpleAllocatorBlock *do_alloc(size_t size);
INLINE bool do_is_empty() const;
virtual SimpleAllocatorBlock *make_block(size_t start, size_t size);
INLINE void mark_contiguous(const LinkedListNode *block);
virtual void changed_contiguous();
protected:
// This is implemented as a linked-list chain of allocated blocks.
// Free blocks are implicit. Blocks are kept in sorted order from
// beginning to end. Allocating a block means creating a new entry
// in the chain wherever it may fit; freeing a block means simply
// removing the allocated block from the chain. With this simple
// approach, there is no need to merge adjacent free blocks to
// straighten out fragmentation, since free blocks are not stored.
// However, it does mean we have to walk through a list of adjacent
// allocated blocks in order to find the free blocks.
size_t _total_size;
size_t _max_size;
// This is what we currently believe our max contiguous space to be.
// This guess might be larger than the actual available space, but
// it will not be smaller.
size_t _contiguous;
// This mutex protects all operations within this class. The caller
// must pass the reference to a mutex in to the constructor, and the
// caller remains responsible for owning the mutex. This allows the
// mutex to be shared where appropriate.
// A derived class may also use it to protect itself as well, but
// take care to call do_alloc() instead of alloc() etc. as
// necessary.
Mutex &_lock;
friend class SimpleAllocatorBlock;
};
////////////////////////////////////////////////////////////////////
// Class : SimpleAllocatorBlock
// Description : A single block as returned from
// SimpleAllocator::alloc().
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_GOBJ SimpleAllocatorBlock : public LinkedListNode {
protected:
INLINE SimpleAllocatorBlock(SimpleAllocator *alloc,
size_t start, size_t size);
PUBLISHED:
INLINE ~SimpleAllocatorBlock();
INLINE void free();
INLINE SimpleAllocator *get_allocator() const;
INLINE size_t get_start() const;
INLINE size_t get_size() const;
INLINE bool is_free() const;
INLINE size_t get_max_size() const;
INLINE bool realloc(size_t size);
INLINE SimpleAllocatorBlock *get_next_block() const;
void output(ostream &out) const;
protected:
INLINE void do_free();
INLINE size_t do_get_max_size() const;
INLINE bool do_realloc(size_t size);
private:
SimpleAllocator *_allocator;
size_t _start;
size_t _size;
friend class SimpleAllocator;
};
INLINE ostream &operator << (ostream &out, const SimpleAllocator &obj) {
obj.output(out);
return out;
}
INLINE ostream &operator << (ostream &out, const SimpleAllocatorBlock &obj) {
obj.output(out);
return out;
}
#include "simpleAllocator.I"
#endif