00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #ifndef lint
00061 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/memalloc.c,v 14.9 2006/09/16 02:04:25 lbutler Exp $ (BRL)";
00062 #endif
00063
00064 #include "common.h"
00065
00066
00067
00068 #include <stdio.h>
00069 #include "machine.h"
00070 #include "vmath.h"
00071 #include "raytrace.h"
00072
00073
00074
00075
00076 static struct mem_map *rt_mem_freemap = MAP_NULL;
00077
00078
00079 #define M_TMTCH 00001
00080 #define M_BMTCH 00002
00081 #define M_TOVFL 00004
00082 #define M_BOVFL 00010
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 unsigned long
00097 rt_memalloc(struct mem_map **pp, register unsigned int size)
00098 {
00099 register struct mem_map *prevp = MAP_NULL;
00100 register struct mem_map *curp;
00101 unsigned long addr;
00102
00103 if( size == 0 )
00104 return( 0L );
00105
00106 for( curp = *pp; curp; curp = (prevp=curp)->m_nxtp ) {
00107 if( curp->m_size >= size )
00108 break;
00109 }
00110
00111 if( curp == MAP_NULL )
00112 return(0L);
00113
00114 addr = curp->m_addr;
00115 curp->m_addr += size;
00116
00117
00118
00119 if( (curp->m_size -= size) == 0 ) {
00120 if( prevp )
00121 prevp->m_nxtp = curp->m_nxtp;
00122 else
00123 *pp = curp->m_nxtp;
00124 curp->m_nxtp = rt_mem_freemap;
00125 rt_mem_freemap = curp;
00126 }
00127
00128 return( addr );
00129 }
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 struct mem_map *
00144 rt_memalloc_nosplit(struct mem_map **pp, register unsigned int size)
00145 {
00146 register struct mem_map *prevp = MAP_NULL;
00147 register struct mem_map *curp;
00148 register struct mem_map *best = MAP_NULL, *best_prevp = MAP_NULL;
00149
00150 if( size == 0 )
00151 return MAP_NULL;
00152
00153 for( curp = *pp; curp; curp = (prevp=curp)->m_nxtp ) {
00154 if( curp->m_size < size ) continue;
00155 if( curp->m_size == size ) {
00156 best = curp;
00157 best_prevp = prevp;
00158 break;
00159 }
00160
00161 if( best == MAP_NULL || curp->m_size < best->m_size ) {
00162 best = curp;
00163 best_prevp = prevp;
00164 }
00165 }
00166 if( !best )
00167 return MAP_NULL;
00168
00169
00170 if( best_prevp )
00171 best_prevp->m_nxtp = best->m_nxtp;
00172 else
00173 *pp = best->m_nxtp;
00174 best->m_nxtp = rt_mem_freemap;
00175 rt_mem_freemap = best;
00176
00177 return best;
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 unsigned long
00192 rt_memget(struct mem_map **pp, register unsigned int size, unsigned int place)
00193 {
00194 register struct mem_map *prevp, *curp;
00195 unsigned int addr;
00196
00197 prevp = MAP_NULL;
00198 if( size == 0 )
00199 rt_bomb("rt_memget() size==0\n");
00200
00201 curp = *pp;
00202 while( curp ) {
00203
00204
00205
00206
00207
00208
00209
00210 if( curp->m_addr == place && curp->m_size >= size )
00211 break;
00212 curp = (prevp=curp)->m_nxtp;
00213 }
00214
00215 if( curp == MAP_NULL )
00216 return(0L);
00217
00218 addr = curp->m_addr;
00219 curp->m_addr += size;
00220
00221
00222 if( (curp->m_size -= size) == 0 ) {
00223 if( prevp )
00224 prevp->m_nxtp = curp->m_nxtp;
00225 else
00226 *pp = curp->m_nxtp;
00227 curp->m_nxtp = rt_mem_freemap;
00228 rt_mem_freemap = curp;
00229 }
00230 return( addr );
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 unsigned long
00245 rt_memget_nosplit(struct mem_map **pp, register unsigned int size, unsigned int place)
00246 {
00247 register struct mem_map *prevp, *curp;
00248
00249 prevp = MAP_NULL;
00250 if( size == 0 )
00251 bu_bomb("rt_memget_nosplit() size==0\n");
00252
00253 curp = *pp;
00254 while( curp ) {
00255
00256
00257
00258
00259
00260
00261
00262 if( curp->m_addr == place && curp->m_size >= size ) {
00263 size = curp->m_size;
00264
00265 if( prevp )
00266 prevp->m_nxtp = curp->m_nxtp;
00267 else
00268 *pp = curp->m_nxtp;
00269 curp->m_nxtp = rt_mem_freemap;
00270 rt_mem_freemap = curp;
00271 return size;
00272 }
00273 curp = (prevp=curp)->m_nxtp;
00274 }
00275
00276 return 0L;
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 void
00291 rt_memfree(struct mem_map **pp, unsigned int size, long unsigned int addr)
00292 {
00293 register int type = 0;
00294 register struct mem_map *prevp = MAP_NULL;
00295 register struct mem_map *curp;
00296 long il;
00297 struct mem_map *tmap;
00298
00299 if( size == 0 )
00300 return;
00301
00302
00303 for( curp = *pp; curp; curp = (prevp=curp)->m_nxtp )
00304 if( addr < curp->m_addr )
00305 break;
00306
00307
00308
00309 if( prevp ) {
00310 if( (il=prevp->m_addr+prevp->m_size) > addr )
00311 type |= M_BOVFL;
00312 if( il == addr )
00313 type |= M_BMTCH;
00314 }
00315 if( curp ) {
00316 if( (il=addr+size) > curp->m_addr )
00317 type |= M_TOVFL;
00318 if( il == curp->m_addr )
00319 type |= M_TMTCH;
00320 }
00321
00322 if( type & (M_TOVFL|M_BOVFL) ) {
00323 bu_log("rt_memfree(addr=x%x,size=%d) ERROR type=0%o\n",
00324 addr, size, type );
00325 if( prevp )
00326 bu_log("prevp: m_addr=x%x, m_size=%d\n",
00327 prevp->m_addr, prevp->m_size );
00328 if( curp )
00329 bu_log("curp: m_addr=x%x, m_size=%d\n",
00330 curp->m_addr, curp->m_size );
00331 return;
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341 switch( type & (M_BMTCH|M_TMTCH) ) {
00342 case M_TMTCH|M_BMTCH:
00343 prevp->m_size += size + curp->m_size;
00344 prevp->m_nxtp = curp->m_nxtp;
00345 curp->m_nxtp = rt_mem_freemap;
00346 rt_mem_freemap = curp;
00347 break;
00348
00349 case M_BMTCH:
00350 prevp->m_size += size;
00351 break;
00352
00353 case M_TMTCH:
00354 curp->m_size += size;
00355 curp->m_addr -= size;
00356 break;
00357
00358 default:
00359 if( (tmap=rt_mem_freemap) == MAP_NULL )
00360 tmap = (struct mem_map *)bu_malloc(sizeof(struct mem_map), "struct mem_map " BU_FLSTR);
00361 else
00362 rt_mem_freemap = rt_mem_freemap->m_nxtp;
00363
00364 if( prevp )
00365 prevp->m_nxtp = tmap;
00366 else
00367 *pp = tmap;
00368
00369 tmap->m_size = size;
00370 tmap->m_addr = addr;
00371 tmap->m_nxtp = curp;
00372 }
00373 }
00374
00375
00376
00377
00378
00379
00380
00381 void
00382 rt_mempurge(struct mem_map **pp)
00383 {
00384 register struct mem_map *prevp = MAP_NULL;
00385 register struct mem_map *curp;
00386
00387 if( *pp == MAP_NULL )
00388 return;
00389
00390
00391 for( curp = *pp; curp; curp = (prevp=curp)->m_nxtp )
00392 ;
00393
00394
00395 prevp->m_nxtp = rt_mem_freemap;
00396 rt_mem_freemap = *pp;
00397
00398 *pp = MAP_NULL;
00399 }
00400
00401
00402
00403
00404
00405
00406 void
00407 rt_memprint(struct mem_map **pp)
00408 {
00409 register struct mem_map *curp;
00410
00411 bu_log("rt_memprint(x%x): address, length\n", *pp);
00412 for( curp = *pp; curp; curp = curp->m_nxtp )
00413 bu_log(" a=x%.8lx, l=%.5d\n", curp->m_addr, curp->m_size );
00414 }
00415
00416
00417
00418
00419
00420
00421 void
00422 rt_memclose(void)
00423 {
00424 register struct mem_map *mp;
00425
00426 while( (mp = rt_mem_freemap) != MAP_NULL ) {
00427 rt_mem_freemap = mp->m_nxtp;
00428 bu_free( (char *)mp, "struct mem_map " BU_FLSTR);
00429 }
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440