Source code of Windows XP (NT5)
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.

266 lines
6.4 KiB

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1992 Microsoft Corporation */
  3. /************************************************************/
  4. #define NOGDICAPMASKS
  5. #define NOVIRTUALKEYCODES
  6. #define NOWINMESSAGES
  7. #define NOWINSTYLES
  8. #define NOSYSMETRICS
  9. #define NOMENUS
  10. #define NOICON
  11. #define NOKEYSTATE
  12. #define NOSYSCOMMANDS
  13. #define NOSHOWWINDOW
  14. #define NOCTLMGR
  15. #define NOCLIPBOARD
  16. #define NOMSG
  17. #define NOGDI
  18. #define NOMB
  19. #define NOSOUND
  20. #define NOCOMM
  21. #define NOPEN
  22. #define NOBRUSH
  23. #define NOFONT
  24. #define NOWNDCLASS
  25. #include <windows.h>
  26. #include "mw.h"
  27. /*
  28. HeapManage.c - several routines to manage the heap, including changing
  29. the finger table, compacting the heap in general, and checking the
  30. heap for consistency.
  31. It also contains the routines which were once in heapNew.
  32. */
  33. #include "code.h"
  34. #include "heapDefs.h"
  35. #include "heapData.h"
  36. #define NOSTRUNDO
  37. #define NOSTRMERGE
  38. #include "str.h"
  39. #include "macro.h"
  40. #define NOUAC
  41. #include "cmddefs.h"
  42. #include "filedefs.h"
  43. #include "docdefs.h"
  44. #ifdef DEBUG
  45. int cPageMinReq = 15;
  46. #else
  47. #define cPageMinReq (15)
  48. #endif
  49. /* the following statics are used when growing both heap and rgbp etc. */
  50. static int cwRealRequest; /* heap is grow in blocks, this is the actual request */
  51. static int cPageIncr; /* count of page buffers to increase */
  52. static int cwRgbpIncr; /* cw in rgbp to be increment */
  53. static int cwHashIncr; /* cw in rgibpHash to be increment */
  54. static int cwBPSIncr; /* cw in mpibpbps to be increment */
  55. static int cwHeapIncr; /* cw in heap increment */
  56. extern CHAR (*rgbp)[cbSector];
  57. extern CHAR *rgibpHash;
  58. extern struct BPS *mpibpbps;
  59. extern int ibpMax;
  60. extern int iibpHashMax;
  61. extern int cwInitStorage;
  62. extern typeTS tsMruBps;
  63. NEAR FGiveupFreeBps(unsigned, int *);
  64. NEAR FThrowPages(int);
  65. NEAR GivePages(int);
  66. NEAR CompressRgbp();
  67. FTryGrow(cb)
  68. unsigned cb;
  69. {
  70. int cPage;
  71. #define cPageRemain (int)(ibpMax - cPage)
  72. if (FGiveupFreeBps(cb, &cPage) &&
  73. (cPageRemain >= cPageMinReq))
  74. {
  75. /* we have enough free pages to give */
  76. GivePages(cPage);
  77. }
  78. else if ((cPageRemain >= cPageMinReq) && FThrowPages(cPage))
  79. {
  80. GivePages(cPage);
  81. }
  82. else
  83. {
  84. return(FALSE);
  85. }
  86. return(TRUE);
  87. }
  88. NEAR FGiveupFreeBps(cb, pCPage)
  89. unsigned cb;
  90. int *pCPage;
  91. {
  92. /* Return true if we can simply give up certain free pages from rgbp to
  93. the heap. Return false if all free pages from rgbp still cannot satisfy
  94. the request
  95. In any case, pCPage contains the count of pages required */
  96. register struct BPS *pbps;
  97. register int cPage = 0;
  98. int ibp;
  99. #define cbTotalFreed ((cPage*cbSector)+(2*cPage*sizeof(CHAR))+(cPage*sizeof(struct BPS)))
  100. for (ibp = 0, pbps = &mpibpbps[0]; ibp < ibpMax; ibp++, pbps++)
  101. {
  102. if (pbps->fn == fnNil)
  103. cPage++;
  104. }
  105. if (cb > cbTotalFreed )
  106. {
  107. /* free pages are not enough, find out exactly how many
  108. pages do we need */
  109. cPage++;
  110. while (cb > cbTotalFreed)
  111. cPage++;
  112. *pCPage = cPage;
  113. return(FALSE);
  114. }
  115. /* there are enough free pages to give, find out exactly how many */
  116. while (cb <= cbTotalFreed)
  117. cPage--;
  118. cPage++;
  119. *pCPage = cPage;
  120. return(TRUE);
  121. } /* end of FGiveupFreeBps */
  122. NEAR FThrowPages(cPage)
  123. int cPage;
  124. {
  125. int i;
  126. register struct BPS *pbps;
  127. Assert(cPage > 0);
  128. for (i = 0; i < cPage; i++)
  129. {
  130. pbps = &mpibpbps[IbpLru(0)];
  131. if (pbps->fn != fnNil)
  132. {
  133. if (pbps->fDirty && !FFlushFn(pbps->fn))
  134. return(FALSE);
  135. /* delete references to old bps in hash table */
  136. FreeBufferPage(pbps->fn, pbps->pn);
  137. }
  138. pbps->ts = ++tsMruBps; /* so that it would not be picked up again as the LRUsed */
  139. }
  140. return(TRUE);
  141. } /* end of FThrowPages */
  142. NEAR GivePages(cPage)
  143. int cPage;
  144. {
  145. register struct BPS *pbpsCur = &mpibpbps[0];
  146. struct BPS *pbpsUsable = pbpsCur;
  147. int ibp;
  148. unsigned cbBps;
  149. unsigned cbRgbp;
  150. unsigned cbTotalNew;
  151. for (ibp = 0; ibp < ibpMax; pbpsCur++, ibp++)
  152. {
  153. /* compressed so that non empty bps are at the low end,
  154. store ibp in ibpHashNext field (this is important for
  155. CompressRgbp relies on that), since ibpHashNext is invalid
  156. after the compress anyway */
  157. if (pbpsCur->fn != fnNil)
  158. {
  159. if (pbpsCur != pbpsUsable)
  160. {
  161. bltbyte((CHAR *)pbpsCur, (CHAR *)pbpsUsable,
  162. sizeof(struct BPS));
  163. /* reinitialized */
  164. SetBytes((CHAR*)pbpsCur, 0, sizeof(struct BPS));
  165. pbpsCur->fn = fnNil;
  166. pbpsCur->ibpHashNext = ibpNil;
  167. }
  168. pbpsUsable->ibpHashNext = ibp;
  169. pbpsUsable++;
  170. }
  171. } /* end of for */
  172. /* compressed rgbp, result -- all used pages at the low end */
  173. CompressRgbp();
  174. /* decrease the size of the hash table */
  175. ibpMax -= cPage;
  176. iibpHashMax = ibpMax * 2 + 1;
  177. cbRgbp = ibpMax * cbSector;
  178. rgibpHash = (CHAR *)((unsigned)rgbp + cbRgbp);
  179. /* contents of rgibpHash should be all ibpNil, that is
  180. taken care in RehashRgibpHash */
  181. cbBps = (ibpMax * sizeof(struct BPS) + 1) & ~1;
  182. bltbyte((CHAR *)mpibpbps, (CHAR *)(mpibpbps = (struct BPS *)
  183. (((unsigned)rgibpHash + iibpHashMax + 1) & ~1)), cbBps);
  184. RehashRgibpHash();
  185. cbTotalNew = cbRgbp + cbBps + ((iibpHashMax + 1) & ~1);
  186. LocalReAlloc((HANDLE)rgbp, cbTotalNew, LPTR);
  187. Assert(rgbp != NULL);
  188. } /* end of GivePages */
  189. NEAR CompressRgbp()
  190. {
  191. /* compressed so that all non empty pages are moved towards the low end of
  192. rgbp */
  193. register struct BPS *pbps = &mpibpbps[0];
  194. struct BPS *pbpsLim = &mpibpbps[ibpMax];
  195. int ibp;
  196. for (ibp = 0; pbps < pbpsLim; ibp++, pbps++)
  197. {
  198. if (pbps->fn == fnNil)
  199. continue;
  200. if (pbps->ibpHashNext != ibp)
  201. {
  202. /* find out the location of pages (stored in ibpHashNext field) */
  203. bltbyte((CHAR *)rgbp[pbps->ibpHashNext], (CHAR *)rgbp[ibp], cbSector);
  204. }
  205. pbps->ibpHashNext = ibpNil;
  206. }
  207. } /* end of CompressRgbp */
  208. #ifdef DEBUG
  209. cPageUnused()
  210. {
  211. int ibp;
  212. struct BPS *pbps;
  213. int cPage = 0;
  214. for (ibp = 0, pbps = &mpibpbps[0]; ibp < ibpMax; ibp++, pbps++)
  215. {
  216. if (pbps->fn == fnNil)
  217. cPage++;
  218. }
  219. return(cPage);
  220. }
  221. #endif
  222.