00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 #include "src/common/shared.hpp"
00019 #include "src/common/blist.hpp"
00020 #include "src/common/blistsort.hpp"
00021 #include "src/memory/align.hpp"
00022 #include "src/memory/memset.hpp"
00023 #include "src/memory/heap.hpp"
00024 #include "src/memory/mmap.hpp"
00025 
00026 
00027 int mmapcompar(const void *a, const void *b)
00028  {
00029 uint32 A, B;
00030         A= bli_dt(a,mmap_s*)->start;
00031         B= bli_dt(b,mmap_s*)->start;
00032 
00033         if (A>B)
00034                 return 1;
00035         if (A<B)
00036                 return -1;
00037         return 0;
00038  }
00039 
00040 
00041 void mmap_t::init(uint32 start, uint32 end, class Memory::Heap::heapbox *hp)
00042  {
00043 
00044         memset(this, 0, sizeof(mmap_t));
00045 
00046         lock_mmap.init(const_cast<char*>("mmap"));
00047         range_lo = start; range_hi = end;
00048         heap=hp;
00049         map.init(FAC_MMAP|FAC_MEMREG, hp);
00050  }
00051 
00052 
00053 void mmap_t::done()
00054  {
00055 blist_s *item, *next;
00056 
00057         item=map.head;
00058         while (item)
00059          {
00060                 next = item->next;
00061                 if (bli_dt(item,mmap_s*)->destroy)
00062 
00063                         bli_dt(item,mmap_s*)->destroy(this,bli_dt(item,mmap_s*));
00064                 heap->free(item->data);
00065                 map.del(item);
00066                 item = next;
00067          }
00068 
00069         memset(this, 0, sizeof(mmap_t));
00070  }
00071 
00072 
00073 blist_s *mmap_t::madd(uint32 start, size_t size, uint32 type, void *dt, uint64 info, int threadno, int (*destroy)(mmap_t*,mmap_s*))
00074  {
00075 
00076 mmap_s reg;
00077         memset(®, 0, sizeof(reg));
00078         reg.start=start;
00079         reg.size=size;
00080         reg.end=start+size;
00081         reg.type=type;
00082         reg.dt=dt;
00083         reg.info=info;
00084         reg.thread= threadno;
00085         reg.destroy=destroy;
00086 
00087         return blistsort_add(&map, ®, sizeof(reg), NULL, &mmapcompar);
00088  }
00089 
00090 
00091 int mmap_t::mdel(blist_s *item) {
00092         return map.del(item);
00093  }
00094 
00095 int mmap_t::mdel(mmap_s *item)
00096  {
00097 blist_s *i;
00098         for(i=map.head;i;i=i->next)
00099                 if (bli_dt(i,mmap_s*)==item)
00100                         return mdel(i);
00101         return EINVAL;
00102  }
00103 
00104 
00105 blist_s *mmap_t::mfind(uint32 start)
00106  {
00107 blist_s *item;
00108         for (item=map.head;item;item=item->next)
00109                 if (bli_dt(item,mmap_s*)->start==start)
00110                         return item;
00111         return NULL;
00112  }
00113 
00114 
00115 blist_s *mmap_t::lower (uint32 start)
00116  {
00117 blist_s *item;
00118 
00119 
00120 
00121 
00122 
00123 
00124         for (item=map.head;item;item=item->next)
00125                 if (bli_dt(item,mmap_s*)->start > start)
00126                         break;
00127         if (!item) {
00128                 if (!map.head)
00129                         return NULL;
00130                 else
00131                         return map.tail;
00132    }
00133         return item->prev;
00134  }
00135 
00136 
00137 blist_s *mmap_t::higher (uint32 start)
00138  {
00139 blist_s *item;
00140         for (item=map.tail;item;item=item->prev)
00141                 if (bli_dt(item,mmap_s*)->start < start)
00142                         break;
00143         if (!item) {
00144                 if (!map.head)
00145                         return NULL;
00146                 else
00147                         return map.head;
00148    }
00149         return item->next;
00150  }
00151  
00152 
00153 uint32 mmap_t::lgth()
00154  {
00155 blist_s *item;
00156 uint32 i=0;
00157         for (item=map.head;item;item=item->next) i++;
00158         return i;
00159  }
00160 
00161 
00162 
00163 
00164 int mmap_t::mfirstfit(uint32 size, uint32 alignment, uint32 *loc) {
00165         return mfitabove(size, alignment, range_lo, loc, FALSE);
00166  }
00167 
00168 
00169 int mmap_t::mlastfit (uint32 size, uint32 alignment, uint32 *loc) {
00170         return mfitbelow(size, alignment, range_hi, loc, FALSE);
00171  }
00172 
00173 
00174 int mmap_t::mfitabove(uint32 size, uint32 alignment, uint32 min, uint32 *loc, bool force)
00175  {
00176 blist_s *item = higher(min);
00177 
00178         if (item == NULL) {
00179         
00180                 if (range_hi >= size + align_up(min,alignment))
00181                  { *loc= align_up(min,alignment); return ESUCCESS; }
00182                 else
00183                         return EINVAL;  
00184    }
00185 
00186 
00187         if (bli_dt(item,mmap_s*)->start > min)
00188                 if (bli_dt(item,mmap_s*)->start - align_up(min, alignment) >= size)             
00189                 { *loc= align_up(min, alignment); return ESUCCESS; }
00190 
00191 
00192         for (item=item; item; item = item->next)
00193          {
00194         
00195                 if (item -> next)
00196                 
00197                         {if (bli_dt(item->next,mmap_s*)->start - align_up(bli_dt(item,mmap_s*)->end, alignment) >= size)
00198                                 {*loc=align_up(bli_dt(item,mmap_s*)->end, alignment); return ESUCCESS;} }
00199                         else
00200                 
00201                                 if (range_hi - align_up(bli_dt(item,mmap_s*)->end, alignment) >= size)
00202                                         {*loc= align_up(bli_dt(item,mmap_s*)->end, alignment); return ESUCCESS; }
00203          }
00204 
00205         if (force)
00206         if (min > range_lo)
00207                 return mfitabove(size, alignment, range_lo, loc, FALSE);
00208 
00209         return EINVAL;
00210  }
00211 
00212 
00213 int mmap_t::mfitbelow(uint32 size, uint32 alignment, uint32 max, uint32 *loc, bool force)
00214  {
00215 blist_s *inode = lower(max);
00216 mmap_s *reg;
00217 uint32 high_lim;        
00218 int i = ESUCCESS;
00219 
00220         if (lgth() == 0) {
00221         
00222 
00223                 if (align_down(max-size,alignment) >= range_lo)
00224                         { *loc=align_down(max-size,alignment);return ESUCCESS;}
00225 
00226                 else
00227                         return EINVAL;  
00228    }
00229 
00230         reg = bli_dt(inode,mmap_s*);
00231 
00232         if (reg->end < max)
00233         if (align_down (max - size, alignment) >= reg->end)
00234                 { *loc= align_down(max - size, alignment); return ESUCCESS;}
00235         high_lim = reg->start;
00236 
00237         while (i == ESUCCESS)
00238          {
00239                 if (align_down (high_lim - size, alignment) >= reg->end)
00240                         {*loc= align_down(high_lim-size, alignment); return ESUCCESS;}
00241         
00242                 inode = inode->prev;
00243                 if (inode == NULL)
00244                         { i = EINVAL; break; }
00245                 high_lim=reg->start;
00246                 reg = bli_dt(inode,mmap_s*);
00247          }
00248 
00249         inode = map.head;
00250         reg=bli_dt(inode,mmap_s*);
00251         if (align_down (reg->start - size,alignment) >= range_lo)
00252                 { *loc= align_down (reg->start - size, alignment); return ESUCCESS;}
00253 
00254         if (force)
00255         if (max < range_hi)
00256                 return mfitabove(size, alignment, range_hi, loc, FALSE);
00257 
00258         return EINVAL;
00259  }
00260 
00261 
00262 
00263 
00264 blist_s *mmap_t::add(uint32 start, size_t size, uint32 type, void *dt, uint64 info, int threadno, int (*destroy)(mmap_t*,mmap_s*))
00265  {
00266 blist_s *i;
00267         lock_mmap.lock();
00268         i= madd(start,size,type,dt,info,threadno,destroy);
00269         lock_mmap.ulock();
00270 
00271         return i;
00272  }
00273 
00274 
00275 blist_s *mmap_t::mmap_find(uint32 type, uint32 virt)
00276  {
00277 blist_s *item;
00278 blist_s *el = NULL;
00279 mmap_s *quux;
00280         lock_mmap.lock();
00281         for (item=map.head;item;item=item->next)
00282          {
00283                 quux = (mmap_s*)item->data;
00284                 if ((type == ME_ANY) || (quux -> type == type))
00285                         if (quux -> start <= virt)
00286                                 if (quux->end >= virt)
00287                                         el = item;
00288          }
00289 
00290         lock_mmap.ulock();
00291 
00292         if (el == NULL)
00293                 return NULL;
00294 
00295         return el;
00296  }
00297 
00298 
00299 int mmap_t::del(blist_s *item)
00300  {
00301 int i;
00302         lock_mmap.lock();
00303         i= mdel(item);
00304         lock_mmap.ulock();
00305 
00306         return i;
00307  }
00308 
00309 
00310 blist_s *mmap_t::find(uint32 start)
00311  {
00312 blist_s *item;
00313         lock_mmap.lock();
00314         item= mfind(start);
00315         lock_mmap.ulock();
00316 
00317         return item;
00318  }
00319 
00320 
00321 int mmap_t::firstfit(uint32 size, uint32 alignment, uint32 type, void *dt, uint64 info,
00322                 uint32 *loc, int threadno, int (*destroy)(mmap_t*,mmap_s*))
00323  {
00324 int i;
00325         lock_mmap.lock();
00326         i= mfirstfit(size,alignment,loc);
00327         if (i!= ESUCCESS)
00328          {      lock_mmap.ulock();
00329                 return i; }
00330         i= (madd(*loc, size, type, dt, info, threadno, destroy) != NULL);
00331         lock_mmap.ulock();
00332 
00333         if (i == false)
00334                 return EFAIL;
00335         return ESUCCESS;
00336  }
00337 
00338 
00339 int mmap_t::fitbelow(uint32 size, uint32 alignment, uint32 max, uint32 type, void *dt,
00340                 uint64 info, uint32 *loc, int threadno, int (*destroy)(mmap_t*,mmap_s*), bool force)
00341  {
00342 int i;
00343         lock_mmap.lock();
00344         i= mfitbelow(size,alignment,max,loc,force);
00345         if (i!= ESUCCESS)
00346          {      lock_mmap.ulock();
00347                 return i; }
00348         i= (int) madd(*loc, size, type, dt, info, threadno,destroy);
00349         lock_mmap.ulock();
00350 
00351         if (i == NULL)
00352                 return EFAIL;
00353         return ESUCCESS;
00354  }
00355 
00356 
00357 
00358 
00359 
00360 
00361