Remove some calls to malloc(...).

This commit is contained in:
Tyler Stachecki 2014-11-01 16:59:12 -04:00
parent 1d339f8f74
commit 08439c0f5f
7 changed files with 90 additions and 64 deletions

View file

@ -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;

View file

@ -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.

View file

@ -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.

View file

@ -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);

View file

@ -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.

View file

@ -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;
}

View file

@ -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);