1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2009 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <gsf@research.att.com> * 18 * David Korn <dgk@research.att.com> * 19 * Phong Vo <kpv@research.att.com> * 20 * * 21 ***********************************************************************/ 22 #if defined(_UWIN) && defined(_BLD_ast) 23 24 void _STUB_vmprofile(){} 25 26 #else 27 28 #include "vmhdr.h" 29 30 /* Method to profile space usage. 31 ** 32 ** Written by Kiem-Phong Vo, kpv@research.att.com, 03/23/94. 33 */ 34 35 #define PFHASH(pf) ((pf)->data.data.hash) 36 #define PFVM(pf) ((pf)->data.data.vm) 37 #define PFFILE(pf) ((pf)->data.data.fm.file) 38 #define PFLINE(pf) ((pf)->line) 39 #define PFNAME(pf) ((pf)->data.f) 40 #define PFNALLOC(pf) ((pf)->data.data.nalloc) 41 #define PFALLOC(pf) ((pf)->data.data.alloc) 42 #define PFNFREE(pf) ((pf)->data.data.nfree) 43 #define PFFREE(pf) ((pf)->data.data.free) 44 #define PFREGION(pf) ((pf)->data.data.region) 45 #define PFMAX(pf) ((pf)->data.data.fm.max) 46 47 typedef struct _pfdata_s Pfdata_t; 48 struct _pfdata_s 49 { Vmulong_t hash; /* hash value */ 50 union 51 { char* file; /* file name */ 52 Vmulong_t max; /* max busy space for region */ 53 } fm; 54 Vmalloc_t* vm; /* region alloc from */ 55 Pfobj_t* region; /* pointer to region record */ 56 Vmulong_t nalloc; /* number of alloc calls */ 57 Vmulong_t alloc; /* amount allocated */ 58 Vmulong_t nfree; /* number of free calls */ 59 Vmulong_t free; /* amount freed */ 60 }; 61 struct _pfobj_s 62 { Pfobj_t* next; /* next in linked list */ 63 int line; /* line #, 0 for name holder */ 64 union 65 { 66 Pfdata_t data; 67 char f[1]; /* actual file name */ 68 } data; 69 }; 70 71 static Pfobj_t** Pftable; /* hash table */ 72 #define PFTABLE 1019 /* table size */ 73 static Vmalloc_t* Vmpf; /* heap for our own use */ 74 75 #if __STD_C 76 static Pfobj_t* pfsearch(Vmalloc_t* vm, const char* file, int line) 77 #else 78 static Pfobj_t* pfsearch(vm, file, line) 79 Vmalloc_t* vm; /* region allocating from */ 80 const char* file; /* the file issuing the allocation request */ 81 int line; /* line number */ 82 #endif 83 { 84 reg Pfobj_t *pf, *last; 85 reg Vmulong_t h; 86 reg int n; 87 reg const char* cp; 88 89 if(!Vmpf && !(Vmpf = vmopen(Vmdcheap,Vmpool,0)) ) 90 return NIL(Pfobj_t*); 91 92 /* make hash table; PFTABLE'th slot hold regions' records */ 93 if(!Pftable) 94 { if(!(Pftable = (Pfobj_t**)vmalloc(Vmheap,(PFTABLE+1)*sizeof(Pfobj_t*))) ) 95 return NIL(Pfobj_t*); 96 for(n = PFTABLE; n >= 0; --n) 97 Pftable[n] = NIL(Pfobj_t*); 98 } 99 100 /* see if it's there with a combined hash value of vm,file,line */ 101 h = line + (((Vmulong_t)vm)>>4); 102 for(cp = file; *cp; ++cp) 103 h += (h<<7) + ((*cp)&0377) + 987654321L; 104 n = (int)(h%PFTABLE); 105 for(last = NIL(Pfobj_t*), pf = Pftable[n]; pf; last = pf, pf = pf->next) 106 if(PFLINE(pf) == line && PFVM(pf) == vm && strcmp(PFFILE(pf),file) == 0) 107 break; 108 109 /* insert if not there yet */ 110 if(!pf) 111 { reg Pfobj_t* fn; 112 reg Pfobj_t* pfvm; 113 reg Vmulong_t hn; 114 115 /* first get/construct the file name slot */ 116 hn = 0; 117 for(cp = file; *cp; ++cp) 118 hn += (hn<<7) + ((*cp)&0377) + 987654321L; 119 n = (int)(hn%PFTABLE); 120 for(fn = Pftable[n]; fn; fn = fn->next) 121 if(PFLINE(fn) < 0 && strcmp(PFNAME(fn),file) == 0) 122 break; 123 if(!fn) 124 { reg size_t s; 125 s = sizeof(Pfobj_t) - sizeof(Pfdata_t) + strlen(file) + 1; 126 if(!(fn = (Pfobj_t*)vmalloc(Vmheap,s)) ) 127 return NIL(Pfobj_t*); 128 fn->next = Pftable[n]; 129 Pftable[n] = fn; 130 PFLINE(fn) = -1; 131 strcpy(PFNAME(fn),file); 132 } 133 134 /* get region record; note that these are ordered by vm */ 135 last = NIL(Pfobj_t*); 136 for(pfvm = Pftable[PFTABLE]; pfvm; last = pfvm, pfvm = pfvm->next) 137 if(vm >= PFVM(pfvm)) 138 break; 139 if(!pfvm || PFVM(pfvm) > vm) 140 { if(!(pfvm = (Pfobj_t*)vmalloc(Vmpf,sizeof(Pfobj_t))) ) 141 return NIL(Pfobj_t*); 142 if(last) 143 { pfvm->next = last->next; 144 last->next = pfvm; 145 } 146 else 147 { pfvm->next = Pftable[PFTABLE]; 148 Pftable[PFTABLE] = pfvm; 149 } 150 PFNALLOC(pfvm) = PFALLOC(pfvm) = 0; 151 PFNFREE(pfvm) = PFFREE(pfvm) = 0; 152 PFMAX(pfvm) = 0; 153 PFVM(pfvm) = vm; 154 PFLINE(pfvm) = 0; 155 } 156 157 if(!(pf = (Pfobj_t*)vmalloc(Vmpf,sizeof(Pfobj_t))) ) 158 return NIL(Pfobj_t*); 159 n = (int)(h%PFTABLE); 160 pf->next = Pftable[n]; 161 Pftable[n] = pf; 162 PFLINE(pf) = line; 163 PFFILE(pf) = PFNAME(fn); 164 PFREGION(pf) = pfvm; 165 PFVM(pf) = vm; 166 PFNALLOC(pf) = 0; 167 PFALLOC(pf) = 0; 168 PFNFREE(pf) = 0; 169 PFFREE(pf) = 0; 170 PFHASH(pf) = h; 171 } 172 else if(last) /* do a move-to-front */ 173 { last->next = pf->next; 174 pf->next = Pftable[n]; 175 Pftable[n] = pf; 176 } 177 178 return pf; 179 } 180 181 #if __STD_C 182 static void pfclose(Vmalloc_t* vm) 183 #else 184 static void pfclose(vm) 185 Vmalloc_t* vm; 186 #endif 187 { 188 reg int n; 189 reg Pfobj_t *pf, *next, *last; 190 191 /* free all records related to region vm */ 192 for(n = PFTABLE; n >= 0; --n) 193 { for(last = NIL(Pfobj_t*), pf = Pftable[n]; pf; ) 194 { next = pf->next; 195 196 if(PFLINE(pf) >= 0 && PFVM(pf) == vm) 197 { if(last) 198 last->next = next; 199 else Pftable[n] = next; 200 vmfree(Vmpf,pf); 201 } 202 else last = pf; 203 204 pf = next; 205 } 206 } 207 } 208 209 #if __STD_C 210 static void pfsetinfo(Vmalloc_t* vm, Vmuchar_t* data, size_t size, const char* file, int line) 211 #else 212 static void pfsetinfo(vm, data, size, file, line) 213 Vmalloc_t* vm; 214 Vmuchar_t* data; 215 size_t size; 216 const char* file; 217 int line; 218 #endif 219 { 220 reg Pfobj_t* pf; 221 reg Vmulong_t s; 222 223 /* let vmclose knows that there are records for region vm */ 224 _Vmpfclose = pfclose; 225 226 if(!file || line <= 0) 227 { file = ""; 228 line = 0; 229 } 230 231 if((pf = pfsearch(vm,file,line)) ) 232 { PFALLOC(pf) += size; 233 PFNALLOC(pf) += 1; 234 } 235 PFOBJ(data) = pf; 236 PFSIZE(data) = size; 237 238 if(pf) 239 { /* update region statistics */ 240 pf = PFREGION(pf); 241 PFALLOC(pf) += size; 242 PFNALLOC(pf) += 1; 243 if((s = PFALLOC(pf) - PFFREE(pf)) > PFMAX(pf) ) 244 PFMAX(pf) = s; 245 } 246 } 247 248 /* sort by file names and line numbers */ 249 #if __STD_C 250 static Pfobj_t* pfsort(Pfobj_t* pf) 251 #else 252 static Pfobj_t* pfsort(pf) 253 Pfobj_t* pf; 254 #endif 255 { 256 reg Pfobj_t *one, *two, *next; 257 reg int cmp; 258 259 if(!pf->next) 260 return pf; 261 262 /* partition to two equal size lists */ 263 one = two = NIL(Pfobj_t*); 264 while(pf) 265 { next = pf->next; 266 pf->next = one; 267 one = pf; 268 269 if((pf = next) ) 270 { next = pf->next; 271 pf->next = two; 272 two = pf; 273 pf = next; 274 } 275 } 276 277 /* sort and merge the lists */ 278 one = pfsort(one); 279 two = pfsort(two); 280 for(pf = next = NIL(Pfobj_t*);; ) 281 { /* make sure that the "<>" file comes first */ 282 if(PFLINE(one) == 0 && PFLINE(two) == 0) 283 cmp = PFVM(one) > PFVM(two) ? 1 : -1; 284 else if(PFLINE(one) == 0) 285 cmp = -1; 286 else if(PFLINE(two) == 0) 287 cmp = 1; 288 else if((cmp = strcmp(PFFILE(one),PFFILE(two))) == 0) 289 { cmp = PFLINE(one) - PFLINE(two); 290 if(cmp == 0) 291 cmp = PFVM(one) > PFVM(two) ? 1 : -1; 292 } 293 294 if(cmp < 0) 295 { if(!pf) 296 pf = one; 297 else next->next = one; 298 next = one; 299 if(!(one = one->next) ) 300 { if(two) 301 next->next = two; 302 return pf; 303 } 304 } 305 else 306 { if(!pf) 307 pf = two; 308 else next->next = two; 309 next = two; 310 if(!(two = two->next) ) 311 { if(one) 312 next->next = one; 313 return pf; 314 } 315 } 316 } 317 } 318 319 #if __STD_C 320 static char* pfsummary(char* buf, Vmulong_t na, Vmulong_t sa, 321 Vmulong_t nf, Vmulong_t sf, Vmulong_t max, Vmulong_t size) 322 #else 323 static char* pfsummary(buf, na, sa, nf, sf, max, size) 324 char* buf; 325 Vmulong_t na; 326 Vmulong_t sa; 327 Vmulong_t nf; 328 Vmulong_t sf; 329 Vmulong_t max; 330 Vmulong_t size; 331 #endif 332 { 333 buf = (*_Vmstrcpy)(buf,"n_alloc", '='); 334 buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(na,-1), ':'); 335 buf = (*_Vmstrcpy)(buf,"n_free", '='); 336 buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(nf,-1), ':'); 337 buf = (*_Vmstrcpy)(buf,"s_alloc", '='); 338 buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(sa,-1), ':'); 339 buf = (*_Vmstrcpy)(buf,"s_free", '='); 340 buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(sf,-1), ':'); 341 if(max > 0) 342 { buf = (*_Vmstrcpy)(buf,"max_busy", '='); 343 buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(max,-1), ':'); 344 buf = (*_Vmstrcpy)(buf,"extent", '='); 345 buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(size,-1), ':'); 346 } 347 *buf++ = '\n'; 348 349 return buf; 350 } 351 352 /* print profile data */ 353 #if __STD_C 354 int vmprofile(Vmalloc_t* vm, int fd) 355 #else 356 int vmprofile(vm, fd) 357 Vmalloc_t* vm; 358 int fd; 359 #endif 360 { 361 reg Pfobj_t *pf, *list, *next, *last; 362 reg int n; 363 reg Vmulong_t nalloc, alloc, nfree, free; 364 reg Seg_t* seg; 365 char buf[1024], *bufp, *endbuf; 366 #define INITBUF() (bufp = buf, endbuf = buf+sizeof(buf)-128) 367 #define CHKBUF() (bufp >= endbuf ? (write(fd,buf,bufp-buf), bufp=buf) : bufp) 368 #define FLSBUF() (bufp > buf ? write(fd,buf,bufp-buf) : 0) 369 370 if(fd < 0) 371 return -1; 372 373 /* initialize functions from vmtrace.c that we use below */ 374 if((n = vmtrace(-1)) >= 0) 375 vmtrace(n); 376 377 alloc = free = nalloc = nfree = 0; 378 list = NIL(Pfobj_t*); 379 for(n = PFTABLE-1; n >= 0; --n) 380 { for(pf = Pftable[n], last = NIL(Pfobj_t*); pf; ) 381 { next = pf->next; 382 383 if(PFLINE(pf) < 0 || (vm && vm != PFVM(pf)) ) 384 { last = pf; 385 goto next_pf; 386 } 387 388 /* remove from hash table */ 389 if(last) 390 last->next = next; 391 else Pftable[n] = next; 392 393 /* put on output list */ 394 pf->next = list; 395 list = pf; 396 nalloc += PFNALLOC(pf); 397 alloc += PFALLOC(pf); 398 nfree += PFNFREE(pf); 399 free += PFFREE(pf); 400 401 next_pf: 402 pf = next; 403 } 404 } 405 406 INITBUF(); 407 bufp = (*_Vmstrcpy)(bufp,"ALLOCATION USAGE SUMMARY", ':'); 408 bufp = pfsummary(bufp,nalloc,alloc,nfree,free,0,0); 409 410 /* print regions' summary data */ 411 for(pf = Pftable[PFTABLE]; pf; pf = pf->next) 412 { if(vm && PFVM(pf) != vm) 413 continue; 414 alloc = 0; 415 for(seg = PFVM(pf)->data->seg; seg; seg = seg->next) 416 alloc += seg->extent; 417 bufp = (*_Vmstrcpy)(bufp,"region", '='); 418 bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(PFVM(pf)),0), ':'); 419 bufp = pfsummary(bufp,PFNALLOC(pf),PFALLOC(pf), 420 PFNFREE(pf),PFFREE(pf),PFMAX(pf),alloc); 421 } 422 423 /* sort then output detailed profile */ 424 list = pfsort(list); 425 for(pf = list; pf; ) 426 { /* compute summary for file */ 427 alloc = free = nalloc = nfree = 0; 428 for(last = pf; last; last = last->next) 429 { if(strcmp(PFFILE(last),PFFILE(pf)) != 0) 430 break; 431 nalloc += PFNALLOC(pf); 432 alloc += PFALLOC(last); 433 nfree += PFNFREE(last); 434 free += PFFREE(last); 435 } 436 CHKBUF(); 437 bufp = (*_Vmstrcpy)(bufp,"file",'='); 438 bufp = (*_Vmstrcpy)(bufp,PFFILE(pf)[0] ? PFFILE(pf) : "<>" ,':'); 439 bufp = pfsummary(bufp,nalloc,alloc,nfree,free,0,0); 440 441 while(pf != last) /* detailed data */ 442 { CHKBUF(); 443 bufp = (*_Vmstrcpy)(bufp,"\tline",'='); 444 bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(PFLINE(pf),-1), ':'); 445 bufp = (*_Vmstrcpy)(bufp, "region", '='); 446 bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(PFVM(pf)),0), ':'); 447 bufp = pfsummary(bufp,PFNALLOC(pf),PFALLOC(pf), 448 PFNFREE(pf),PFFREE(pf),0,0); 449 450 /* reinsert into hash table */ 451 next = pf->next; 452 n = (int)(PFHASH(pf)%PFTABLE); 453 pf->next = Pftable[n]; 454 Pftable[n] = pf; 455 pf = next; 456 } 457 } 458 459 FLSBUF(); 460 return 0; 461 } 462 463 #if __STD_C 464 static Void_t* pfalloc(Vmalloc_t* vm, size_t size) 465 #else 466 static Void_t* pfalloc(vm, size) 467 Vmalloc_t* vm; 468 size_t size; 469 #endif 470 { 471 reg size_t s; 472 reg Void_t* data; 473 reg char* file; 474 reg int line, local, inuse; 475 reg Void_t* func; 476 reg Vmdata_t* vd = vm->data; 477 478 VMFLF(vm,file,line,func); 479 SETINUSE(vd, inuse); 480 if(!(local = vd->mode&VM_TRUST) ) 481 { GETLOCAL(vd, local); 482 if(ISLOCK(vd, local)) 483 { CLRINUSE(vd, inuse); 484 return NIL(Void_t*); 485 } 486 SETLOCK(vd, local); 487 } 488 489 s = ROUND(size,ALIGN) + PF_EXTRA; 490 if(!(data = KPVALLOC(vm,s,(*(Vmbest->allocf))) ) ) 491 goto done; 492 493 pfsetinfo(vm,(Vmuchar_t*)data,size,file,line); 494 495 if(!local && (vd->mode&VM_TRACE) && _Vmtrace) 496 { vm->file = file; vm->line = line; vm->func = func; 497 (*_Vmtrace)(vm,NIL(Vmuchar_t*),(Vmuchar_t*)data,size,0); 498 } 499 done: 500 CLRLOCK(vd, local); 501 ANNOUNCE(local, vm, VM_ALLOC, (Void_t*)data, vm->disc); 502 CLRINUSE(vd, inuse); 503 return data; 504 } 505 506 #if __STD_C 507 static int pffree(Vmalloc_t* vm, Void_t* data) 508 #else 509 static int pffree(vm, data) 510 Vmalloc_t* vm; 511 Void_t* data; 512 #endif 513 { 514 reg Pfobj_t* pf; 515 reg size_t s; 516 reg char* file; 517 reg int line, rv, local, inuse; 518 reg Void_t* func; 519 reg Vmdata_t* vd = vm->data; 520 521 VMFLF(vm,file,line,func); 522 523 if(!data) 524 return 0; 525 526 SETINUSE(vd, inuse); 527 if(!(local = vd->mode&VM_TRUST) ) 528 { GETLOCAL(vd,local); 529 if(ISLOCK(vd,local)) 530 { CLRINUSE(vd, inuse); 531 return -1; 532 } 533 SETLOCK(vd,local); 534 } 535 536 if(KPVADDR(vm,data,Vmbest->addrf) != 0 ) 537 { if(vm->disc->exceptf) 538 (void)(*vm->disc->exceptf)(vm,VM_BADADDR,data,vm->disc); 539 CLRLOCK(vd,0); 540 CLRINUSE(vd, inuse); 541 return -1; 542 } 543 544 pf = PFOBJ(data); 545 s = PFSIZE(data); 546 if(pf) 547 { PFNFREE(pf) += 1; 548 PFFREE(pf) += s; 549 pf = PFREGION(pf); 550 PFNFREE(pf) += 1; 551 PFFREE(pf) += s; 552 } 553 554 if(!local && (vd->mode&VM_TRACE) && _Vmtrace) 555 { vm->file = file; vm->line = line; vm->func = func; 556 (*_Vmtrace)(vm,(Vmuchar_t*)data,NIL(Vmuchar_t*),s,0); 557 } 558 559 rv = KPVFREE((vm), (Void_t*)data, (*Vmbest->freef)); 560 CLRLOCK(vd,local); 561 ANNOUNCE(local, vm, VM_FREE, data, vm->disc); 562 CLRINUSE(vd, inuse); 563 return rv; 564 } 565 566 #if __STD_C 567 static Void_t* pfresize(Vmalloc_t* vm, Void_t* data, size_t size, int type) 568 #else 569 static Void_t* pfresize(vm, data, size, type) 570 Vmalloc_t* vm; 571 Void_t* data; 572 size_t size; 573 int type; 574 #endif 575 { 576 reg Pfobj_t* pf; 577 reg size_t s; 578 reg size_t news; 579 reg Void_t* addr; 580 reg char* file; 581 reg int line, local, inuse; 582 reg Void_t* func; 583 reg size_t oldsize; 584 reg Vmdata_t* vd = vm->data; 585 586 SETINUSE(vd, inuse); 587 if(!data) 588 { oldsize = 0; 589 addr = pfalloc(vm,size); 590 goto done; 591 } 592 if(size == 0) 593 { (void)pffree(vm,data); 594 CLRINUSE(vd, inuse); 595 return NIL(Void_t*); 596 } 597 598 VMFLF(vm,file,line,func); 599 if(!(local = vd->mode&VM_TRUST)) 600 { GETLOCAL(vd, local); 601 if(ISLOCK(vd, local)) 602 { CLRINUSE(vd, inuse); 603 return NIL(Void_t*); 604 } 605 SETLOCK(vd, local); 606 } 607 608 if(KPVADDR(vm,data,Vmbest->addrf) != 0 ) 609 { if(vm->disc->exceptf) 610 (void)(*vm->disc->exceptf)(vm,VM_BADADDR,data,vm->disc); 611 CLRLOCK(vd, local); 612 CLRINUSE(vd, inuse); 613 return NIL(Void_t*); 614 } 615 616 pf = PFOBJ(data); 617 s = oldsize = PFSIZE(data); 618 619 news = ROUND(size,ALIGN) + PF_EXTRA; 620 if((addr = KPVRESIZE(vm,data,news,(type&~VM_RSZERO),Vmbest->resizef)) ) 621 { if(pf) 622 { PFFREE(pf) += s; 623 PFNFREE(pf) += 1; 624 pf = PFREGION(pf); 625 PFFREE(pf) += s; 626 PFNFREE(pf) += 1; 627 pfsetinfo(vm,(Vmuchar_t*)addr,size,file,line); 628 } 629 630 if(!local && (vd->mode&VM_TRACE) && _Vmtrace) 631 { vm->file = file; vm->line = line; vm->func = func; 632 (*_Vmtrace)(vm,(Vmuchar_t*)data,(Vmuchar_t*)addr,size,0); 633 } 634 } 635 else if(pf) /* reset old info */ 636 { PFALLOC(pf) -= s; 637 PFNALLOC(pf) -= 1; 638 pf = PFREGION(pf); 639 PFALLOC(pf) -= s; 640 PFNALLOC(pf) -= 1; 641 file = PFFILE(pf); 642 line = PFLINE(pf); 643 pfsetinfo(vm,(Vmuchar_t*)data,s,file,line); 644 } 645 646 CLRLOCK(vd, local); 647 ANNOUNCE(local, vm, VM_RESIZE, (Void_t*)addr, vm->disc); 648 649 done: if(addr && (type&VM_RSZERO) && oldsize < size) 650 { reg Vmuchar_t *d = (Vmuchar_t*)addr+oldsize, *ed = (Vmuchar_t*)addr+size; 651 do { *d++ = 0; } while(d < ed); 652 } 653 654 CLRINUSE(vd, inuse); 655 return addr; 656 } 657 658 #if __STD_C 659 static long pfsize(Vmalloc_t* vm, Void_t* addr) 660 #else 661 static long pfsize(vm, addr) 662 Vmalloc_t* vm; 663 Void_t* addr; 664 #endif 665 { 666 return (*Vmbest->addrf)(vm,addr) != 0 ? -1L : (long)PFSIZE(addr); 667 } 668 669 #if __STD_C 670 static long pfaddr(Vmalloc_t* vm, Void_t* addr) 671 #else 672 static long pfaddr(vm, addr) 673 Vmalloc_t* vm; 674 Void_t* addr; 675 #endif 676 { 677 return (*Vmbest->addrf)(vm,addr); 678 } 679 680 #if __STD_C 681 static int pfcompact(Vmalloc_t* vm) 682 #else 683 static int pfcompact(vm) 684 Vmalloc_t* vm; 685 #endif 686 { 687 return (*Vmbest->compactf)(vm); 688 } 689 690 #if __STD_C 691 static Void_t* pfalign(Vmalloc_t* vm, size_t size, size_t align) 692 #else 693 static Void_t* pfalign(vm, size, align) 694 Vmalloc_t* vm; 695 size_t size; 696 size_t align; 697 #endif 698 { 699 reg size_t s; 700 reg Void_t* data; 701 reg char* file; 702 reg int line, local, inuse; 703 reg Void_t* func; 704 reg Vmdata_t* vd = vm->data; 705 706 VMFLF(vm,file,line,func); 707 708 SETINUSE(vd, inuse); 709 if(!(local = vd->mode&VM_TRUST) ) 710 { GETLOCAL(vd,local); 711 if(ISLOCK(vd, local)) 712 { CLRINUSE(vd, inuse); 713 return NIL(Void_t*); 714 } 715 SETLOCK(vd, local); 716 } 717 718 s = (size <= TINYSIZE ? TINYSIZE : ROUND(size,ALIGN)) + PF_EXTRA; 719 if(!(data = KPVALIGN(vm,s,align,Vmbest->alignf)) ) 720 goto done; 721 722 pfsetinfo(vm,(Vmuchar_t*)data,size,file,line); 723 724 if(!local && (vd->mode&VM_TRACE) && _Vmtrace) 725 { vm->file = file; vm->line = line; vm->func = func; 726 (*_Vmtrace)(vm,NIL(Vmuchar_t*),(Vmuchar_t*)data,size,align); 727 } 728 done: 729 CLRLOCK(vd, local); 730 ANNOUNCE(local, vm, VM_ALLOC, data, vm->disc); 731 CLRINUSE(vd, inuse); 732 return data; 733 } 734 735 static Vmethod_t _Vmprofile = 736 { 737 pfalloc, 738 pfresize, 739 pffree, 740 pfaddr, 741 pfsize, 742 pfcompact, 743 pfalign, 744 VM_MTPROFILE 745 }; 746 747 __DEFINE__(Vmethod_t*,Vmprofile,&_Vmprofile); 748 749 #ifdef NoF 750 NoF(vmprofile) 751 #endif 752 753 #endif 754