usermode/library/pmalloc/src/vhalloc.c

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2011 Computer Sciences Department, 
00003     University of Wisconsin -- Madison
00004 
00005     ----------------------------------------------------------------------
00006 
00007     This file is part of Mnemosyne: Lightweight Persistent Memory, 
00008     originally developed at the University of Wisconsin -- Madison.
00009 
00010     Mnemosyne was originally developed primarily by Haris Volos
00011     with contributions from Andres Jaan Tack.
00012 
00013     ----------------------------------------------------------------------
00014 
00015     Mnemosyne is free software; you can redistribute it and/or
00016     modify it under the terms of the GNU General Public License
00017     as published by the Free Software Foundation, version 2
00018     of the License.
00019  
00020     Mnemosyne is distributed in the hope that it will be useful,
00021     but WITHOUT ANY WARRANTY; without even the implied warranty of
00022     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023     GNU General Public License for more details.
00024 
00025     You should have received a copy of the GNU General Public License
00026     along with this program; if not, write to the Free Software
00027     Foundation, Inc., 51 Franklin Street, Fifth Floor, 
00028     Boston, MA  02110-1301, USA.
00029 
00030 ### END HEADER ###
00031 */
00032 
00040 #define VHALLOC_PREGION_BASE          0xc00000000
00041 #define VHALLOC_PREGION_METADATA_SIZE (1024*1024)        /* Bytes */
00042 #define VHALLOC_PREGION_HOLE_SIZE     0
00043 #define VHALLOC_PREGION_HEAP_SIZE     (1024*1024*1024)   /* Bytes */
00044 
00045 /*
00046  * A single persistent region is allocated to store the two vistaheap_s 
00047  * structures, the nugget metadata, and the allocated chunks. 
00048  *
00049  * +-------------------------------------------------------------------------+
00050  * |                                                                         |
00051  * |  +------------------+  +--------------------+                           |
00052  * |  | main vistaheap_s |  | nugget vistaheap_s |                           |
00053  * |  +------------------+  +--------------------+                           |
00054  * |                                                                         |
00055  * +-------------------------------------------------------------------------+  
00056  * | Nugget metadata kept here                                               |
00057  * |                                                                         |
00058  * +-------------------------------------------------------------------------+  
00059  * | Chunks allocated here                                                   |
00060  * |                                                                         |
00061  * |                                                                         |
00062  *                                      ... 
00063  * |                                                                         |
00064  * +-------------------------------------------------------------------------+  
00065  *
00066  */
00067 
00068 #include <mnemosyne.h>
00069 #include <stdint.h>
00070 #include <stdlib.h>
00071 #include <sys/mman.h>
00072 #include <pcm.h>
00073 #include "vistaheap.h"
00074 #include "genalloc.h"
00075 #include "vhalloc.h"
00076 
00077 
00078 __attribute__ ((section("PERSISTENT"))) int      vhalloc_init_done = 0; 
00079 __attribute__ ((section("PERSISTENT"))) uint64_t vhalloc_pregion = 0x0;
00080 
00081 static int       volatile_init_done = 0; 
00082 static vistaheap *vistaheap_main;
00083 static vistaheap *vistaheap_nugget;
00084 
00085 TM_PURE static inline
00086 void
00087 _init(void)
00088 {
00089         size_t         size;
00090         void           *metadata_base;           
00091         void           *metadata_hardlimit;
00092         void           *heap_base;           
00093         void           *heap_hardlimit;
00094 
00095         if (vhalloc_init_done) {
00096                 if (!volatile_init_done) {
00097                         vistaheap_main = (vistaheap *) vhalloc_pregion;
00098                         vistaheap_nugget = (vistaheap *) (vhalloc_pregion + sizeof(vistaheap));
00099                         volatile_init_done = 1;
00100                 }       
00101                 return;
00102         }
00103 
00104         if (vhalloc_pregion == 0x0) {
00105                 size = sizeof(vistaheap) * 2 + 
00106                            VHALLOC_PREGION_METADATA_SIZE + 
00107                            VHALLOC_PREGION_HOLE_SIZE + 
00108                            VHALLOC_PREGION_HEAP_SIZE;
00109             TM_WAIVER {
00110                         vhalloc_pregion = (uint64_t) m_pmap((void *) VHALLOC_PREGION_BASE, size, PROT_READ|PROT_WRITE, 0);
00111                 }       
00112                 if ((void *) vhalloc_pregion == (void *) -1) {
00113                         TM_WAIVER {
00114                                 abort();
00115                         }       
00116                 }
00117         }
00118 
00119         vistaheap_main = (vistaheap *) vhalloc_pregion;
00120         vistaheap_nugget = (vistaheap *) (vhalloc_pregion + sizeof(vistaheap));
00121         metadata_base = (void *) (vhalloc_pregion + sizeof(vistaheap)*2);
00122         metadata_hardlimit = (void *) (((uintptr_t) metadata_base) + VHALLOC_PREGION_METADATA_SIZE);
00123         heap_base = (void *) (((uintptr_t) metadata_hardlimit) + VHALLOC_PREGION_HOLE_SIZE);
00124         heap_hardlimit = (void *) (((uintptr_t) heap_base) + VHALLOC_PREGION_HEAP_SIZE);
00125 
00126         __tm_atomic 
00127         {
00128                 vistaheap_init(vistaheap_nugget, metadata_base, metadata_hardlimit, NULL);
00129                 vistaheap_init(vistaheap_main, heap_base, heap_hardlimit, vistaheap_nugget);
00130                 vhalloc_init_done = 1;
00131         } 
00132         volatile_init_done = 1;
00133 }
00134 
00135 struct header_s {
00136         size_t sz;
00137 };
00138 
00139 
00140 size_t VHALLOC_OBJSIZE(void *ptr)
00141 {
00142         struct header_s* header_ptr;
00143         header_ptr = (struct header_s *) ((char *)ptr - sizeof(struct header_s));
00144         return header_ptr->sz;
00145 }
00146 
00147 
00148 void *
00149 VHALLOC_PMALLOC(size_t sz)
00150 {
00151         void *ptr;
00152         struct header_s* header_ptr;
00153         _init();
00154         /* HACK: Vistaheap does not track size so we track it in a header ourselves */
00155         ptr = vistaheap_malloc(vistaheap_main, sz + sizeof(struct header_s));
00156         header_ptr = (struct header_s *) ptr;
00157         header_ptr->sz = sz;
00158         return (void *) ((char *) ptr + sizeof(struct header_s));
00159 }
00160 
00161 
00162 void 
00163 vhalloc_pfree(void *ptr)
00164 {
00165         //TODO
00166 }

Generated on Sat Apr 23 11:43:36 2011 for Mnemosyne by  doxygen 1.4.7