summaryrefslogtreecommitdiffstats
path: root/src/H5SMcache.c
diff options
context:
space:
mode:
authorJames Laird <jlaird@hdfgroup.org>2006-11-13 20:41:36 (GMT)
committerJames Laird <jlaird@hdfgroup.org>2006-11-13 20:41:36 (GMT)
commitb6c317f27cd150aa7bfc4e9cf275629570c9a319 (patch)
tree3413a54aec3bbebb821088a473f6ff425c3d39be /src/H5SMcache.c
parent77c265f26746359cf348437702c93c162f7022f6 (diff)
downloadhdf5-b6c317f27cd150aa7bfc4e9cf275629570c9a319.zip
hdf5-b6c317f27cd150aa7bfc4e9cf275629570c9a319.tar.gz
hdf5-b6c317f27cd150aa7bfc4e9cf275629570c9a319.tar.bz2
[svn-r12902] Checkin of Shared Object Header Message work.
This feature is still in progress; Shared Object Header Messages are not complete as a feature and are not thoroughly tested. There are still "TODO" comments in the code (comments with the word "JAMES" in them, so as not to be confused with other TODO comments). Hopefully this checkin will reduce the liklihood of conflicts as I finish implementing this feature. All current tests pass on juniper, copper (parallel), heping, kagiso, and mir.
Diffstat (limited to 'src/H5SMcache.c')
-rw-r--r--src/H5SMcache.c626
1 files changed, 626 insertions, 0 deletions
diff --git a/src/H5SMcache.c b/src/H5SMcache.c
new file mode 100644
index 0000000..6403dc3
--- /dev/null
+++ b/src/H5SMcache.c
@@ -0,0 +1,626 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5SM_PACKAGE /*suppress error about including H5SMpkg */
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+
+/***********/
+/* Headers */
+/***********/
+/* JAMES: these need to go first or else FILE isn't defined in H5Fpkg.h */
+/* JAMES: which of these are really needed? H5Fpkg.h, even? */
+#include "H5private.h" /* Generic Functions */
+#include "H5Aprivate.h" /* Attributes */
+#include "H5ACprivate.h" /* Metadata cache */
+#include "H5Dprivate.h" /* Datasets */
+#include "H5Eprivate.h" /* Error handling */
+
+#include "H5Fpkg.h" /* File access */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5FOprivate.h" /* File objects */
+#include "H5HLprivate.h" /* Local heaps */
+#include "H5MFprivate.h" /* File memory management */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Vprivate.h" /* Vectors and arrays */
+#include "H5SMpkg.h" /* Shared object header messages */
+#include "H5FDprivate.h" /* File drivers */
+
+/****************/
+/* Local Macros */
+/****************/
+#define H5F_TABLEBUF_SIZE H5SM_TABLE_SIZEOF_MAGIC + 20 + (H5SM_MAX_INDEXES * 26)
+/* JAMES: should this change according to address size? */
+#define H5F_LISTBUF_SIZE H5SM_LIST_SIZEOF_MAGIC + H5SM_MAX_LIST_ELEMS * 16
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/********************/
+/* Local Prototypes */
+/********************/
+static herr_t H5SM_flush_table(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_master_table_t *table);
+static H5SM_master_table_t *H5SM_load_table(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1, void *udata2);
+static herr_t H5SM_clear_table(H5F_t *f, H5SM_master_table_t *table, hbool_t destroy);
+static herr_t H5SM_dest_table(H5F_t *f, H5SM_master_table_t* table);
+static herr_t H5SM_table_size(const H5F_t *f, const H5SM_master_table_t *table, size_t *size_ptr);
+
+static herr_t H5SM_flush_list(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_list_t *list);
+static H5SM_list_t *H5SM_load_list(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1, void *udata2);
+static herr_t H5SM_clear_list(H5F_t *f, H5SM_list_t *list, hbool_t destroy);
+static herr_t H5SM_dest_list(H5F_t *f, H5SM_list_t* list);
+static herr_t H5SM_list_size(const H5F_t *f, const H5SM_list_t UNUSED *list, size_t *size_ptr);
+
+/*********************/
+/* Package Variables */
+/*********************/
+/* H5SM inherits cache-like properties from H5AC */
+const H5AC_class_t H5AC_SOHM_TABLE[1] = {{
+ H5AC_SOHM_TABLE_ID,
+ (H5AC_load_func_t) H5SM_load_table,
+ (H5AC_flush_func_t) H5SM_flush_table,
+ (H5AC_dest_func_t) H5SM_dest_table,
+ (H5AC_clear_func_t)H5SM_clear_table,
+ (H5AC_size_func_t) H5SM_table_size,
+}};
+
+const H5AC_class_t H5AC_SOHM_LIST[1] = {{
+ H5AC_SOHM_LIST_ID,
+ (H5AC_load_func_t) H5SM_load_list,
+ (H5AC_flush_func_t) H5SM_flush_list,
+ (H5AC_dest_func_t) H5SM_dest_list,
+ (H5AC_clear_func_t)H5SM_clear_list,
+ (H5AC_size_func_t) H5SM_list_size,
+}};
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_flush_table
+ *
+ * Purpose: Flushes (and destroys) the table of Shared Object Header
+ * Message indexes.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * November 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5SM_flush_table(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_master_table_t *table)
+{
+ herr_t ret_value=SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5SM_flush_table, FAIL)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(table);
+
+ if (table->cache_info.is_dirty) {
+ uint8_t buf[H5F_TABLEBUF_SIZE]; /* Temporary buffer */ /* JAMES This is big. Do I need to use H5FL_BLK_MALLOC instead? */
+ uint8_t *p; /* Pointer into raw data buffer */
+ size_t size; /* Header size on disk */
+ int x; /* Counter variable */
+
+ /* Encode the master table and all of the index headers as one big blob */
+ size = H5SM_TABLE_SIZE(f) + (H5SM_INDEX_HEADER_SIZE(f) * table->num_indexes);
+
+ /* Encode the master table */
+ p = buf;
+
+ /* Encode magic number */
+ HDmemcpy(p, H5SM_TABLE_MAGIC, (size_t)H5SM_TABLE_SIZEOF_MAGIC);
+ p += H5SM_TABLE_SIZEOF_MAGIC;
+
+ *p++ = HDF5_SOHMTABLE_VERSION; /* Version */
+
+ *p++ = table->num_indexes; /* Number of indexes in the table */
+
+ /* Encode each index header */
+ for(x=0; x<table->num_indexes; ++x) {
+ *p++ = table->indexes[x].index_type; /* Is message index a list or a B-tree? */
+
+ UINT16ENCODE(p, table->indexes[x].mesg_types); /* Type of messages in the index */
+
+ UINT16ENCODE(p, table->indexes[x].list_to_btree); /* List cutoff; fewer than this number and index becomes a list */
+ UINT16ENCODE(p, table->indexes[x].btree_to_list); /* B-tree cutoff; more than this number and index becomes a B-tree */
+ UINT16ENCODE(p, table->indexes[x].num_messages); /* Number of messages shared */
+ H5F_addr_encode(f, &p, table->indexes[x].index_addr); /* Address of the actual index */
+ H5F_addr_encode(f, &p, table->indexes[x].heap_addr); /* Address of the index's heap */
+ }
+
+ /* Write the table to disk */
+ HDassert((size_t)(p - buf) == size);
+ if(H5F_block_write(f, H5FD_MEM_SOHM, addr, size, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to save sohm table to disk")
+
+ table->cache_info.is_dirty = FALSE;
+ }
+
+ if(destroy)
+ if(H5SM_dest_table(f, table) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy sohm table")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5SM_flush_table */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_load_table
+ *
+ * Purpose: Loads the master table of Shared Object Header Message
+ * indexes.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * November 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5SM_master_table_t *
+H5SM_load_table(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void UNUSED *udata2)
+{
+ H5SM_master_table_t *table; /* The SOHM table being read in */
+ size_t table_size; /* Size of SOHM master table on disk */
+ size_t indexes_size; /* Size of index headers on disk */
+ uint8_t *buf=NULL; /* Reading buffer */
+ uint8_t *p; /* Pointer into input buffer */
+ uint8_t x; /* Counter variable for index headers */
+ H5SM_master_table_t *ret_value;
+
+ FUNC_ENTER_NOAPI(H5SM_load_table, NULL)
+
+ /* Allocate space for the SOHM table data structure */
+ if(NULL == (table = H5MM_calloc(sizeof(H5SM_master_table_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Compute the size of the SOHM table header on disk. Read in just the table first */
+ table_size = H5SM_TABLE_SIZE(f);
+
+ /* Allocate temporary buffer */
+ if(NULL == (buf = HDmalloc(table_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Read header from disk */
+ if(H5F_block_read(f, H5FD_MEM_SOHM, addr, table_size, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_READERROR, NULL, "can't read SOHM table")
+
+ p = buf;
+
+ /* Check magic number */
+ if(HDmemcmp(p, H5SM_TABLE_MAGIC, (size_t)H5SM_TABLE_SIZEOF_MAGIC))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM table signature");
+ p += H5SM_TABLE_SIZEOF_MAGIC;
+
+ /* Version number */
+ if (HDF5_SOHMTABLE_VERSION != *p++)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unknown SOHM table version number")
+
+ table->num_indexes = *p++; /* Number of indexes in the table */
+
+ HDassert((size_t)(p - buf) == table_size);
+
+ /* Allocate space for the index headers */
+ if(NULL == (table->indexes = H5FL_ARR_MALLOC(H5SM_index_header_t, table->num_indexes)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for SOHM indexes")
+
+ /* Now read in the list of index headers */
+ indexes_size = table->num_indexes * H5SM_INDEX_HEADER_SIZE(f);
+
+ /* Re-allocate temporary buffer */
+ HDassert(buf);
+ HDfree(buf);
+ if(NULL == (buf = HDmalloc(indexes_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+
+ if(H5F_block_read(f, H5FD_MEM_SOHM, addr + table_size, indexes_size, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_READERROR, NULL, "can't read SOHM table")
+ p=buf;
+
+ for(x=0; x<table->num_indexes; ++x) {
+ table->indexes[x].index_type= *p++; /* type of the index (list or B-tree) */
+
+ UINT16DECODE(p, table->indexes[x].mesg_types);
+ UINT16DECODE(p, table->indexes[x].list_to_btree);
+ UINT16DECODE(p, table->indexes[x].btree_to_list);
+ UINT16DECODE(p, table->indexes[x].num_messages);
+ H5F_addr_decode(f, &p, &(table->indexes[x].index_addr));
+ H5F_addr_decode(f, &p, &(table->indexes[x].heap_addr));
+ }
+
+ HDassert((size_t)(p - buf) == indexes_size);
+ ret_value = table;
+
+done:
+ /* Free buffer if it was allocated */
+ if(buf)
+ HDfree(buf);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5SM_load_table */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_clear_table
+ *
+ * Purpose: Mark this table as no longer being dirty.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * November 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5SM_clear_table(H5F_t *f, H5SM_master_table_t *table, hbool_t destroy)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5SM_clear_table)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(table);
+
+ /* Reset the dirty flag. */
+ table->cache_info.is_dirty = FALSE;
+
+ if(destroy)
+ if(H5SM_dest_table(f, table) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to delete SOHM master table")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5SM_clear_table */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_dest_table
+ *
+ * Purpose: Frees memory used by the SOHM table.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * November 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5SM_dest_table(H5F_t *f, H5SM_master_table_t* table)
+{
+ FUNC_ENTER_NOAPI_NOFUNC(H5SM_dest_table)
+
+ assert(table);
+
+ assert(table->indexes);
+
+ H5FL_ARR_FREE(H5SM_index_header_t, table->indexes);
+
+ H5MM_free(table);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5SM_dest_table */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_table_size
+ *
+ * Purpose: Returns the size of the table encoded on disk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * November 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5SM_table_size(const H5F_t *f, const H5SM_master_table_t *table, size_t *size_ptr)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_table_size)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(table);
+ HDassert(size_ptr);
+
+ /* Set size value */
+ *size_ptr = H5SM_TABLE_SIZE(f) + (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f));
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5SM_table_size */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_flush_list
+ *
+ * Purpose: Flush this list index.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * November 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5SM_flush_list(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_list_t *list)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5SM_flush_list, FAIL)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(list);
+ HDassert(list->header);
+
+ if (list->cache_info.is_dirty) {
+ uint8_t buf[H5F_LISTBUF_SIZE]; /* Temporary buffer */ /* JAMES Do I need to use H5FL_BLK_MALLOC instead? */
+ uint8_t *p; /* Pointer into raw data buffer */
+ size_t size; /* Header size on disk */
+ hsize_t x;
+
+ size = H5SM_LIST_SIZE(f, list->header->num_messages);
+
+ /* Encode the list */
+ p = buf;
+
+ /* Encode magic number */
+ HDmemcpy(p, H5SM_LIST_MAGIC, (size_t)H5SM_LIST_SIZEOF_MAGIC);
+ p += H5SM_LIST_SIZEOF_MAGIC;
+
+ /* Write messages from the messages array to disk */
+ /* JAMES: we have to search the whole array. not the best way to do it; could go until we've written
+ * num_messages */
+ for(x=0; x<list->header->list_to_btree; x++) {
+ if(list->messages[x].fheap_id != 0 && list->messages[x].hash != H5O_HASH_UNDEF) {
+ /* JAMES: use H5SM_message_encode here */
+ UINT32ENCODE(p, list->messages[x].hash); /* Read the hash value for this message */
+ UINT16ENCODE(p, list->messages[x].ref_count); /* Read the reference count for this message */
+ UINT64ENCODE(p, list->messages[x].fheap_id); /* Get the heap ID for the message */
+ }
+ }
+
+ /* Write the list to disk */
+ HDassert((size_t)(p - buf) == size);
+ if(H5F_block_write(f, H5FD_MEM_SOHM, addr, size, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to save sohm table to disk")
+
+ list->cache_info.is_dirty = FALSE;
+ }
+
+ if(destroy)
+ if(H5SM_dest_list(f, list) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy list")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5SM_flush_list */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_load_list
+ *
+ * Purpose: Loads a list of SOHM messages.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * November 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5SM_list_t *
+H5SM_load_list(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void *udata2)
+{
+ H5SM_list_t *list; /* The SOHM list being read in */
+ H5SM_index_header_t *header = (H5SM_index_header_t *) udata2; /* Index header for this list */
+ size_t size; /* Size of SOHM list on disk */
+ uint8_t *buf = NULL; /* Reading buffer */
+ uint8_t *p; /* Pointer into input buffer */
+ hsize_t x; /* Counter variable for messages in list */
+ H5SM_list_t *ret_value=NULL;
+
+ FUNC_ENTER_NOAPI(H5SM_load_list, NULL)
+
+ HDassert(header);
+
+ /* Allocate space for the SOHM list data structure and initialize list JAMES don't need to initialize all of list */
+ if(NULL == (list = H5FL_MALLOC(H5SM_list_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HDmemset(&list->cache_info, 0, sizeof(H5AC_info_t));
+
+ /* Allocate list in memory as an array*/
+ if((list->messages = H5FL_ARR_MALLOC(H5SM_sohm_t, header->list_to_btree)) == NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "file allocation failed for SOHM list")
+
+ list->header = header;
+
+ /* Compute the size of the SOHM list on disk */
+ size = H5SM_LIST_SIZE(f, header->num_messages);
+
+ /* Allocate temporary buffer */
+ /* JAMES: is BLK_MALLOC somehow better for this? */
+ if(NULL == (buf = HDmalloc(size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Read list from disk */
+ if(H5F_block_read(f, H5FD_MEM_SOHM, addr, size, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_READERROR, NULL, "can't read SOHM list")
+ p = buf;
+
+ /* Check magic number */
+ if(HDmemcmp(p, H5SM_LIST_MAGIC, (size_t)H5SM_LIST_SIZEOF_MAGIC))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM list signature");
+ p += H5SM_LIST_SIZEOF_MAGIC;
+
+ /* Read messages into the list array */
+ for(x=0; x<header->num_messages; x++)
+ {
+ UINT32DECODE(p, list->messages[x].hash); /* Read the hash value for this message */
+ UINT16DECODE(p, list->messages[x].ref_count); /* Read the reference count for this message */
+ UINT64DECODE(p, list->messages[x].fheap_id); /* Get the heap ID for the message */
+ }
+
+ /* Initialize the rest of the array */
+ for(x=header->num_messages; x<header->list_to_btree; x++)
+ {
+ list->messages[x].fheap_id = 0; /* JAMES: would making this one operation make it faster? */
+ list->messages[x].hash = H5O_HASH_UNDEF;
+ }
+
+ HDassert((size_t)(p - buf) == size);
+
+ ret_value = list;
+done:
+ if(buf)
+ HDfree(buf);
+
+ if(ret_value == NULL) {
+ if(list) {
+ if(list->messages) {
+ H5FL_ARR_FREE(H5SM_sohm_t, list->messages);
+ }
+ H5FL_FREE(H5SM_list_t, list);
+ }
+ }
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5SM_load_list */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_clear_list
+ *
+ * Purpose: Marks a list as not dirty.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * November 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5SM_clear_list(H5F_t *f, H5SM_list_t *list, hbool_t destroy)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5SM_clear_list)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(list);
+
+ /* Reset the dirty flag. */
+ list->cache_info.is_dirty = FALSE;
+
+ if(destroy)
+ if(H5SM_dest_list(f, list) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy SOHM list")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end of H5SM_clear_list */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_dest_list
+ *
+ * Purpose: Frees all memory used by the list.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * November 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5SM_dest_list(H5F_t *f, H5SM_list_t* list)
+{
+ FUNC_ENTER_NOAPI_NOFUNC(H5SM_dest_list)
+
+ HDassert(list);
+ HDassert(list->messages);
+
+ H5FL_ARR_FREE(H5SM_sohm_t, list->messages);
+
+ H5FL_FREE(H5SM_list_t, list);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5SM_dest_list */
+
+
+/* JAMES: should this number be constant, or should it increase and decrease as
+ * messages are added and removed? */
+/*-------------------------------------------------------------------------
+ * Function: H5SM_list_size
+ *
+ * Purpose: Gets the size of a list on disk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * November 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5SM_list_size(const H5F_t *f, const H5SM_list_t *list, size_t *size_ptr)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_list_size)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(list);
+ HDassert(list->header);
+ HDassert(size_ptr);
+
+ /* Set size value */
+ *size_ptr = H5SM_LIST_SIZE(f, list->header->list_to_btree); /* JAMES: might want to have variable-sized lists */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5SM_list_size */
+
+
+