00001
00002 #ifndef MEMPOOL_H
00003 #define MEMPOOL_H
00004
00005 #include "conv-config.h"
00006 #include "converse.h"
00007
00008 #if CMK_CONVERSE_UGNI
00009 #include "gni_pub.h"
00010 #include "pmi.h"
00011 typedef gni_mem_handle_t mem_handle_t;
00012 #else
00013
00014
00015 typedef CmiInt8 mem_handle_t;
00016 #endif
00017
00018 typedef void* (*mempool_newblockfn)(size_t* size, mem_handle_t* mem_hndl, int expand_flag);
00019 typedef void (*mempool_freeblock)(void* ptr, mem_handle_t mem_hndl);
00020
00021 #define cutOffNum CMK_MEMPOOL_CUTOFFNUM
00022
00023
00024 #define MEMPOOL_GetBlockHead(x) (&((x)->block_head))
00025
00026 #define MEMPOOL_GetBlockSize(x) ((x)->size)
00027 #define MEMPOOL_GetBlockMemHndl(x) ((x)->mem_hndl)
00028 #define MEMPOOL_GetBlockNext(x) ((x)->block_next)
00029
00030 #define MEMPOOL_GetMempoolHeader(x, align) \
00031 ((mempool_header*)((char*)(x) - (align)))
00032
00033 #define MEMPOOL_GetBlockPtr(x) ((x)->block_ptr)
00034 #define MEMPOOL_GetMempoolPtr(x) (MEMPOOL_GetBlockPtr(x)->mptr)
00035 #define MEMPOOL_GetSize(x) (MEMPOOL_GetBlockPtr(x)->size)
00036 #define MEMPOOL_GetMemHndl(x) (MEMPOOL_GetBlockPtr(x)->mem_hndl)
00037 #define MEMPOOL_GetMsgInRecv(x) (MEMPOOL_GetBlockPtr(x)->msgs_in_recv)
00038 #define MEMPOOL_GetMsgInSend(x) (MEMPOOL_GetBlockPtr(x)->msgs_in_send)
00039 #define MEMPOOL_IncMsgInRecv(x) (MEMPOOL_GetBlockPtr(x)->msgs_in_recv)++
00040 #define MEMPOOL_DecMsgInRecv(x) (MEMPOOL_GetBlockPtr(x)->msgs_in_recv)--
00041 #define MEMPOOL_IncMsgInSend(x) (MEMPOOL_GetBlockPtr(x)->msgs_in_send)++
00042 #define MEMPOOL_DecMsgInSend(x) (MEMPOOL_GetBlockPtr(x)->msgs_in_send)--
00043 #define MEMPOOL_GetSlotGNext(x) ((x)->gnext)
00044 #define MEMPOOL_GetSlotStatus(x) ((x)->status)
00045 #define MEMPOOL_GetSlotSize(x) ((x)->size)
00046 struct block_header;
00047 struct mempool_type;
00048
00049
00050 typedef struct slot_header_
00051 {
00052 struct block_header* block_ptr;
00053 size_t size;
00054 int power, status;
00055 size_t gprev, gnext;
00056 size_t prev, next;
00057 #if CMK_64BIT
00058 int padding[2];
00059 #endif
00060 } slot_header;
00061
00062 typedef struct used_header_
00063 {
00064 struct block_header* block_ptr;
00065 size_t size;
00066 int power, status;
00067 size_t gprev, gnext;
00068 int padding[2];
00069 } used_header;
00070
00071 typedef used_header mempool_header;
00072
00073
00074
00075 typedef struct block_header
00076 {
00077 mem_handle_t mem_hndl;
00078 size_t size, used;
00079 size_t block_prev, block_next;
00080 struct mempool_type* mptr;
00081 #if CMK_CONVERSE_UGNI
00082 int msgs_in_send;
00083 int msgs_in_recv;
00084 #define freelists_extra (sizeof(mem_handle_t) + sizeof(struct mempool_type*) + 2 * sizeof(int))
00085 #else
00086 #define freelists_extra (sizeof(mem_handle_t) + sizeof(struct mempool_type*))
00087 #endif
00088
00089 size_t freelists[cutOffNum + CMIPADDING(cutOffNum * sizeof(size_t) + freelists_extra, 16) / sizeof(size_t)];
00090 #undef freelists_extra
00091 } block_header;
00092
00093 typedef struct large_block_header
00094 {
00095 mem_handle_t mem_hndl;
00096 size_t size;
00097 size_t block_prev, block_next;
00098 struct mempool_type* mptr;
00099 #if CMK_CONVERSE_UGNI
00100 int msgs_in_send;
00101 int msgs_in_recv;
00102 #endif
00103 int padding[2];
00104 } large_block_header;
00105
00106
00107 typedef struct mempool_type
00108 {
00109 block_header block_head;
00110 mempool_newblockfn newblockfn;
00111 mempool_freeblock freeblockfn;
00112 size_t large_blocks;
00113 size_t block_tail;
00114 size_t limit;
00115 size_t size;
00116 #if CMK_USE_MEMPOOL_ISOMALLOC || (CMK_SMP && CMK_CONVERSE_UGNI)
00117 CmiNodeLock mempoolLock;
00118 char padding[CMIPADDING((6 * sizeof(size_t) + sizeof(CmiNodeLock)), 16)];
00119 #elif !CMK_64BIT
00120 size_t padding[2];
00121 #endif
00122 } mempool_type;
00123
00124 #ifdef __cplusplus
00125 static_assert(sizeof(slot_header) % 16 == 0, "slot_header is not a multiple of 16 bytes");
00126 static_assert(sizeof(used_header) % 16 == 0, "used_header is not a multiple of 16 bytes");
00127 static_assert(sizeof(block_header) % 16 == 0, "block_header is not a multiple of 16 bytes");
00128 static_assert(sizeof(large_block_header) % 16 == 0, "large_block_header is not a multiple of 16 bytes");
00129 static_assert(sizeof(mempool_type) % 16 == 0, "mempool_type is not a multiple of 16 bytes");
00130
00131 extern "C" {
00132 #endif
00133
00134 mempool_type* mempool_init(size_t pool_size, mempool_newblockfn newfn, mempool_freeblock freefn, size_t limit);
00135 void mempool_destroy(mempool_type* mptr);
00136 void* mempool_malloc(mempool_type* mptr, size_t size, int expand);
00137 void* mempool_large_malloc(mempool_type* mptr, size_t size, int expand);
00138 void mempool_free(mempool_type* mptr, void* ptr_free);
00139 #if CMK_USE_MEMPOOL_ISOMALLOC || (CMK_SMP && CMK_CONVERSE_UGNI)
00140 void mempool_free_thread(void* ptr_free);
00141 #endif
00142
00143 #if defined(__cplusplus)
00144 }
00145 #endif
00146
00147 #if CMK_CONVERSE_UGNI
00148 void* getNextRegisteredPool();
00149 #endif
00150
00151 #endif