#define MMALLOC_MAGIC "mmalloc" /* Mapped file magic number */
#define MMALLOC_MAGIC_SIZE 8 /* Size of magic number buf */
-#define MMALLOC_VERSION 1 /* Current mmalloc version */
+#define MMALLOC_VERSION 2 /* Current mmalloc version */
/* The allocator divides the heap into blocks of fixed size; large
requests receive one or more whole blocks, and small requests
#define ADDRESS(B) ((void*) (((ADDR2UINT(B)) - 1) * BLOCKSIZE + (char*) mdp -> heapbase))
-const char *xbt_thread_self_name(void);
-
/* Doubly linked lists of free fragments. */
struct list {
struct list *next;
/* Data structure giving per-block information.
*
- * There is one such structure in the mdp->heapinfo array,
- * that is addressed by block number.
+ * There is one such structure in the mdp->heapinfo array per block used in that heap,
+ * the array index is the block number.
*
* There is several types of blocks in memory:
* - full busy blocks: used when we are asked to malloc a block which size is > BLOCKSIZE/2
* 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
* - make room to store the backtrace of where the blocks and fragment were malloced, too.
*/
typedef 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];
+ //void *bt[XBT_BACKTRACE_SIZE][MAX_FRAGMENT_PER_BLOCK]; /* Where it was malloced (or realloced lastly) */
} busy_frag;
struct {
size_t size; /* Size (in blocks) of a large cluster. */
size_t busy_size; /* Actually used space, in bytes */
+ void *bt[XBT_BACKTRACE_SIZE]; /* Where it was malloced (or realloced lastly) */
+ int bt_size;
} busy_block;
/* Heap information for a free block (that may be the first of a free cluster). */
struct {
/* Semaphore locking the access to the heap */
sem_t sem;
+ char locked;
/* Number of processes that attached the heap */
unsigned int refcount;
};
-int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap_addr);
+int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2);
void mmalloc_display_info(void *h);
like sbrk(), but using mmap(). */
extern void *mmorecore(struct mdesc *mdp, int size);
-/* Thread-safety (if the sem is already created) FIXME: KILLIT*/
-#define LOCK(mdp) \
- sem_wait(&mdp->sem)
-
-#define UNLOCK(mdp) \
- sem_post(&mdp->sem)
+/* Thread-safety (if the sem is already created)
+ *
+ * This is mandatory in the case where the user runs a parallel simulation
+ * in a model-checking enabled tree. Without this protection, our malloc
+ * implementation will not like multi-threading AT ALL.
+ */
+#define LOCK(mdp) do { \
+ if (0 && mdp->locked) { \
+ fprintf(stderr,"panic! deadlock detected because %s is not reintrant.\n",__FUNCTION__); \
+ abort(); \
+ } \
+ sem_wait(&mdp->sem); \
+ mdp->locked=1; \
+ } while(0)
+
+#define UNLOCK(mdp) do { \
+ sem_post(&mdp->sem); \
+ mdp->locked=0; \
+ } while (0)
#endif /* __MMPRIVATE_H */