1 /* BLURB lgpl
2
3 Coda File System
4 Release 5
5
6 Copyright (c) 1987-1999 Carnegie Mellon University
7 Additional copyrights listed below
8
9 This code is distributed "AS IS" without warranty of any kind under
10 the terms of the GNU Library General Public Licence Version 2, as
11 shown in the file LICENSE. The technical and financial contributors to
12 Coda are listed in the file CREDITS.
13
14 Additional copyrights
15 none currently
16
17 #*/
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28
29 #include <rvm/rvm.h>
30 #include <rvm/rvm_segment.h>
31
32 /* from rvm_private.h */
33 rvm_bool_t rvm_register_page(char *vmaddr, rvm_length_t length);
34 rvm_bool_t rvm_unregister_page(char *vmaddr, rvm_length_t length);
35
36 #ifdef __CYGWIN32__
37 #include <windows.h>
38 #endif
39
40 /* Routine to check if regions will overlap in memory. */
41
overlap(nregions,regionDefs)42 int overlap(nregions, regionDefs)
43 unsigned long nregions;
44 rvm_region_def_t regionDefs[];
45 {
46 int i,j;
47 rvm_region_def_t temp;
48
49 /* sort array */
50 for (i = 0; i < (nregions - 1); i++) {
51 for (j = i + 1; j < nregions; j++) {
52 if (regionDefs[j].vmaddr < regionDefs[i].vmaddr) {
53 temp.vmaddr = regionDefs[i].vmaddr;
54 temp.length = regionDefs[i].length;
55 temp.offset = regionDefs[i].offset;
56
57 regionDefs[i].vmaddr = regionDefs[j].vmaddr;
58 regionDefs[i].length = regionDefs[j].length;
59 regionDefs[i].offset = regionDefs[j].offset;
60
61 regionDefs[j].vmaddr = temp.vmaddr;
62 regionDefs[j].length = temp.length;
63 regionDefs[j].offset = temp.offset;
64 }
65 }
66 }
67
68 for (i = 0; i < (nregions - 1); i++) {
69 if (regionDefs[i].vmaddr + regionDefs[i].length > regionDefs[i+1].vmaddr)
70 return(TRUE);
71 }
72
73 return FALSE;
74 }
75
76
77 /* BSD44 memory allocation; uses mmap as an allocator. Any mmap-aware
78 system should be able to use this code */
79
80 #include <sys/types.h>
81 #include <sys/mman.h>
82 #include "coda_mmap_anon.h"
83 #include <errno.h>
84 #define ALLOCATE_VM_DEFINED
85
86
87 rvm_return_t
allocate_vm(addr,length)88 allocate_vm(addr, length)
89 char **addr;
90 unsigned long length;
91 {
92 rvm_return_t ret = RVM_SUCCESS;
93 char *requested_addr = *addr; /* save this so that we can check it
94 against the address location
95 returned by mmap. this is
96 important because if it isn't 0,
97 it's a location that we HAVE to
98 be able to map to. */
99
100 #ifdef HAVE_MMAP
101 mmap_anon(*addr, *addr, length, (PROT_READ | PROT_WRITE));
102 #else
103 {
104 HANDLE hMap = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL,
105 PAGE_READWRITE, 0, length, NULL);
106 if (hMap == NULL)
107 return(RVM_EINTERNAL);
108 *addr = MapViewOfFileEx(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0, *addr);
109 if (*addr == NULL) {
110 #if 0
111 DWORD errnum;
112 errnum = GetLastError();
113 printf ("allocate_vm: errnum = %d\n", errnum);
114 #endif
115 *addr = (char *)-1;
116 }
117 CloseHandle(hMap);
118 }
119 #endif
120
121 if (*addr == (char*)-1) {
122 if (errno == ENOMEM) {
123 ret = RVM_ENO_MEMORY;
124 } else {
125 ret = RVM_EINTERNAL;
126 }
127 }
128
129 if (requested_addr != 0 && *addr != requested_addr) {
130 ret = RVM_EINTERNAL; /* couldn't allocated requested memory. */
131 }
132
133 /* modified by tilt, Nov 19 1996.
134 When we allocate a page (or range of pages) we register
135 it in an internal table we're keeping around to keep
136 track of pages. (The previous solution was to try to
137 re-allocate the page, and see if it fails, which is
138 not only wrong [since we don't if it's allocated, or
139 actually allocated in the RVM heap!!], but doesn't
140 work with mmap()). */
141 if (rvm_register_page(*addr, length) == rvm_false) {
142 ret = RVM_EINTERNAL;
143 }
144
145 return ret;
146 }
147
148 rvm_return_t
deallocate_vm(addr,length)149 deallocate_vm(addr, length)
150 char *addr;
151 unsigned long length;
152 {
153 rvm_return_t ret = RVM_SUCCESS;
154
155 #ifdef HAVE_MMAP
156 if (munmap(addr, length)) {
157 ret = RVM_EINTERNAL;
158 }
159 #else
160 UnmapViewOfFile(addr);
161 #endif
162
163 if (rvm_unregister_page(addr, length) == rvm_false) {
164 ret = RVM_EINTERNAL;
165 }
166
167 return ret;
168 }
169
170
171