Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of scm.gforge.inria.fr:/gitroot/simgrid/simgrid
[simgrid.git] / src / xbt / mmalloc / mmprivate.h
index 8352e13..24ca7e8 100644 (file)
    requests receive one or more whole blocks, and small requests
    receive a fragment of a block.  Fragment sizes are powers of two,
    and all fragments of a block are the same size.  When all the
-   fragments in a block have been freed, the block itself is freed.  */
+   fragments in a block have been freed, the block itself is freed.
+
+   FIXME: we are not targeting 16bits machines anymore; update values */
 
 #define INT_BIT                (CHAR_BIT * sizeof(int))
 #define BLOCKLOG       (INT_BIT > 16 ? 12 : 9)
 #define BLOCKSIZE      ((unsigned int) 1 << BLOCKLOG)
 #define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
 
+/* We keep fragment-specific meta-data for introspection purposes, and these
+ * information are kept in fixed lenght arrays. Here is the computation of
+ * that size.
+ *
+ * Never make SMALLEST_POSSIBLE_MALLOC smaller than sizeof(list) because we
+ * need to enlist the free fragments.
+ */
+
+#define SMALLEST_POSSIBLE_MALLOC (sizeof(struct list))
+#define MAX_FRAGMENT_PER_BLOCK (BLOCKSIZE / SMALLEST_POSSIBLE_MALLOC)
+
 /* The difference between two pointers is a signed int.  On machines where
    the data addresses have the high bit set, we need to ensure that the
    difference becomes an unsigned int when we are using the address as an
@@ -58,8 +71,8 @@
 #define HEAP           (INT_BIT > 16 ? 4194304 : 65536)
 
 /* Number of contiguous free blocks allowed to build up at the end of
-   memory before they will be returned to the system.  */
-
+   memory before they will be returned to the system.
+   FIXME: this is not used anymore: we never return memory to the system. */
 #define FINAL_FREE_BLOCKS      8
 
 /* Where to start searching the free list when looking for new memory.
 
 const char *xbt_thread_self_name(void);
 
+/* Doubly linked lists of free fragments.  */
+struct list {
+       struct list *next;
+       struct list *prev;
+};
+
 /* Data structure giving per-block information.
  *
  * There is one such structure in the mdp->heapinfo array,
@@ -95,17 +114,10 @@ const char *xbt_thread_self_name(void);
  *    When looking for free blocks, we traverse the mdp->heapinfo looking
  *    for a cluster of free blocks that would be large enough.
  *
- *    The size of the cluster is only to be trusted in the first block of the cluster.
- *    If the cluster results of the fusion of several clusters, the previously first
- *    block of their cluster will have partial data. The only information kept consistent over
- *    all blocks of the clusters is their type (== -1).
- *
- * Note that there is no way to determine if the block is free or busy by exploring
- * this structure only. It wasn't intended to be crawled for comparison and we should fix it (TODO).
+ *    The size of the cluster is only to be trusted in the first block of the cluster, not in the middle blocks.
  *
- * TODO: understand whether the information are written in each blocks of a cluster (be it
- * free or busy) or only in the first block of the cluster. And in the latter case, how can
- * I retrieve the first block of my cluster.
+ * The type field is consistently updated for every blocks, even within clusters of blocks.
+ * You can crawl the array and rely on that value.
  *
  * TODO:
  *  - add an indication of the requested size in each fragment, similarly to busy_block.busy_size
@@ -120,6 +132,7 @@ typedef struct {
                struct {
                        size_t nfree;           /* Free fragments in a fragmented block.  */
                        size_t first;           /* First free fragment of the block.  */
+                       unsigned short frag_size[MAX_FRAGMENT_PER_BLOCK];
                } busy_frag;
                struct {
                        size_t size; /* Size (in blocks) of a large cluster.  */
@@ -134,12 +147,6 @@ typedef struct {
        };
 } malloc_info;
 
-/* Doubly linked lists of free fragments.  */
-struct list {
-       struct list *next;
-       struct list *prev;
-};
-
 /* Internal structure that defines the format of the malloc-descriptor.
    This gets written to the base address of the region that mmalloc is
    managing, and thus also becomes the file header for the mapped file,