• 32位系统使用文件作为媒介来模拟大于4G内存访问


    代码一篇,暂时没发现bug:

      1 // vm_mgr.cpp : Defines the exported functions for the DLL application.
      2 //
      3 
      4 #include "stdafx.h"
      5 
      6 #include <Windows.h>
      7 #include <vector>
      8 #include <assert.h>
      9 #include <tchar.h>
     10 #include "../common/assist.h"
     11 #include"../error_no/error_no.h"
     12 #include "../Log/log.h"
     13 #include "vm_mgr.h"
     14 
     15 #define VM_ADDR_GEN(addr, index)                (assert(index < 16), (((index & 0xfULL) << 60) | addr))
     16 #define VM_START_ADDR                           0x100000000ULL
     17 #define VM_WINDOW_SIZE                          (64 * 1024 * 1024UL)
     18 #define VM_ALIGN_SIZE                           (64 * 1024)
     19 
     20 struct vm_window {
     21         void                    *p;
     22         vm_ptr_t                start;
     23         unsigned long           size;
     24 };
     25 
     26 struct vm_item {
     27         int                 addr_index;
     28         HANDLE              mutext;    
     29         HANDLE              hMap;
     30         vm_ptr_t            vm_start_ptr;
     31         unsigned long long  vm_size;
     32         struct vm_window    window;
     33         TCHAR               file_path[MAX_PATH];
     34 };
     35 
     36 struct {
     37     std::vector<struct vm_item>    tbl;
     38 } vm;
     39 
     40 static int find_empty_index()
     41 {
     42         int addr_index;
     43         int i;
     44 
     45         for (addr_index = 0; ; addr_index++) {
     46                 for (i = 0; i < vm.tbl.size(); i++) {
     47                         if (vm.tbl.at(i).addr_index == addr_index)
     48                                 break;
     49                 }
     50                 assert(addr_index <= 16);
     51                 if (i >= vm.tbl.size())
     52                         return addr_index;
     53         }
     54 }
     55 
     56 vm_ptr_t vm_alloc(unsigned long long size)
     57 {
     58         TCHAR                       tmp_path[MAX_PATH];
     59         TCHAR                       tmp_file_path[MAX_PATH];
     60         int                         err;
     61         struct vm_item              vm_item;
     62 
     63         GetTempPath(ARRAY_SIZE(tmp_path), tmp_path);
     64         GetTempFileName(tmp_path, _T("DediProg"), 0, tmp_file_path);
     65 
     66         HANDLE hFile = CreateFile(
     67                                 tmp_file_path,
     68                                 GENERIC_READ | GENERIC_WRITE,
     69                                 FILE_SHARE_READ | FILE_SHARE_WRITE,
     70                                 NULL,
     71                                 OPEN_ALWAYS,
     72                                 FILE_FLAG_SEQUENTIAL_SCAN,
     73                                 NULL
     74                                 );
     75         if (hFile == NULL) {
     76                 return NULL; 
     77         }
     78 
     79         vm_item.hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, size >> 32, size & 0xffffffff, NULL);
     80         if (vm_item.hMap == NULL) {
     81                 err = GetLastError();
     82                 return -E_ALLOC_MEMORY_FAIL;
     83         }
     84         vm_item.vm_start_ptr = (vm_ptr_t)MapViewOfFile(
     85                 vm_item.hMap,
     86                 FILE_MAP_ALL_ACCESS,
     87                 0 >> 32,
     88                 0 & 0xffffffff,
     89                 min(size, VM_WINDOW_SIZE)
     90                 );
     91  
     92         vm_item.addr_index = find_empty_index();
     93         vm_item.vm_start_ptr = VM_ADDR_GEN(vm_item.vm_start_ptr, vm_item.addr_index);
     94 
     95         assert(vm_item.vm_start_ptr < ((-1) >> 4));
     96 
     97         CloseHandle(hFile);
     98         hFile = NULL;
     99         vm_item.vm_size = size;
    100         vm_item.window.size = (unsigned long)min(VM_WINDOW_SIZE, size);
    101         vm_item.window.start = vm_item.vm_start_ptr;
    102         vm_item.window.p = (unsigned char *)vm_item.vm_start_ptr;
    103         vm_item.mutext = CreateMutex(NULL, FALSE, NULL);
    104         _tcsncpy(vm_item.file_path, tmp_file_path, ARRAY_SIZE(vm_item.file_path));
    105         vm.tbl.push_back(vm_item);
    106 
    107         return vm_item.vm_start_ptr;
    108 }
    109 
    110 static __inline int in_region(vm_ptr_t ptr, unsigned long long size)
    111 {
    112         //static int dbg = 0;
    113         int i;
    114  
    115         for (i = 0; i < (int)vm.tbl.size(); i++) {
    116                 if ((ptr + size) <= (vm.tbl.at(i).vm_start_ptr + vm.tbl.at(i).vm_size) && (ptr >= vm.tbl.at(i).vm_start_ptr))
    117                         return i;
    118                 //if (ptr + size > vm.tbl.at(i).vm_start_ptr + vm.tbl.at(i).vm_size)
    119                 //        i = 'DEAD';
    120                 //if (ptr < vm.tbl.at(i).vm_start_ptr)
    121                 //        i = 'INVA';
    122         }
    123         
    124         LOG_BEGIN {
    125                 log_add("----------------------------------------------");
    126                 log_add("|             Virtual Memory layout          |");
    127                 log_add("|--------------------------------------------|");
    128                 for (i = 0; i < (int)vm.tbl.size(); i++)
    129                 log_add("|window.start_addr:%llx | window.size:%llx   |", vm.tbl.at(i).window.start, vm.tbl.at(i).window.size);
    130                 log_add("|--------------------------------------------|");
    131                 log_add("|user.ptr:%llx          | user.size:%llx     |", ptr, size);
    132                 log_add("----------------------------------------------");
    133         } LOG_END;
    134         //dbg++;
    135         assert(!"Invalid Memory");
    136         return -1;
    137 }
    138 
    139 static __inline unsigned char *scroll_window(int vm_index, vm_ptr_t ptr, unsigned long size)
    140 {
    141         unsigned char           *p;
    142         vm_ptr_t            win_start;
    143         unsigned long           win_size;
    144         unsigned long long      file_offset;
    145         unsigned long long      tmp_offset;
    146 
    147 
    148         win_start = vm.tbl.at(vm_index).window.start;
    149         win_size = vm.tbl.at(vm_index).window.size;
    150 
    151         
    152         UnmapViewOfFile(vm.tbl.at(vm_index).window.p);
    153 
    154         win_size = (unsigned long)min(VM_WINDOW_SIZE, size);
    155 
    156         assert(ptr >= vm.tbl.at(vm_index).vm_start_ptr);
    157         file_offset = ptr - vm.tbl.at(vm_index).vm_start_ptr;
    158         
    159         tmp_offset = file_offset / VM_ALIGN_SIZE * VM_ALIGN_SIZE;
    160         tmp_offset = file_offset - tmp_offset;
    161         
    162         file_offset = file_offset / VM_ALIGN_SIZE * VM_ALIGN_SIZE;
    163 
    164         size += (unsigned long)tmp_offset;
    165 
    166         p = (unsigned char *)MapViewOfFile(
    167                 vm.tbl.at(vm_index).hMap,
    168                 FILE_MAP_ALL_ACCESS,
    169                 file_offset >> 32,
    170                 file_offset & 0xffffffff,
    171                 size
    172                 );
    173 
    174         if (p) {
    175                 vm.tbl.at(vm_index).window.start = ptr;
    176                 vm.tbl.at(vm_index).window.size = size;
    177                 vm.tbl.at(vm_index).window.p = p;
    178 
    179                 return p + tmp_offset;
    180         }
    181 
    182         return NULL;
    183 }
    184 
    185 int vm_write(vm_ptr_t pointer, const unsigned char *buff, unsigned long long size)
    186 {
    187         int             ret;
    188         unsigned char       *p;
    189         unsigned long       len;
    190         int index = in_region(pointer, size);
    191 
    192         ret = 0;
    193 
    194         if (index == -1) {
    195                 ret = -1;
    196                 goto end;
    197         }
    198         WaitForSingleObject(vm.tbl.at(index).mutext, 20000);        /* timeout 10s */
    199         while (size) {
    200                 len = (unsigned long)min(size, VM_WINDOW_SIZE);
    201                 p = scroll_window(index, pointer, len);
    202                 if (!p) {
    203                         ret = -1;
    204                         goto end;
    205                 }
    206 
    207                 memcpy(p, buff, len);
    208 
    209                 pointer += len;
    210                 buff += len;
    211                 size -= len;
    212         }
    213 end:
    214         ReleaseMutex(vm.tbl.at(index).mutext);
    215         return ret;
    216 }
    217 
    218 
    219 int vm_read(unsigned char *buff, vm_ptr_t ptr, unsigned long long size)
    220 {
    221         unsigned char   *p;
    222         unsigned long   len;
    223         int index;
    224 
    225         assert(buff);
    226 
    227         index = in_region(ptr, size);
    228 
    229         if (index == -1)
    230                 return -E_ALLOC_MEMORY_FAIL;
    231 
    232         while (size) {
    233                 len = (unsigned long)min(size, VM_WINDOW_SIZE);
    234                 p = scroll_window(index, ptr, len);
    235                 if (!p)
    236                         return -1;
    237 
    238                 memcpy(buff, p, len);
    239 
    240                 ptr += len;
    241                 buff += len;
    242                 size -= len;
    243         }
    244 
    245         return 0;
    246 }
    247 
    248 int vm_free(vm_ptr_t ptr)
    249 {
    250     int i;
    251 
    252     LOG_BEGIN {
    253                 log_add("----------------------------------------------");
    254                 log_add("|             Virtual Memory layout          |");
    255                 log_add("|--------------------------------------------|");
    256                 for (i = 0; i < (int)vm.tbl.size(); i++)
    257                 log_add("|window.start_addr:%llx | window.size:%llx   |", vm.tbl.at(i).window.start, vm.tbl.at(i).window.size);
    258                 log_add("----------------------------------------------");
    259     } LOG_END;
    260 
    261     for (i = 0; i < (int)vm.tbl.size(); i++) {
    262         if (vm.tbl.at(i).vm_start_ptr == ptr) {
    263             assert(vm.tbl.at(i).hMap);
    264 
    265             UnmapViewOfFile(vm.tbl.at(i).window.p);
    266             CloseHandle(vm.tbl.at(i).hMap);
    267 
    268             DeleteFile(vm.tbl.at(i).file_path);
    269 
    270             vm.tbl.erase(vm.tbl.begin() + i);
    271             return 0;
    272         }
    273     }
    274 
    275     assert(!"Invalid pointer");
    276 
    277     return 0;
    278 }
  • 相关阅读:
    MongoDB 数组
    MongoDB 内嵌文档
    MongoDB 聚合操作
    MongoDB 文档的删除操作
    MongoDB 文档的更新操作
    MongoDB 文档的查询和插入操作
    MongoDB 安装和可视化工具
    SSIS 容器
    SSISDB2:SSIS工程的操作实例
    Replication:distribution 中一直在运行 waitfor delay @strdelaytime 语句
  • 原文地址:https://www.cnblogs.com/findstr/p/3558558.html
Copyright © 2020-2023  润新知