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