summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/emualloc.h
blob: 44e39e199ad7cd6aec3661efc4e82b3f589c1daa (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************

    emualloc.h

    Memory allocation helpers for the core emulator.

***************************************************************************/

#pragma once

#ifndef __EMUALLOC_H__
#define __EMUALLOC_H__

#include <new>
#include <mutex>
#include "osdcore.h"
#include "coretmpl.h"

//**************************************************************************
//  MACROS
//**************************************************************************

// pool allocation helpers
#define pool_alloc(_pool, _type)                    (_pool).add_object(global_alloc(_type))
#define pool_alloc_clear(_pool, _type)              (_pool).add_object(global_alloc_clear _type)
#define pool_alloc_array(_pool, _type, _num)        (_pool).add_array(global_alloc_array(_type,_num), (_num))
#define pool_alloc_array_clear(_pool, _type, _num)  (_pool).add_array(global_alloc_array_clear<_type>(_num), (_num))
#define pool_free(_pool, v)                         (_pool).remove(v)



//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************

// resource_pool_item is a base class for items that are tracked by a resource pool
class resource_pool_item
{
private:
	resource_pool_item(const resource_pool_item &);
	resource_pool_item &operator=(const resource_pool_item &);

public:
	resource_pool_item(void *ptr, size_t size)
		: m_next(nullptr),
			m_ordered_next(nullptr),
			m_ordered_prev(nullptr),
			m_ptr(ptr),
			m_size(size),
			m_id(~(uint64_t)0) { }
	virtual ~resource_pool_item() { }

	resource_pool_item *    m_next;
	resource_pool_item *    m_ordered_next;
	resource_pool_item *    m_ordered_prev;
	void *                  m_ptr;
	size_t                  m_size;
	uint64_t                  m_id;
};


// a resource_pool_object is a simple object wrapper for the templatized type
template<class _ObjectClass>
class resource_pool_object : public resource_pool_item
{
private:
	resource_pool_object<_ObjectClass>(const resource_pool_object<_ObjectClass> &);
	resource_pool_object<_ObjectClass> &operator=(const resource_pool_object<_ObjectClass> &);

public:
	resource_pool_object(_ObjectClass *object)
		: resource_pool_item(reinterpret_cast<void *>(object), sizeof(_ObjectClass)),
			m_object(object) { }
	virtual ~resource_pool_object() { delete m_object; }

private:
	_ObjectClass *          m_object;
};


// a resource_pool_array is a simple object wrapper for an allocated array of
// the templatized type
template<class _ObjectClass> class resource_pool_array : public resource_pool_item
{
private:
	resource_pool_array<_ObjectClass>(const resource_pool_array<_ObjectClass> &);
	resource_pool_array<_ObjectClass> &operator=(const resource_pool_array<_ObjectClass> &);

public:
	resource_pool_array(_ObjectClass *array, int count)
		: resource_pool_item(reinterpret_cast<void *>(array), sizeof(_ObjectClass) * count),
			m_array(array),
			m_count(count) { }
	virtual ~resource_pool_array() { delete[] m_array; }

private:
	_ObjectClass *          m_array;
	int                     m_count;
};


// a resource pool tracks items and frees them upon reset or destruction
class resource_pool
{
private:
	resource_pool(const resource_pool &);
	resource_pool &operator=(const resource_pool &);

public:
	resource_pool(int hash_size = 193);
	virtual ~resource_pool();

	void add(resource_pool_item &item, size_t size, const char *type);
	void remove(resource_pool_item &item) { remove(item.m_ptr); }
	void remove(void *ptr);
	void remove(const void *ptr) { remove(const_cast<void *>(ptr)); }
	resource_pool_item *find(void *ptr);
	bool contains(void *ptrstart, void *ptrend);
	void clear();

	template<class _ObjectClass> _ObjectClass *add_object(_ObjectClass* object) { add(*new resource_pool_object<_ObjectClass>(object), sizeof(_ObjectClass), typeid(_ObjectClass).name()); return object; }
	template<class _ObjectClass> _ObjectClass *add_array(_ObjectClass* array, int count) { add(*new resource_pool_array<_ObjectClass>(array, count), sizeof(_ObjectClass), typeid(_ObjectClass).name()); return array; }

private:
	int                     m_hash_size;
	std::mutex              m_listlock;
	std::vector<resource_pool_item *> m_hash;
	resource_pool_item *    m_ordered_head;
	resource_pool_item *    m_ordered_tail;
	static uint64_t           s_id;
};


#endif  /* __EMUALLOC_H__ */