diff options
author | Andrew Cagney <cagney@redhat.com> | 1998-03-22 05:06:27 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 1998-03-22 05:06:27 +0000 |
commit | e5f0d498af49da4680564df06b9709423523ba6e (patch) | |
tree | 0e052b4638713a10794e9fbd11df0651dcf974c7 /sim/common/hw-base.c | |
parent | b1e9223cee0728b89f6b909c445a896d9fe41452 (diff) | |
download | gdb-e5f0d498af49da4680564df06b9709423523ba6e.zip gdb-e5f0d498af49da4680564df06b9709423523ba6e.tar.gz gdb-e5f0d498af49da4680564df06b9709423523ba6e.tar.bz2 |
Add hw_{malloc,zalloc,free} functions to hw_device. Any memory
allocated using these functions is reclaimed when the corresponding
device is deleted.
Diffstat (limited to 'sim/common/hw-base.c')
-rw-r--r-- | sim/common/hw-base.c | 68 |
1 files changed, 61 insertions, 7 deletions
diff --git a/sim/common/hw-base.c b/sim/common/hw-base.c index 0c4b8a5..495f96d 100644 --- a/sim/common/hw-base.c +++ b/sim/common/hw-base.c @@ -24,10 +24,6 @@ /* LATER: #include "hwconfig.h" */ -struct hw_base_data { - int finished_p; - const struct hw_device_descriptor *descriptor; -}; extern const struct hw_device_descriptor dv_core_descriptor[]; extern const struct hw_device_descriptor dv_pal_descriptor[]; const struct hw_device_descriptor *hw_descriptors[] = { @@ -50,6 +46,11 @@ const struct hw_device_descriptor *hw_descriptors[] = { #include <ctype.h> +struct hw_base_data { + int finished_p; + const struct hw_device_descriptor *descriptor; + hw_delete_callback *to_delete; +}; static int generic_hw_unit_decode (struct hw *bus, @@ -287,6 +288,14 @@ panic_hw_port_event (struct hw *me, hw_abort (me, "no port method"); } +static void +ignore_hw_delete (struct hw *me) +{ + /* NOP */ +} + + + static const char * full_name_of_hw (struct hw *leaf, @@ -345,6 +354,7 @@ hw_create (SIM_DESC sd, const char *unit, const char *args) { + /* NOTE: HW must be allocated using ZALLOC, others use HW_ZALLOC */ struct hw *hw = ZALLOC (struct hw); /* our identity */ @@ -391,6 +401,10 @@ hw_create (SIM_DESC sd, else hw->path_of_hw = "/"; + /* create our base type */ + hw->base_of_hw = HW_ZALLOC (hw, struct hw_base_data); + hw->base_of_hw->finished_p = 0; + /* our callbacks */ set_hw_io_read_buffer (hw, panic_hw_io_read_buffer); set_hw_io_write_buffer (hw, panic_hw_io_write_buffer); @@ -402,6 +416,7 @@ hw_create (SIM_DESC sd, set_hw_unit_size_to_attach_size (hw, generic_hw_unit_size_to_attach_size); set_hw_attach_address (hw, passthrough_hw_attach_address); set_hw_detach_address (hw, passthrough_hw_detach_address); + set_hw_delete (hw, ignore_hw_delete); /* locate a descriptor */ { @@ -417,13 +432,11 @@ hw_create (SIM_DESC sd, { if (strcmp (family, entry->family) == 0) { - hw->base_of_hw = ZALLOC (struct hw_base_data); hw->base_of_hw->descriptor = entry; - hw->base_of_hw->finished_p = 0; } } } - if (hw->base_of_hw == NULL) + if (hw->base_of_hw->descriptor == NULL) { hw_abort (parent, "Unknown device `%s'", family); } @@ -465,3 +478,44 @@ hw_finish (struct hw *me) me->base_of_hw->descriptor->to_finish (me); me->base_of_hw->finished_p = 1; } + + +void +hw_delete (struct hw *me) +{ + /* give the object a chance to tidy up */ + me->base_of_hw->to_delete (me); + + /* now unlink us from the tree */ + if (hw_parent (me)) + { + struct hw **sibling = &hw_parent (me)->child_of_hw; + while (*sibling != NULL) + { + if (*sibling == me) + { + *sibling = me->sibling_of_hw; + me->sibling_of_hw = NULL; + me->parent_of_hw = NULL; + break; + } + } + } + + /* some sanity checks */ + if (hw_child (me) != NULL) + { + hw_abort (me, "attempt to delete device with children"); + } + if (hw_sibling (me) != NULL) + { + hw_abort (me, "attempt to delete device with siblings"); + } + + /* blow away all memory belonging to the device */ + hw_free_all (me); + + /* finally */ + zfree (me->base_of_hw); + zfree (me); +} |