Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

187 lines
4.4 KiB

  1. /*
  2. ** Copyright 1994, Silicon Graphics, Inc.
  3. ** All Rights Reserved.
  4. **
  5. ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6. ** the contents of this file may not be disclosed to third parties, copied or
  7. ** duplicated in any form, in whole or in part, without the prior written
  8. ** permission of Silicon Graphics, Inc.
  9. **
  10. ** RESTRICTED RIGHTS LEGEND:
  11. ** Use, duplication or disclosure by the Government is subject to restrictions
  12. ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13. ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14. ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15. ** rights reserved under the Copyright Laws of the United States.
  16. **
  17. ** Author: Eric Veach, July 1994.
  18. */
  19. #ifdef NT
  20. #include <glos.h>
  21. #endif
  22. #include "memalloc.h"
  23. #include <assert.h>
  24. #ifdef NO_MALLOPT
  25. #define memalign(a,n) malloc(n)
  26. #define mallopt(t,v)
  27. #endif
  28. #define Pool mPool
  29. typedef struct Pool {
  30. char *prevAlloc;
  31. char *lastAlloc;
  32. int usedCount;
  33. int chunkSize;
  34. } Pool;
  35. typedef struct Chunk {
  36. Pool *pool;
  37. } Chunk;
  38. static Pool **Pools;
  39. static size_t MaxFast;
  40. #define POOL_SIZE 200
  41. #define CHUNK_PAD sizeof(Chunk)
  42. #define ALIGN_SHIFT 3
  43. #define ALIGN (1 << ALIGN_SHIFT)
  44. #define CHUNK_SIZE(n) (((n) + CHUNK_PAD + ALIGN - 1) & (-ALIGN))
  45. #define ALIGNED_CHUNK_PAD ((CHUNK_PAD + ALIGN - 1) & (-ALIGN))
  46. static int NewPool( size_t n, int poolSize )
  47. {
  48. Pool *p;
  49. char *base;
  50. /* We want the *returned* chunks to be aligned on ALIGN boundaries.
  51. * The Chunk structures will be located just before these boundaries.
  52. */
  53. p = (Pool *)malloc( CHUNK_SIZE(sizeof(Pool)) + poolSize * n );
  54. if (p == NULL) {
  55. return 0;
  56. }
  57. base = (char *)p + CHUNK_SIZE(sizeof(Pool)) - CHUNK_PAD;
  58. p->prevAlloc = base - n;
  59. p->lastAlloc = base + (poolSize-1) * n;
  60. p->usedCount = poolSize;
  61. p->chunkSize = n;
  62. Pools[n>>ALIGN_SHIFT] = p;
  63. return 1;
  64. }
  65. int __gl_memInit( size_t maxFast )
  66. {
  67. int i, numPools;
  68. if( Pools == NULL ) {
  69. #ifdef MEMORY_DEBUG
  70. mallopt( M_DEBUG, 1 );
  71. #endif
  72. MaxFast = CHUNK_SIZE(maxFast) - CHUNK_PAD;
  73. numPools = ((MaxFast + CHUNK_PAD) >> ALIGN_SHIFT) + 1;
  74. Pools = (struct Pool **)malloc( numPools * sizeof(Pools[0]) );
  75. if (Pools == NULL)
  76. return 0;
  77. /* Create a tiny pool for every size, to avoid a check for NULL
  78. * in memAlloc().
  79. */
  80. for( i = 1; i < numPools; ++i ) {
  81. if (NewPool( i << ALIGN_SHIFT, 1 ) == 0) {
  82. return 0;
  83. }
  84. }
  85. }
  86. return 1;
  87. }
  88. void *__gl_memAlloc( size_t n )
  89. {
  90. Pool *p;
  91. Chunk *c;
  92. if( n <= MaxFast ) {
  93. n = CHUNK_SIZE( n );
  94. p = Pools[n >> ALIGN_SHIFT];
  95. assert ( p->chunkSize == n );
  96. c = (Chunk *)(p->prevAlloc + n);
  97. p->prevAlloc = (char *) c;
  98. c->pool = p;
  99. if( c >= (Chunk *) p->lastAlloc ) {
  100. if (NewPool( n, POOL_SIZE ) == 0) {
  101. return 0;
  102. }
  103. }
  104. assert( ((size_t)(c + 1) & (ALIGN - 1)) == 0 );
  105. } else {
  106. char* v;
  107. /* v = (char*) malloc( n + ALIGNED_CHUNK_PAD ) + ALIGNED_CHUNK_PAD;*/
  108. v = (char*) malloc( n + ALIGNED_CHUNK_PAD );
  109. if (v == NULL) {
  110. return 0;
  111. }
  112. v = v + ALIGNED_CHUNK_PAD;
  113. c = ((Chunk*) v) - 1;
  114. c->pool = NULL;
  115. assert( ((size_t)(c + 1) & (ALIGN - 1)) == 0 );
  116. }
  117. return (c + 1);
  118. }
  119. extern void *__gl_memRealloc( void *v1, size_t n )
  120. {
  121. Chunk *c = ((Chunk *) v1) - 1;
  122. Pool *p = c->pool;
  123. void *v2;
  124. #ifdef NT
  125. size_t len;
  126. #else
  127. int len;
  128. #endif
  129. if( p == NULL ) {
  130. char* v;
  131. /* v = (char*) realloc( (char*)v1 - ALIGNED_CHUNK_PAD, n + ALIGNED_CHUNK_PAD )
  132. + ALIGNED_CHUNK_PAD; */
  133. v = (char*) realloc( (char*)v1 - ALIGNED_CHUNK_PAD, n + ALIGNED_CHUNK_PAD);
  134. if (v == NULL) {
  135. return 0;
  136. }
  137. v = v + ALIGNED_CHUNK_PAD;
  138. c = ((Chunk*) v) - 1;
  139. assert( ((size_t)(c + 1) & (ALIGN - 1)) == 0 );
  140. return (c+1);
  141. }
  142. len = p->chunkSize - CHUNK_PAD;
  143. if( n <= len ) { return v1; }
  144. v2 = memAlloc( n );
  145. if (v2 == NULL) {
  146. return 0;
  147. }
  148. (void) memcpy( v2, v1, len );
  149. memFree( v1 );
  150. return v2;
  151. }
  152. extern void __gl_memFree( void *v )
  153. {
  154. Chunk *c = ((Chunk *) v) - 1;
  155. Pool *p = c->pool;
  156. if( p == NULL ) {
  157. free( ((char*) v) - ALIGNED_CHUNK_PAD );
  158. } else {
  159. if( --p->usedCount <= 0 ) {
  160. free( p );
  161. }
  162. }
  163. }