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.

197 lines
4.3 KiB

  1. // vm.c
  2. //
  3. // simple minded virtual memory implemenation
  4. // there is no code to do the OS2 version...
  5. #include <stdio.h>
  6. #include <fcntl.h>
  7. #include <io.h>
  8. #include <sys\types.h>
  9. #include <sys\stat.h>
  10. #include <malloc.h>
  11. #include <string.h>
  12. #if defined(OS2)
  13. #define INCL_NOCOMMON
  14. #define INCL_DOSPROCESS
  15. #define INCL_DOSSEMAPHORES
  16. #define INCL_DOSFILEMGR
  17. #define INCL_DOSERRORS
  18. #define INCL_DOSMISC
  19. #include <os2.h>
  20. #else
  21. #include <windows.h>
  22. #endif
  23. #include "hungary.h"
  24. #include "vm.h"
  25. #include "sbrproto.h"
  26. #include "errors.h"
  27. #define CB_PAGE_SIZE 2048 // 4k pages
  28. #define C_LOCKS_MAX 16 // up to 16 pages may be locked in ram
  29. #define C_PAGES_MAX 8192 // up to 4k pages resident
  30. #define C_FREE_LIST_MAX 256 // keep free lists for items up to 256 bytes
  31. #define GRP_MAX 16 // max number of memory groups
  32. typedef WORD VPG; // virtual page number
  33. typedef VA far *LPVA; // far pointer to VA
  34. // virtual address arithmetic
  35. //
  36. // #define VpgOfVa(va) ((WORD)((va>>12)))
  37. // this is really the same as the above but it assumes that the high byte
  38. // of the long is all zero's and it is optimized for our C compiler
  39. #define VpgOfVa(va) ((((WORD)((BYTE)(va>>16)))<<4)|\
  40. (((BYTE)(((WORD)va)>>8))>>4))
  41. #define OfsOfVa(va) ((WORD)((va) & 0x07ff))
  42. #define VaBaseOfVpg(vpg) (((DWORD)(vpg)) << 12)
  43. // phsyical page header
  44. typedef struct _pg {
  45. BYTE fDirty; // needs to be written out
  46. BYTE cLocks; // this page is locked
  47. VPG vpg; // what is the virtual page number of this page
  48. struct _pg FAR *lppgNext; // LRU ordering next
  49. struct _pg FAR *lppgPrev; // and prev
  50. } PG;
  51. typedef PG FAR * LPPG;
  52. typedef struct _mem {
  53. VA vaFree;
  54. WORD cbFree;
  55. VA mpCbVa[C_FREE_LIST_MAX];
  56. #ifdef SWAP_INFO
  57. WORD cPages;
  58. #endif
  59. } MGI; // Memory Group Info
  60. static MGI mpGrpMgi[GRP_MAX];
  61. // translation table -- map virtual page number to physical page address
  62. static LPPG mpVpgLppg[C_PAGES_MAX];
  63. // head and tail pointers for LRU
  64. //
  65. static LPPG near lppgHead;
  66. static LPPG near lppgTail;
  67. // nil page pointer
  68. //
  69. #define lppgNil 0
  70. // points to the start of linked lists of free blocks
  71. //
  72. static VA mpCbVa[C_FREE_LIST_MAX];
  73. // these pages are locked in memory
  74. //
  75. static LPPG near rgLppgLocked[C_LOCKS_MAX];
  76. // number of pages we have given out
  77. static VPG near vpgMac;
  78. // number of physical pages we have resident
  79. static WORD near cPages;
  80. // should we keep trying to allocate memory
  81. static BOOL near fTryMemory = TRUE;
  82. // the file handle for the backing store
  83. static int near fhVM;
  84. // the name of the file for the backing store
  85. static LSZ near lszVM;
  86. #ifdef ASSERT
  87. #define Assert(x, sz) { if (!(x)) AssertionFailed(sz); }
  88. VOID
  89. AssertionFailed(LSZ lsz)
  90. // something went wrong...
  91. //
  92. {
  93. printf("assertion failure:%s\n", lsz);
  94. Fatal();
  95. }
  96. #else
  97. #define Assert(x, y)
  98. #endif
  99. LPV VM_API
  100. LpvAllocCb(ULONG cb)
  101. // allocate a block of far memory, if _fmalloc fails, the free some of
  102. // the memory we were using for the VM cache
  103. //
  104. {
  105. LPV lpv;
  106. if (!(lpv = calloc(cb,1))) {
  107. Error(ERR_OUT_OF_MEMORY, "");
  108. }
  109. return lpv;
  110. }
  111. VA VM_API
  112. VaAllocGrpCb(WORD grp, ULONG cb)
  113. // allocate cb bytes from the requested memory group
  114. //
  115. {
  116. VA vaNew;
  117. MGI FAR *lpMgi;
  118. LPV lpv;
  119. lpMgi = &mpGrpMgi[grp];
  120. Assert(grp < GRP_MAX, "Memory Group out of range");
  121. if (cb < C_FREE_LIST_MAX && (vaNew = lpMgi->mpCbVa[cb])) {
  122. lpv = LpvFromVa(vaNew, 0);
  123. lpMgi->mpCbVa[cb] = *(LPVA)lpv;
  124. memset(lpv, 0, cb);
  125. DirtyVa(vaNew);
  126. return vaNew;
  127. }
  128. if (cb < mpGrpMgi[grp].cbFree) {
  129. vaNew = mpGrpMgi[grp].vaFree;
  130. (PBYTE)mpGrpMgi[grp].vaFree += cb;
  131. mpGrpMgi[grp].cbFree -= cb;
  132. }
  133. else {
  134. vaNew = VaAllocCb(CB_PAGE_SIZE - sizeof(PG));
  135. mpGrpMgi[grp].vaFree = (PBYTE)vaNew + cb;
  136. mpGrpMgi[grp].cbFree = CB_PAGE_SIZE - cb - sizeof(PG);
  137. }
  138. return vaNew;
  139. }
  140. VOID VM_API
  141. FreeGrpVa(WORD grp, VA va, ULONG cb)
  142. // put this block on the free list for blocks of that size
  143. // we don't remember how big the blocks were so the caller has
  144. // provide that info
  145. //
  146. {
  147. MGI FAR *lpMgi;
  148. lpMgi = &mpGrpMgi[grp];
  149. if (cb < C_FREE_LIST_MAX && cb >= 4 ) {
  150. *(LPVA)LpvFromVa(va, 0) = lpMgi->mpCbVa[cb];
  151. DirtyVa(va);
  152. lpMgi->mpCbVa[cb] = va;
  153. }
  154. }