mirror of
https://github.com/n64dev/cen64.git
synced 2024-06-23 14:33:13 -04:00
Remove some calls to malloc(...).
This commit is contained in:
parent
1d339f8f74
commit
08439c0f5f
|
@ -33,11 +33,6 @@ struct bus_controller_mapping {
|
|||
uint32_t length;
|
||||
};
|
||||
|
||||
// Releases resources acquired by the bus component.
|
||||
void bus_cleanup(struct bus_controller *bus) {
|
||||
destroy_memory_map(bus->map);
|
||||
}
|
||||
|
||||
// Initializes the bus component.
|
||||
int bus_init(struct bus_controller *bus) {
|
||||
unsigned i;
|
||||
|
@ -78,12 +73,12 @@ int bus_init(struct bus_controller *bus) {
|
|||
bus->rsp
|
||||
};
|
||||
|
||||
if ((bus->map = create_memory_map(NUM_MAPPINGS)) == NULL)
|
||||
return -1;
|
||||
create_memory_map(&bus->map);
|
||||
|
||||
for (i = 0; i < NUM_MAPPINGS; i++)
|
||||
map_address_range(bus->map, mappings[i].address, mappings[i].length,
|
||||
instances[i], mappings[i].read, mappings[i].write);
|
||||
if (map_address_range(&bus->map, mappings[i].address, mappings[i].length,
|
||||
instances[i], mappings[i].read, mappings[i].write))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -96,7 +91,7 @@ int bus_read_word(struct bus_controller *bus,
|
|||
if (address < RDRAM_BASE_ADDRESS_LEN)
|
||||
return read_rdram(bus->ri, address, word);
|
||||
|
||||
else if ((node = resolve_mapped_address(bus->map, address)) == NULL) {
|
||||
else if ((node = resolve_mapped_address(&bus->map, address)) == NULL) {
|
||||
debug("bus_read_word: Failed to access: 0x%.8X\n", address);
|
||||
|
||||
*word = 0x00000000U;
|
||||
|
@ -114,7 +109,7 @@ int bus_write_word(struct bus_controller *bus,
|
|||
if (address < RDRAM_BASE_ADDRESS_LEN)
|
||||
return write_rdram(bus->ri, address, word & dqm, dqm);
|
||||
|
||||
else if ((node = resolve_mapped_address(bus->map, address)) == NULL) {
|
||||
else if ((node = resolve_mapped_address(&bus->map, address)) == NULL) {
|
||||
debug("bus_write_word: Failed to access: 0x%.8X\n", address);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -25,8 +25,6 @@ struct rsp;
|
|||
struct vr4300;
|
||||
|
||||
struct bus_controller {
|
||||
struct memory_map *map;
|
||||
|
||||
struct ai_controller *ai;
|
||||
struct pi_controller *pi;
|
||||
struct ri_controller *ri;
|
||||
|
@ -37,13 +35,15 @@ struct bus_controller {
|
|||
struct rsp *rsp;
|
||||
struct vr4300 *vr4300;
|
||||
|
||||
// For resolving physical address ranges to devices.
|
||||
struct memory_map map;
|
||||
|
||||
// Allows to to pop back out into device_run during simulation.
|
||||
// Kind of a hack to put this in with the device "bus", but at
|
||||
// least everyone gets access to it this way.
|
||||
jmp_buf unwind_data;
|
||||
};
|
||||
|
||||
void bus_cleanup(struct bus_controller *bus);
|
||||
int bus_init(struct bus_controller *bus);
|
||||
|
||||
// General-purpose accesssor functions.
|
||||
|
|
|
@ -16,35 +16,14 @@ static void rotate_left(struct memory_map *, struct memory_map_node *);
|
|||
static void rotate_right(struct memory_map *, struct memory_map_node *);
|
||||
|
||||
// Creates a new memory map.
|
||||
struct memory_map *create_memory_map(unsigned num_maps) {
|
||||
struct memory_map_node *mappings;
|
||||
struct memory_map *map;
|
||||
|
||||
size_t alloc_size = sizeof(*map) + sizeof(*mappings) * (num_maps + 1);
|
||||
if ((map = (struct memory_map*) malloc(alloc_size)) == NULL)
|
||||
return NULL;
|
||||
|
||||
mappings = (struct memory_map_node*) (map + 1);
|
||||
|
||||
// Initialize the allocation.
|
||||
memset(map, 0, alloc_size);
|
||||
map->mappings = mappings;
|
||||
|
||||
// Initialize the tree.
|
||||
map->num_mappings = num_maps;
|
||||
map->nil = &mappings[num_maps];
|
||||
void create_memory_map(struct memory_map *map) {
|
||||
map->next_map_index = 1;
|
||||
map->nil = map->mappings;
|
||||
map->root = map->nil;
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
// Releases memory allocated for a memory map.
|
||||
void destroy_memory_map(struct memory_map *memory_map) {
|
||||
free(memory_map);
|
||||
}
|
||||
|
||||
// Rebalances the tree after a node is inserted.
|
||||
static void fixup(struct memory_map *map, struct memory_map_node *node) {
|
||||
void fixup(struct memory_map *map, struct memory_map_node *node) {
|
||||
struct memory_map_node *cur;
|
||||
|
||||
// Rebalance the whole tree as needed.
|
||||
|
@ -108,20 +87,25 @@ static void fixup(struct memory_map *map, struct memory_map_node *node) {
|
|||
}
|
||||
|
||||
// Inserts a mapping into the tree.
|
||||
void map_address_range(struct memory_map *map, uint32_t start, uint32_t length,
|
||||
int map_address_range(struct memory_map *map, uint32_t start, uint32_t length,
|
||||
void *instance, memory_rd_function on_read, memory_wr_function on_write) {
|
||||
struct memory_map_node *check = map->root;
|
||||
struct memory_map_node *cur = map->nil;
|
||||
uint32_t end = start + length - 1;
|
||||
|
||||
struct memory_map_node *newNode;
|
||||
struct memory_map_node *new_node;
|
||||
struct memory_mapping mapping;
|
||||
|
||||
// Make sure we have enough space in the map.
|
||||
assert(map->next_map_index < map->num_mappings &&
|
||||
"Tried to insert into a memory_map with no free mappings.");
|
||||
const unsigned num_mappings = sizeof(map->mappings) /
|
||||
sizeof(map->mappings[0]) - 1;
|
||||
|
||||
newNode = &map->mappings[map->next_map_index++];
|
||||
if (unlikely(map->next_map_index >= num_mappings)) {
|
||||
debug("map_address_range: Out of free mappings.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
new_node = &map->mappings[map->next_map_index++];
|
||||
|
||||
// Walk down the tree.
|
||||
while (check != map->nil) {
|
||||
|
@ -133,16 +117,16 @@ void map_address_range(struct memory_map *map, uint32_t start, uint32_t length,
|
|||
|
||||
// Insert the entry.
|
||||
if (cur == map->nil)
|
||||
map->root = newNode;
|
||||
map->root = new_node;
|
||||
|
||||
else if (start < cur->mapping.start)
|
||||
cur->left = newNode;
|
||||
cur->left = new_node;
|
||||
else
|
||||
cur->right = newNode;
|
||||
cur->right = new_node;
|
||||
|
||||
newNode->left = map->nil;
|
||||
newNode->right = map->nil;
|
||||
newNode->parent = cur;
|
||||
new_node->left = map->nil;
|
||||
new_node->right = map->nil;
|
||||
new_node->parent = cur;
|
||||
|
||||
// Initialize the entry.
|
||||
mapping.instance = instance;
|
||||
|
@ -153,11 +137,12 @@ void map_address_range(struct memory_map *map, uint32_t start, uint32_t length,
|
|||
mapping.length = length;
|
||||
mapping.start = start;
|
||||
|
||||
newNode->mapping = mapping;
|
||||
new_node->mapping = mapping;
|
||||
|
||||
// Rebalance the tree.
|
||||
newNode->color = MEMORY_MAP_RED;
|
||||
fixup(map, newNode);
|
||||
new_node->color = MEMORY_MAP_RED;
|
||||
fixup(map, new_node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Returns a pointer to a region given an address.
|
||||
|
|
|
@ -42,18 +42,16 @@ struct memory_map_node {
|
|||
};
|
||||
|
||||
struct memory_map {
|
||||
struct memory_map_node *mappings;
|
||||
struct memory_map_node mappings[16];
|
||||
|
||||
struct memory_map_node *nil;
|
||||
struct memory_map_node *root;
|
||||
|
||||
unsigned next_map_index;
|
||||
unsigned num_mappings;
|
||||
};
|
||||
|
||||
struct memory_map* create_memory_map(unsigned num_mappings);
|
||||
void destroy_memory_map(struct memory_map *memory_map);
|
||||
void create_memory_map(struct memory_map *map);
|
||||
|
||||
void map_address_range(struct memory_map *memory_map,
|
||||
int map_address_range(struct memory_map *memory_map,
|
||||
uint32_t start, uint32_t length, void *instance,
|
||||
memory_rd_function on_read, memory_wr_function on_write);
|
||||
|
||||
|
|
1
device.c
1
device.c
|
@ -106,7 +106,6 @@ struct cen64_device *device_create(struct cen64_device *device,
|
|||
|
||||
// Deallocates and cleans up a device.
|
||||
void device_destroy(struct cen64_device *device) {
|
||||
bus_cleanup(&device->bus);
|
||||
}
|
||||
|
||||
// Called when we should (probably?) leave simulation.
|
||||
|
|
|
@ -12,7 +12,45 @@
|
|||
#include "options.h"
|
||||
#include "os/gl_window.h"
|
||||
#include "os/main.h"
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct ram_hunk {
|
||||
void *ptr;
|
||||
int fd;
|
||||
};
|
||||
|
||||
static uint8_t *allocate_ram(struct ram_hunk *ram, size_t size);
|
||||
static void deallocate_ram(struct ram_hunk *ram, size_t size);
|
||||
|
||||
// Allocates a large hunk of zeroed RAM.
|
||||
uint8_t *allocate_ram(struct ram_hunk *ram, size_t size) {
|
||||
#ifdef __linux__
|
||||
if ((ram->fd = open("/dev/zero", O_RDWR)) < 0)
|
||||
#else
|
||||
if ((ram->fd = open("/dev/null", O_RDWR)) < 0)
|
||||
#endif
|
||||
return NULL;
|
||||
|
||||
if ((ram->ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE, ram->fd, 0)) == MAP_FAILED) {
|
||||
close(ram->fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef __linux__
|
||||
memset(ram->ptr, 0, size);
|
||||
#endif
|
||||
return ram->ptr;
|
||||
}
|
||||
|
||||
// Allocates a large hunk of RAM.
|
||||
void deallocate_ram(struct ram_hunk *ram, size_t size) {
|
||||
munmap(ram->ptr, size);
|
||||
close(ram->fd);
|
||||
}
|
||||
|
||||
// Unix application entry point.
|
||||
int main(int argc, const char *argv[]) {
|
||||
|
@ -27,6 +65,14 @@ int os_main(struct cen64_options *options,
|
|||
|
||||
// Allocate the device on the stack.
|
||||
struct cen64_device device;
|
||||
struct ram_hunk hunk;
|
||||
uint8_t *ram;
|
||||
|
||||
if ((ram = allocate_ram(&hunk, DEVICE_RAMSIZE)) == NULL) {
|
||||
printf("Failed to allocate enough memory.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(&device, 0, sizeof(device));
|
||||
|
||||
// Prevent debugging tools from raising warnings
|
||||
|
@ -35,11 +81,14 @@ int os_main(struct cen64_options *options,
|
|||
|
||||
if (create_gl_window(&device.vi.gl_window, &hints)) {
|
||||
printf("Failed to create a window.\n");
|
||||
|
||||
deallocate_ram(&hunk, DEVICE_RAMSIZE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
status = device_run(&device, options, malloc(DEVICE_RAMSIZE), pifrom, cart);
|
||||
status = device_run(&device, options, ram, pifrom, cart);
|
||||
destroy_gl_window(&device.vi.gl_window);
|
||||
deallocate_ram(&hunk, DEVICE_RAMSIZE);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -26,11 +26,11 @@ int open_rom_file(const char *path, struct rom_file *file) {
|
|||
void *ptr;
|
||||
int fd;
|
||||
|
||||
/* Open the file for read only. */
|
||||
// Open the file for read only.
|
||||
if ((fd = open(path, O_RDONLY)) == -1)
|
||||
return -1;
|
||||
|
||||
/* Get the file's size, map it into the address space. */
|
||||
// Get the file's size, map it into the address space.
|
||||
if (fstat(fd, &sb) == -1 || (ptr = mmap(NULL,
|
||||
sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) {
|
||||
close(fd);
|
||||
|
|
Loading…
Reference in a new issue