removed simple_list from emumem (nw)

This commit is contained in:
Miodrag Milanovic 2016-06-18 15:31:03 +02:00
parent ae8f989a8b
commit 408ce16683
2 changed files with 99 additions and 120 deletions

View File

@ -1568,30 +1568,30 @@ void memory_manager::initialize()
// if there is a configuration for this space, we need an address space
const address_space_config *spaceconfig = memory.space_config(spacenum);
if (spaceconfig != nullptr)
m_spacelist.append(address_space::allocate(*this, *spaceconfig, memory, spacenum));
address_space::allocate(m_spacelist,*this, *spaceconfig, memory, spacenum);
}
// construct and preprocess the address_map for each space
for (address_space &space : m_spacelist)
space.prepare_map();
for (auto &space : m_spacelist)
space->prepare_map();
// create the handlers from the resulting address maps
for (address_space &space : m_spacelist)
space.populate_from_map();
for (auto &space : m_spacelist)
space->populate_from_map();
// allocate memory needed to back each address space
for (address_space &space : m_spacelist)
space.allocate_memory();
for (auto &space : m_spacelist)
space->allocate_memory();
// find all the allocated pointers
for (address_space &space : m_spacelist)
space.locate_memory();
for (auto &space : m_spacelist)
space->locate_memory();
// disable logging of unmapped access when no one receives it
for (address_space &space : m_spacelist)
for (auto &space : m_spacelist)
{
if (!machine().options().log() && !machine().options().oslog() && !(machine().debug_flags & DEBUG_FLAG_ENABLED))
space.set_log_unmap(false);
space->set_log_unmap(false);
}
// register a callback to reset banks when reloading state
@ -1617,19 +1617,19 @@ void memory_manager::dump(FILE *file)
return;
// loop over address spaces
for (address_space &space : m_spacelist)
for (auto &space : m_spacelist)
{
fprintf(file, "\n\n"
"====================================================\n"
"Device '%s' %s address space read handler dump\n"
"====================================================\n", space.device().tag(), space.name());
space.dump_map(file, ROW_READ);
"====================================================\n", space->device().tag(), space->name());
space->dump_map(file, ROW_READ);
fprintf(file, "\n\n"
"====================================================\n"
"Device '%s' %s address space write handler dump\n"
"====================================================\n", space.device().tag(), space.name());
space.dump_map(file, ROW_WRITE);
"====================================================\n", space->device().tag(), space->name());
space->dump_map(file, ROW_WRITE);
}
}
@ -1721,8 +1721,7 @@ void memory_manager::bank_reattach()
//-------------------------------------------------
address_space::address_space(memory_manager &manager, device_memory_interface &memory, address_spacenum spacenum, bool large)
: m_next(nullptr),
m_config(*memory.space_config(spacenum)),
: m_config(*memory.space_config(spacenum)),
m_device(memory.device()),
m_addrmask(0xffffffffUL >> (32 - m_config.m_addrbus_width)),
m_bytemask(address_to_byte_end(m_addrmask)),
@ -1757,7 +1756,7 @@ address_space::~address_space()
// allocate - static smart allocator of subtypes
//-------------------------------------------------
address_space &address_space::allocate(memory_manager &manager, const address_space_config &config, device_memory_interface &memory, address_spacenum spacenum)
void address_space::allocate(std::vector<std::unique_ptr<address_space>> &space_list,memory_manager &manager, const address_space_config &config, device_memory_interface &memory, address_spacenum spacenum)
{
// allocate one of the appropriate type
bool large = (config.addr2byte_end(0xffffffffUL >> (32 - config.m_addrbus_width)) >= (1 << 18));
@ -1767,68 +1766,73 @@ address_space &address_space::allocate(memory_manager &manager, const address_sp
case 8:
if (config.endianness() == ENDIANNESS_LITTLE)
{
if (large)
return *global_alloc(address_space_8le_large(manager, memory, spacenum));
if (large)
space_list.push_back(std::make_unique<address_space_8le_large>(manager, memory, spacenum));
else
return *global_alloc(address_space_8le_small(manager, memory, spacenum));
space_list.push_back(std::make_unique<address_space_8le_small>(manager, memory, spacenum));
}
else
{
if (large)
return *global_alloc(address_space_8be_large(manager, memory, spacenum));
if (large)
space_list.push_back(std::make_unique<address_space_8be_large>(manager, memory, spacenum));
else
return *global_alloc(address_space_8be_small(manager, memory, spacenum));
space_list.push_back(std::make_unique<address_space_8be_small>(manager, memory, spacenum));
}
break;
case 16:
if (config.endianness() == ENDIANNESS_LITTLE)
{
if (large)
return *global_alloc(address_space_16le_large(manager, memory, spacenum));
if (large)
space_list.push_back(std::make_unique<address_space_16le_large>(manager, memory, spacenum));
else
return *global_alloc(address_space_16le_small(manager, memory, spacenum));
space_list.push_back(std::make_unique<address_space_16le_small>(manager, memory, spacenum));
}
else
{
if (large)
return *global_alloc(address_space_16be_large(manager, memory, spacenum));
space_list.push_back(std::make_unique<address_space_16be_large>(manager, memory, spacenum));
else
return *global_alloc(address_space_16be_small(manager, memory, spacenum));
space_list.push_back(std::make_unique<address_space_16be_small>(manager, memory, spacenum));
}
break;
case 32:
if (config.endianness() == ENDIANNESS_LITTLE)
{
if (large)
return *global_alloc(address_space_32le_large(manager, memory, spacenum));
space_list.push_back(std::make_unique<address_space_32le_large>(manager, memory, spacenum));
else
return *global_alloc(address_space_32le_small(manager, memory, spacenum));
space_list.push_back(std::make_unique<address_space_32le_small>(manager, memory, spacenum));
}
else
{
if (large)
return *global_alloc(address_space_32be_large(manager, memory, spacenum));
space_list.push_back(std::make_unique<address_space_32be_large>(manager, memory, spacenum));
else
return *global_alloc(address_space_32be_small(manager, memory, spacenum));
space_list.push_back(std::make_unique<address_space_32be_small>(manager, memory, spacenum));
}
break;
case 64:
if (config.endianness() == ENDIANNESS_LITTLE)
{
if (large)
return *global_alloc(address_space_64le_large(manager, memory, spacenum));
space_list.push_back(std::make_unique<address_space_64le_large>(manager, memory, spacenum));
else
return *global_alloc(address_space_64le_small(manager, memory, spacenum));
space_list.push_back(std::make_unique<address_space_64le_small>(manager, memory, spacenum));
}
else
{
if (large)
return *global_alloc(address_space_64be_large(manager, memory, spacenum));
space_list.push_back(std::make_unique<address_space_64be_large>(manager, memory, spacenum));
else
return *global_alloc(address_space_64be_small(manager, memory, spacenum));
space_list.push_back(std::make_unique<address_space_64be_small>(manager, memory, spacenum));
}
}
throw emu_fatalerror("Invalid width %d specified for address_space::allocate", config.data_width());
break;
default:
throw emu_fatalerror("Invalid width %d specified for address_space::allocate", config.data_width());
}
}
@ -2193,20 +2197,20 @@ void address_space::populate_map_entry_setoffset(const address_map_entry &entry)
void address_space::allocate_memory()
{
simple_list<memory_block> &blocklist = manager().m_blocklist;
auto &blocklist = manager().m_blocklist;
// make a first pass over the memory map and track blocks with hardcoded pointers
// we do this to make sure they are found by space_find_backing_memory first
memory_block *prev_memblock_tail = blocklist.last();
int tail = blocklist.size();
for (address_map_entry &entry : m_map->m_entrylist)
if (entry.m_memory != nullptr)
blocklist.append(*global_alloc(memory_block(*this, entry.m_bytestart, entry.m_byteend, entry.m_memory)));
blocklist.push_back(std::make_unique<memory_block>(*this, entry.m_bytestart, entry.m_byteend, entry.m_memory));
// loop over all blocks just allocated and assign pointers from them
address_map_entry *unassigned = nullptr;
memory_block *first_new_block = (prev_memblock_tail != nullptr) ? prev_memblock_tail->next() : blocklist.first();
for (memory_block *memblock = first_new_block; memblock != nullptr; memblock = memblock->next())
unassigned = block_assign_intersecting(memblock->bytestart(), memblock->byteend(), memblock->data());
for (auto memblock = blocklist.begin() + tail; memblock != blocklist.end(); ++memblock)
unassigned = block_assign_intersecting(memblock->get()->bytestart(), memblock->get()->byteend(), memblock->get()->data());
// if we don't have an unassigned pointer yet, try to find one
if (unassigned == nullptr)
@ -2247,10 +2251,11 @@ void address_space::allocate_memory()
// we now have a block to allocate; do it
offs_t curbytestart = curblockstart * MEMORY_BLOCK_CHUNK;
offs_t curbyteend = curblockend * MEMORY_BLOCK_CHUNK + (MEMORY_BLOCK_CHUNK - 1);
memory_block &block = blocklist.append(*global_alloc(memory_block(*this, curbytestart, curbyteend)));
auto block = std::make_unique<memory_block>(*this, curbytestart, curbyteend);
// assign memory that intersected the new block
unassigned = block_assign_intersecting(curbytestart, curbyteend, block.data());
unassigned = block_assign_intersecting(curbytestart, curbyteend, block.get()->data());
blocklist.push_back(std::move(block));
}
}
@ -2572,8 +2577,9 @@ void address_space::install_ram_generic(offs_t addrstart, offs_t addrend, offs_t
{
if (machine().phase() >= MACHINE_PHASE_RESET)
fatalerror("Attempted to call install_ram_generic() after initialization time without a baseptr!\n");
memory_block &block = manager().m_blocklist.append(*global_alloc(memory_block(*this, address_to_byte(addrstart), address_to_byte_end(addrend))));
bank.set_base(block.data());
auto block = std::make_unique<memory_block>(*this, address_to_byte(addrstart), address_to_byte_end(addrend));
bank.set_base(block.get()->data());
manager().m_blocklist.push_back(std::move(block));
}
}
@ -2601,8 +2607,9 @@ void address_space::install_ram_generic(offs_t addrstart, offs_t addrend, offs_t
{
if (machine().phase() >= MACHINE_PHASE_RESET)
fatalerror("Attempted to call install_ram_generic() after initialization time without a baseptr!\n");
memory_block &block = manager().m_blocklist.append(*global_alloc(memory_block(*this, address_to_byte(addrstart), address_to_byte_end(addrend))));
bank.set_base(block.data());
auto block = std::make_unique<memory_block>(*this, address_to_byte(addrstart), address_to_byte_end(addrend));
bank.set_base(block.get()->data());
manager().m_blocklist.push_back(std::move(block));
}
}
}
@ -2781,11 +2788,11 @@ void *address_space::find_backing_memory(offs_t addrstart, offs_t addrend)
}
// if not found there, look in the allocated blocks
for (memory_block &block : manager().m_blocklist)
if (block.contains(*this, bytestart, byteend))
for (auto &block : manager().m_blocklist)
if (block->contains(*this, bytestart, byteend))
{
VPRINTF(("found in allocated memory block %08X-%08X [%p]\n", block.bytestart(), block.byteend(), block.data() + (bytestart - block.bytestart())));
return block.data() + bytestart - block.bytestart();
VPRINTF(("found in allocated memory block %08X-%08X [%p]\n", block->bytestart(), block->byteend(), block->data() + (bytestart - block->bytestart())));
return block->data() + bytestart - block->bytestart();
}
VPRINTF(("did not find\n"));
@ -3953,22 +3960,23 @@ direct_read_data::direct_range *direct_read_data::find_range(offs_t byteaddress,
entry = m_space.read().lookup_live_nowp(byteaddress);
// scan our table
for (direct_range &range : m_rangelist[entry])
for (auto &range : m_rangelist[entry])
if (byteaddress >= range.m_bytestart && byteaddress <= range.m_byteend)
return &range;
// didn't find out; allocate a new one
direct_range *range = m_freerangelist.first();
if (range != nullptr)
m_freerangelist.detach(*range);
else
range = global_alloc(direct_range);
direct_range range;
if (m_freerangelist.size() > 0)
{
range = m_freerangelist.front();
m_freerangelist.pop_front();
}
// fill in the range
m_space.read().derive_range(byteaddress, range->m_bytestart, range->m_byteend);
m_rangelist[entry].prepend(*range);
m_space.read().derive_range(byteaddress, range.m_bytestart, range.m_byteend);
m_rangelist[entry].push_front(range);
return range;
return &m_rangelist[entry].front();
}
@ -3983,16 +3991,13 @@ void direct_read_data::remove_intersecting_ranges(offs_t bytestart, offs_t bytee
for (auto & elem : m_rangelist)
{
// loop over all ranges in this entry's list
direct_range *nextrange;
for (direct_range *range = elem.first(); range != nullptr; range = nextrange)
for (std::list<direct_range>::iterator range = elem.begin(); range!=elem.end();++range)
{
nextrange = range->next();
// if we intersect, remove and add to the free range list
if (bytestart <= range->m_byteend && byteend >= range->m_bytestart)
{
elem.detach(*range);
m_freerangelist.prepend(*range);
m_freerangelist.push_front(*range);
elem.erase(range);
}
}
}
@ -4037,8 +4042,7 @@ void direct_read_data::explicit_configure(offs_t bytestart, offs_t byteend, offs
//-------------------------------------------------
memory_block::memory_block(address_space &space, offs_t bytestart, offs_t byteend, void *memory)
: m_next(nullptr),
m_machine(space.machine()),
: m_machine(space.machine()),
m_space(space),
m_bytestart(bytestart),
m_byteend(byteend),
@ -4137,8 +4141,8 @@ memory_bank::~memory_bank()
bool memory_bank::references_space(const address_space &space, read_or_write readorwrite) const
{
for (bank_reference &ref : m_reflist)
if (ref.matches(space, readorwrite))
for (auto &ref : m_reflist)
if (ref->matches(space, readorwrite))
return true;
return false;
}
@ -4154,7 +4158,7 @@ void memory_bank::add_reference(address_space &space, read_or_write readorwrite)
// if we already have a reference, skip it
if (references_space(space, readorwrite))
return;
m_reflist.append(*global_alloc(bank_reference(space, readorwrite)));
m_reflist.push_back(std::make_unique<bank_reference>(space, readorwrite));
}
@ -4166,8 +4170,8 @@ void memory_bank::add_reference(address_space &space, read_or_write readorwrite)
void memory_bank::invalidate_references()
{
// invalidate all the direct references to any referenced address spaces
for (bank_reference &ref : m_reflist)
ref.space().direct().force_update();
for (auto &ref : m_reflist)
ref->space().direct().force_update();
}

View File

@ -147,16 +147,14 @@ public:
{
public:
// construction
direct_range()
: m_next(nullptr),
m_bytestart(0),
m_byteend(~0) { }
// getters
direct_range *next() const { return m_next; }
direct_range(): m_bytestart(0),m_byteend(~0) { }
inline bool operator==(direct_range val) noexcept
{ // return true if _Left and _Right identify the same thread
return (m_bytestart == val.m_bytestart) && (m_byteend == val.m_byteend);
}
// internal state
direct_range * m_next; // pointer to the next range in the list
offs_t m_bytestart; // starting byte offset of the range
offs_t m_byteend; // ending byte offset of the range
};
@ -200,8 +198,8 @@ private:
offs_t m_bytestart; // minimum valid byte address
offs_t m_byteend; // maximum valid byte address
UINT16 m_entry; // live entry
simple_list<direct_range> m_rangelist[TOTAL_MEMORY_BANKS]; // list of ranges for each entry
simple_list<direct_range> m_freerangelist; // list of recycled range entries
std::list<direct_range> m_rangelist[TOTAL_MEMORY_BANKS]; // list of ranges for each entry
std::list<direct_range> m_freerangelist; // list of recycled range entries
direct_update_delegate m_directupdate; // fast direct-access update callback
};
@ -258,20 +256,17 @@ class address_space
friend class address_table_write;
friend class address_table_setoffset;
friend class direct_read_data;
friend class simple_list<address_space>;
friend resource_pool_object<address_space>::~resource_pool_object();
protected:
// construction/destruction
address_space(memory_manager &manager, device_memory_interface &memory, address_spacenum spacenum, bool large);
virtual ~address_space();
public:
virtual ~address_space();
// public allocator
static address_space &allocate(memory_manager &manager, const address_space_config &config, device_memory_interface &memory, address_spacenum spacenum);
static void allocate(std::vector<std::unique_ptr<address_space>> &space_list, memory_manager &manager, const address_space_config &config, device_memory_interface &memory, address_spacenum spacenum);
// getters
address_space *next() const { return m_next; }
memory_manager &manager() const { return m_manager; }
device_t &device() const { return m_device; }
running_machine &machine() const { return m_machine; }
@ -459,7 +454,6 @@ private:
protected:
// private state
address_space * m_next; // next address space in the global list
const address_space_config &m_config; // configuration of this space
device_t & m_device; // reference to the owning device
std::unique_ptr<address_map> m_map; // original memory map
@ -489,9 +483,6 @@ class memory_block
{
DISABLE_COPYING(memory_block);
friend class simple_list<memory_block>;
friend resource_pool_object<memory_block>::~resource_pool_object();
public:
// construction/destruction
memory_block(address_space &space, offs_t bytestart, offs_t byteend, void *memory = nullptr);
@ -499,7 +490,6 @@ public:
// getters
running_machine &machine() const { return m_machine; }
memory_block *next() const { return m_next; }
offs_t bytestart() const { return m_bytestart; }
offs_t byteend() const { return m_byteend; }
UINT8 *data() const { return m_data; }
@ -512,7 +502,6 @@ public:
private:
// internal state
memory_block * m_next; // next memory block in the list
running_machine & m_machine; // need the machine to free our memory
address_space & m_space; // which address space are we associated with?
offs_t m_bytestart, m_byteend; // byte-normalized start/end for verifying a match
@ -526,24 +515,16 @@ private:
// a memory bank is a global pointer to memory that can be shared across devices and changed dynamically
class memory_bank
{
friend class simple_list<memory_bank>;
friend resource_pool_object<memory_bank>::~resource_pool_object();
// a bank reference is an entry in a list of address spaces that reference a given bank
class bank_reference
{
friend class simple_list<bank_reference>;
friend resource_pool_object<bank_reference>::~resource_pool_object();
public:
// construction/destruction
bank_reference(address_space &space, read_or_write readorwrite)
: m_next(nullptr),
m_space(space),
m_readorwrite(readorwrite) { }
: m_space(space),
m_readorwrite(readorwrite) { }
// getters
bank_reference *next() const { return m_next; }
address_space &space() const { return m_space; }
// does this reference match the space+read/write combination?
@ -554,7 +535,6 @@ class memory_bank
private:
// internal state
bank_reference * m_next; // link to the next reference
address_space & m_space; // address space that references us
read_or_write m_readorwrite; // used for read or write?
};
@ -614,7 +594,7 @@ private:
std::vector<bank_entry> m_entry; // array of entries (dynamically allocated)
std::string m_name; // friendly name for this bank
std::string m_tag; // tag for this bank
simple_list<bank_reference> m_reflist; // linked list of address spaces referencing this bank
std::vector<std::unique_ptr<bank_reference>> m_reflist; // linked list of address spaces referencing this bank
};
@ -623,8 +603,6 @@ private:
// a memory share contains information about shared memory region
class memory_share
{
friend class simple_list<memory_share>;
public:
// construction/destruction
memory_share(UINT8 width, size_t bytes, endianness_t endianness, void *ptr = nullptr)
@ -664,9 +642,6 @@ class memory_region
DISABLE_COPYING(memory_region);
friend class memory_manager;
friend class simple_list<memory_region>;
friend resource_pool_object<memory_region>::~resource_pool_object();
public:
// construction/destruction
memory_region(running_machine &machine, const char *name, UINT32 length, UINT8 width, endianness_t endian);
@ -707,7 +682,7 @@ private:
class memory_manager
{
friend class address_space;
friend memory_region::memory_region(running_machine &machine, const char *name, UINT32 length, UINT8 width, endianness_t endian);
public:
// construction/destruction
memory_manager(running_machine &machine);
@ -740,8 +715,8 @@ private:
UINT8 * m_bank_ptr[TOTAL_MEMORY_BANKS]; // array of bank pointers
simple_list<address_space> m_spacelist; // list of address spaces
simple_list<memory_block> m_blocklist; // head of the list of memory blocks
std::vector<std::unique_ptr<address_space>> m_spacelist; // list of address spaces
std::vector<std::unique_ptr<memory_block>> m_blocklist; // head of the list of memory blocks
std::unordered_map<std::string,std::unique_ptr<memory_bank>> m_banklist; // data gathered for each bank
UINT16 m_banknext; // next bank to allocate