ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/vm_alloc.cpp
(Generate patch)

Comparing BasiliskII/src/Unix/vm_alloc.cpp (file contents):
Revision 1.12 by cebix, 2004-01-12T15:29:25Z vs.
Revision 1.13 by gbeauche, 2004-11-08T21:07:07Z

# Line 23 | Line 23
23   #include "config.h"
24   #endif
25  
26 + #ifdef HAVE_FCNTL_H
27 + #include <fcntl.h>
28 + #endif
29 +
30   // TODO: Win32 VMs ?
31 + #include <stdio.h>
32   #include <stdlib.h>
33   #include <string.h>
34 + #include <limits.h>
35   #include "vm_alloc.h"
36  
37   #ifdef HAVE_MACH_VM
# Line 45 | Line 51
51   #ifndef MAP_32BIT
52   #define MAP_32BIT 0
53   #endif
54 + #ifndef MAP_ANON
55 + #define MAP_ANON 0
56 + #endif
57 + #ifndef MAP_ANONYMOUS
58 + #define MAP_ANONYMOUS 0
59 + #endif
60  
61   #define MAP_EXTRA_FLAGS (MAP_32BIT)
62  
# Line 66 | Line 78 | static char * next_address = (char *)MAP
78   #define map_flags       (MAP_ANONYMOUS | MAP_EXTRA_FLAGS)
79   #define zero_fd         -1
80   #else
69 #ifdef HAVE_FCNTL_H
70 #include <fcntl.h>
71 #endif
81   #define map_flags       (MAP_EXTRA_FLAGS)
82   static int zero_fd      = -1;
83   #endif
84   #endif
85   #endif
86  
87 + /* Utility functions for POSIX SHM handling.  */
88 +
89 + #ifdef USE_33BIT_ADDRESSING
90 + struct shm_range_t {
91 +        const char *file;
92 +        void *base;
93 +        unsigned int size;
94 +        shm_range_t *next;
95 + };
96 +
97 + static shm_range_t *shm_ranges = NULL;
98 +
99 + static bool add_shm_range(const char *file, void *base, unsigned int size)
100 + {
101 +        shm_range_t *r = (shm_range_t *)malloc(sizeof(shm_range_t));
102 +        if (r) {
103 +                r->file = file;
104 +                r->base = base;
105 +                r->size = size;
106 +                r->next = shm_ranges ? shm_ranges : NULL;
107 +                shm_ranges = r;
108 +                return true;
109 +        }
110 +        return false;
111 + }
112 +
113 + static shm_range_t *find_shm_range(void *base, unsigned int size)
114 + {
115 +        for (shm_range_t *r = shm_ranges; r != NULL; r = r->next)
116 +                if (r->base == base && r->size == size)
117 +                        return r;
118 +        return NULL;
119 + }
120 +
121 + static bool remove_shm_range(shm_range_t *r)
122 + {
123 +        if (r) {
124 +                for (shm_range_t *p = shm_ranges; p != NULL; p = p->next) {
125 +                        if (p->next == r) {
126 +                                p->next = r->next;
127 +                                free(r);
128 +                                return true;
129 +                        }
130 +                }
131 +        }
132 +        return false;
133 + }
134 +
135 + static bool remove_shm_range(void *base, unsigned int size)
136 + {
137 +        remove_shm_range(find_shm_range(base, size));
138 + }
139 + #endif
140 +
141 + /* Build a POSIX SHM memory segment file descriptor name.  */
142 +
143 + #ifdef USE_33BIT_ADDRESSING
144 + static const char *build_shm_filename(void)
145 + {
146 +        static int id = 0;
147 +        static char filename[PATH_MAX];
148 +        
149 +        int ret = snprintf(filename, sizeof(filename), "/BasiliskII-%d-shm-%d", getpid(), id);
150 +        if (ret == -1 || ret >= sizeof(filename))
151 +                return NULL;
152 +
153 +        id++;
154 +        return filename;
155 + }
156 + #endif
157 +
158   /* Translate generic VM map flags to host values.  */
159  
160   #ifdef HAVE_MMAP_VM
# Line 136 | Line 216 | void * vm_acquire(size_t size, int optio
216                  return VM_MAP_FAILED;
217   #else
218   #ifdef HAVE_MMAP_VM
219 <        const int extra_map_flags = translate_map_flags(options);
219 >        int fd = zero_fd;
220 >        int the_map_flags = translate_map_flags(options) | map_flags;
221  
222 <        if ((addr = mmap((caddr_t)next_address, size, VM_PAGE_DEFAULT, extra_map_flags | map_flags, zero_fd, 0)) == (void *)MAP_FAILED)
222 > #ifdef USE_33BIT_ADDRESSING
223 >        const char *shm_file = NULL;
224 >        if (sizeof(void *) == 8 && (options & VM_MAP_33BIT)) {
225 >                the_map_flags &= ~(MAP_PRIVATE | MAP_ANON | MAP_ANONYMOUS);
226 >                the_map_flags |= MAP_SHARED;
227 >
228 >                if ((shm_file = build_shm_filename()) == NULL)
229 >                        return VM_MAP_FAILED;
230 >
231 >                if ((fd = shm_open(shm_file, O_RDWR | O_CREAT | O_EXCL, 0644)) < 0)
232 >                        return VM_MAP_FAILED;
233 >
234 >                if (ftruncate(fd, size) < 0)
235 >                        return VM_MAP_FAILED;
236 >
237 >                the_map_flags |= MAP_SHARED;
238 >        }
239 > #endif
240 >
241 >        if ((addr = mmap((caddr_t)next_address, size, VM_PAGE_DEFAULT, the_map_flags, fd, 0)) == (void *)MAP_FAILED)
242                  return VM_MAP_FAILED;
243          
244          // Sanity checks for 64-bit platforms
# Line 150 | Line 250 | void * vm_acquire(size_t size, int optio
250          // Since I don't know the standard behavior of mmap(), zero-fill here
251          if (memset(addr, 0, size) != addr)
252                  return VM_MAP_FAILED;
253 +
254 +        // Remap to 33-bit space
255 + #ifdef USE_33BIT_ADDRESSING
256 +        if (sizeof(void *) == 8 && (options & VM_MAP_33BIT)) {
257 +                if (!add_shm_range(strdup(shm_file), addr, size))
258 +                        return VM_MAP_FAILED;
259 +
260 +                if (mmap((char *)addr + (1L << 32), size, VM_PAGE_DEFAULT, the_map_flags | MAP_FIXED, fd, 0) == (void *)MAP_FAILED)
261 +                        return VM_MAP_FAILED;
262 +                close(fd);
263 +        }
264 + #endif
265   #else
266          if ((addr = calloc(size, 1)) == 0)
267                  return VM_MAP_FAILED;
# Line 220 | Line 332 | int vm_release(void * addr, size_t size)
332   #ifdef HAVE_MMAP_VM
333          if (munmap((caddr_t)addr, size) != 0)
334                  return -1;
335 +
336 + #ifdef USE_33BIT_ADDRESSING
337 +        shm_range_t *r = find_shm_range(addr, size);
338 +        if (r) {
339 +                if (munmap((char *)r->base + (1L << 32), size) != 0)
340 +                        return -1;
341 +
342 +                if (shm_unlink(r->file) < 0)
343 +                        return -1;
344 +                free((char *)r->file);
345 +
346 +                if (!remove_shm_range(r))
347 +                        return -1;
348 +        }
349 + #endif
350   #else
351          free(addr);
352   #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines