charset=UTF-8 Last-Modified: Sat, 03 May 2025 14:30:22 GMT Expires: Sat, 03 May 2025 14:35:22 GMT mame - MAME - Multiple Arcade Machine Emulator
summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/glm/doc/api/a00019_source.html
12131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
Commit message (Expand)AuthorAgeFilesLines
* Update GLM to tip of stable branch (0.9.8.5 pre-release) - fixes build with M... Vas Crabb2017-02-251-170/+209
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************

    emualloc.c

    Memory allocation helpers for the core emulator.

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

#include "emucore.h"


//**************************************************************************
//  DEBUGGING
//**************************************************************************

#define LOG_ALLOCS      (0)



//**************************************************************************
//  GLOBALS
//**************************************************************************

UINT64 resource_pool::s_id = 0;



//**************************************************************************
//  RESOURCE POOL
//**************************************************************************

//-------------------------------------------------
//  resource_pool - constructor for a new resource
//  pool
//-------------------------------------------------

resource_pool::resource_pool(int hash_size)
	: m_hash_size(hash_size),
		m_listlock(osd_lock_alloc()),
		m_hash(hash_size),
		m_ordered_head(nullptr),
		m_ordered_tail(nullptr)
{
	memset(&m_hash[0], 0, hash_size*sizeof(m_hash[0]));
}


//-------------------------------------------------
//  ~resource_pool - destructor for a resource
//  pool; make sure all tracked objects are
//  deleted
//-------------------------------------------------

resource_pool::~resource_pool()
{
	clear();
	if (m_listlock != nullptr)
		osd_lock_free(m_listlock);
}


//-------------------------------------------------
//  add - add a new item to the resource pool
//-------------------------------------------------

void resource_pool::add(resource_pool_item &item, size_t size, const char *type)
{
	osd_lock_acquire(m_listlock);

	// insert into hash table
	int hashval = reinterpret_cast<FPTR>(item.m_ptr) % m_hash_size;
	item.m_next = m_hash[hashval];
	m_hash[hashval] = &item;

	// fetch the ID of this item's pointer; some implementations put hidden data
	// before, so if we don't find it, check 4 bytes ahead
	item.m_id = ++s_id;
	if (LOG_ALLOCS)
		fprintf(stderr, "#%06d, add %s, %d bytes\n", (UINT32)item.m_id, type, UINT32(size));

	// find the entry to insert after
	resource_pool_item *insert_after;
	for (insert_after = m_ordered_tail; insert_after != nullptr; insert_after = insert_after->m_ordered_prev)
		if (insert_after->m_id < item.m_id)
			break;

	// insert into the appropriate spot
	if (insert_after != nullptr)
	{
		item.m_ordered_next = insert_after->m_ordered_next;
		if (item.m_ordered_next != nullptr)
			item.m_ordered_next->m_ordered_prev = &item;
		else
			m_ordered_tail = &item;
		item.m_ordered_prev = insert_after;
		insert_after->m_ordered_next = &item;
	}
	else
	{
		item.m_ordered_next = m_ordered_head;
		if (item.m_ordered_next != nullptr)
			item.m_ordered_next->m_ordered_prev = &item;
		else
			m_ordered_tail = &item;
		item.m_ordered_prev = nullptr;
		m_ordered_head = &item;
	}

	osd_lock_release(m_listlock);
}


//-------------------------------------------------
//  remove - remove a specific item from the
//  resource pool
//-------------------------------------------------

void resource_pool::remove(void *ptr)
{
	// ignore NULLs
	if (ptr == nullptr)
		return;

	// search for the item
	osd_lock_acquire(m_listlock);

	int hashval = reinterpret_cast<FPTR>(ptr) % m_hash_size;
	for (resource_pool_item **scanptr = &m_hash[hashval]; *scanptr != nullptr; scanptr = &(*scanptr)->m_next)

		// must match the pointer
		if ((*scanptr)->m_ptr == ptr)
		{
			// remove from hash table
			resource_pool_item *deleteme = *scanptr;
			*scanptr = deleteme->m_next;

			// remove from ordered list
			if (deleteme->m_ordered_prev != nullptr)
				deleteme->m_ordered_prev->m_ordered_next = deleteme->m_ordered_next;
			else
				m_ordered_head = deleteme->m_ordered_next;
			if (deleteme->m_ordered_next != nullptr)
				deleteme->m_ordered_next->m_ordered_prev = deleteme->m_ordered_prev;
			else
				m_ordered_tail = deleteme->m_ordered_prev;

			// delete the object and break
			if (LOG_ALLOCS)
				fprintf(stderr, "#%06d, delete %d bytes\n", (UINT32)deleteme->m_id, static_cast<UINT32>(deleteme->m_size));
			global_free(deleteme);
			break;
		}

	osd_lock_release(m_listlock);
}


//-------------------------------------------------
//  find - find a specific item in the resource
//  pool
//-------------------------------------------------

resource_pool_item *resource_pool::find(void *ptr)
{
	// search for the item
	osd_lock_acquire(m_listlock);

	int hashval = reinterpret_cast<FPTR>(ptr) % m_hash_size;
	resource_pool_item *item;
	for (item = m_hash[hashval]; item != nullptr; item = item->m_next)
		if (item->m_ptr == ptr)
			break;

	osd_lock_release(m_listlock);

	return item;
}


//-------------------------------------------------
//  contains - return true if given ptr is
//  contained by one of the objects in the pool
//-------------------------------------------------

bool resource_pool::contains(void *_ptrstart, void *_ptrend)
{
	UINT8 *ptrstart = reinterpret_cast<UINT8 *>(_ptrstart);
	UINT8 *ptrend = reinterpret_cast<UINT8 *>(_ptrend);

	// search for the item
	osd_lock_acquire(m_listlock);

	resource_pool_item *item = nullptr;
	for (item = m_ordered_head; item != nullptr; item = item->m_ordered_next)
	{
		UINT8 *objstart = reinterpret_cast<UINT8 *>(item->m_ptr);
		UINT8 *objend = objstart + item->m_size;
		if (ptrstart >= objstart && ptrend <= objend)
			goto found;
	}

found:
	osd_lock_release(m_listlock);

	return (item != nullptr);
}


//-------------------------------------------------
//  clear - remove all items from a resource pool
//-------------------------------------------------

void resource_pool::clear()
{
	osd_lock_acquire(m_listlock);

	// important: delete from earliest to latest; this allows objects to clean up after
	// themselves if they wish
	while (m_ordered_head != nullptr)
		remove(m_ordered_head->m_ptr);

	osd_lock_release(m_listlock);
}