/[pcsx2_0.9.7]/trunk/common/src/Utilities/Windows/WinHostSys.cpp
ViewVC logotype

Contents of /trunk/common/src/Utilities/Windows/WinHostSys.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 280 - (show annotations) (download)
Thu Dec 23 12:02:12 2010 UTC (9 years, 1 month ago) by william
File size: 4217 byte(s)
re-commit (had local access denied errors when committing)
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16 #include "PrecompiledHeader.h"
17 #include "Utilities/RedtapeWindows.h"
18 #include "PageFaultSource.h"
19
20 #include <winnt.h>
21
22
23 int SysPageFaultExceptionFilter( EXCEPTION_POINTERS* eps )
24 {
25 if( eps->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION )
26 return EXCEPTION_CONTINUE_SEARCH;
27
28 Source_PageFault->Dispatch( PageFaultInfo( (uptr)eps->ExceptionRecord->ExceptionInformation[1] ) );
29 return Source_PageFault->WasHandled() ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH;
30 }
31
32 void _platform_InstallSignalHandler()
33 {
34 // NOP on Win32 systems -- we use __try{} __except{} instead.
35 }
36
37
38 static DWORD ConvertToWinApi( const PageProtectionMode& mode )
39 {
40 DWORD winmode = PAGE_NOACCESS;
41
42 // Windows has some really bizarre memory protection enumeration that uses bitwise
43 // numbering (like flags) but is in fact not a flag value. *Someone* from the early
44 // microsoft days wasn't a very good coder, me thinks. --air
45
46 if (mode.CanExecute())
47 {
48 winmode = mode.CanWrite() ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
49 }
50 else if (mode.CanRead())
51 {
52 winmode = mode.CanWrite() ? PAGE_READWRITE : PAGE_READONLY;
53 }
54
55 return winmode;
56 }
57
58 void* HostSys::MmapReservePtr(void* base, size_t size)
59 {
60 return VirtualAlloc(base, size, MEM_RESERVE, PAGE_NOACCESS);
61 }
62
63 bool HostSys::MmapCommitPtr(void* base, size_t size, const PageProtectionMode& mode)
64 {
65 void* result = VirtualAlloc(base, size, MEM_COMMIT, ConvertToWinApi(mode));
66 if (result) return true;
67
68 const DWORD errcode = GetLastError();
69 if (errcode == ERROR_COMMITMENT_MINIMUM)
70 {
71 Console.Warning("(MmapCommit) Received windows error %u {Virtual Memory Minimum Too Low}.", ERROR_COMMITMENT_MINIMUM);
72 Sleep(1000); // Cut windows some time to rework its memory...
73 }
74 else if (errcode != ERROR_NOT_ENOUGH_MEMORY && errcode != ERROR_OUTOFMEMORY)
75 {
76 pxFailDev(L"VirtualAlloc COMMIT failed: " + Exception::WinApiError().GetMsgFromWindows());
77 return false;
78 }
79
80 if (!pxDoOutOfMemory) return false;
81 pxDoOutOfMemory(size);
82 return VirtualAlloc(base, size, MEM_COMMIT, ConvertToWinApi(mode)) != NULL;
83 }
84
85 void HostSys::MmapResetPtr(void* base, size_t size)
86 {
87 VirtualFree(base, size, MEM_DECOMMIT);
88 }
89
90
91 void* HostSys::MmapReserve(uptr base, size_t size)
92 {
93 return MmapReservePtr((void*)base, size);
94 }
95
96 bool HostSys::MmapCommit(uptr base, size_t size, const PageProtectionMode& mode)
97 {
98 return MmapCommitPtr( (void*)base, size, mode );
99 }
100
101 void HostSys::MmapReset(uptr base, size_t size)
102 {
103 MmapResetPtr((void*)base, size);
104 }
105
106
107 void* HostSys::Mmap(uptr base, size_t size)
108 {
109 return VirtualAlloc((void*)base, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
110 }
111
112 void HostSys::Munmap(uptr base, size_t size)
113 {
114 if (!base) return;
115 //VirtualFree((void*)base, size, MEM_DECOMMIT);
116 VirtualFree((void*)base, 0, MEM_RELEASE);
117 }
118
119 void HostSys::MemProtect( void* baseaddr, size_t size, const PageProtectionMode& mode )
120 {
121 pxAssertDev( ((size & (__pagesize-1)) == 0), pxsFmt(
122 L"Memory block size must be a multiple of the target platform's page size.\n"
123 L"\tPage Size: 0x%04x (%d), Block Size: 0x%04x (%d)",
124 __pagesize, __pagesize, size, size )
125 );
126
127 DWORD OldProtect; // enjoy my uselessness, yo!
128 if (!VirtualProtect( baseaddr, size, ConvertToWinApi(mode), &OldProtect ))
129 {
130 Exception::WinApiError apiError;
131
132 apiError.SetDiagMsg(
133 pxsFmt(L"VirtualProtect failed @ 0x%08X -> 0x%08X (mode=%s)",
134 baseaddr, (uptr)baseaddr + size, mode.ToString().c_str()
135 ));
136
137 pxFailDev( apiError.FormatDiagnosticMessage() );
138 }
139 }

  ViewVC Help
Powered by ViewVC 1.1.22