diff options
| author | Gerd Moellmann | 2000-09-14 15:14:02 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 2000-09-14 15:14:02 +0000 |
| commit | b86af064c5b7b8c8c290c4193e4e59ec640e50aa (patch) | |
| tree | 17ecd524726c166e34cbb0e9719c2efda612b59d /src | |
| parent | 71a7bfa7ee076eca9de5ed9ca737e06fcf7c4bec (diff) | |
| download | emacs-b86af064c5b7b8c8c290c4193e4e59ec640e50aa.tar.gz emacs-b86af064c5b7b8c8c290c4193e4e59ec640e50aa.zip | |
Move allocation with mmap here, from ralloc.c. Change
conditional compilation on REL_ALLOC_MMAP to USE_MMAP_FOR_BUFFERS.
(mmap_alloc, mmap_free, mmap_realloc) [REL_ALLOC_MMAP]: Renamed
from former r_alloc_* functions in ralloc.c.
(mmap_page_size, mmap_initialized_p) [REL_ALLOC_MMAP]: New
variables.
(MEM_ALIGN) [REL_ALLOC_MMAP]: New macro.
(mmap_init) [REL_ALLOC_MMAP]: New function.
(alloc_buffer_text, enlarge_buffer_text, free_buffer_text): New
functions replacing macros BUFFER_ALLOC, BUFFER_REALLOC, and
BUFFER_FREE.
Diffstat (limited to 'src')
| -rw-r--r-- | src/buffer.c | 567 |
1 files changed, 549 insertions, 18 deletions
diff --git a/src/buffer.c b/src/buffer.c index a839b1e97a9..5df8e2d17cd 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -176,6 +176,10 @@ Lisp_Object Qmodification_hooks; | |||
| 176 | Lisp_Object Qinsert_in_front_hooks; | 176 | Lisp_Object Qinsert_in_front_hooks; |
| 177 | Lisp_Object Qinsert_behind_hooks; | 177 | Lisp_Object Qinsert_behind_hooks; |
| 178 | 178 | ||
| 179 | static void alloc_buffer_text P_ ((struct buffer *, size_t)); | ||
| 180 | static void free_buffer_text P_ ((struct buffer *b)); | ||
| 181 | |||
| 182 | |||
| 179 | /* For debugging; temporary. See set_buffer_internal. */ | 183 | /* For debugging; temporary. See set_buffer_internal. */ |
| 180 | /* Lisp_Object Qlisp_mode, Vcheck_symbol; */ | 184 | /* Lisp_Object Qlisp_mode, Vcheck_symbol; */ |
| 181 | 185 | ||
| @@ -347,7 +351,7 @@ The value is never nil.") | |||
| 347 | BLOCK_INPUT; | 351 | BLOCK_INPUT; |
| 348 | /* We allocate extra 1-byte at the tail and keep it always '\0' for | 352 | /* We allocate extra 1-byte at the tail and keep it always '\0' for |
| 349 | anchoring a search. */ | 353 | anchoring a search. */ |
| 350 | BUFFER_ALLOC (BUF_BEG_ADDR (b), (BUF_GAP_SIZE (b) + 1)); | 354 | alloc_buffer_text (b, BUF_GAP_SIZE (b) + 1); |
| 351 | UNBLOCK_INPUT; | 355 | UNBLOCK_INPUT; |
| 352 | if (! BUF_BEG_ADDR (b)) | 356 | if (! BUF_BEG_ADDR (b)) |
| 353 | buffer_memory_full (); | 357 | buffer_memory_full (); |
| @@ -1301,7 +1305,7 @@ with SIGHUP.") | |||
| 1301 | 1305 | ||
| 1302 | BLOCK_INPUT; | 1306 | BLOCK_INPUT; |
| 1303 | if (! b->base_buffer) | 1307 | if (! b->base_buffer) |
| 1304 | BUFFER_FREE (BUF_BEG_ADDR (b)); | 1308 | free_buffer_text (b); |
| 1305 | 1309 | ||
| 1306 | if (b->newline_cache) | 1310 | if (b->newline_cache) |
| 1307 | { | 1311 | { |
| @@ -1548,16 +1552,10 @@ set_buffer_internal_1 (b) | |||
| 1548 | register Lisp_Object tail, valcontents; | 1552 | register Lisp_Object tail, valcontents; |
| 1549 | Lisp_Object tem; | 1553 | Lisp_Object tem; |
| 1550 | 1554 | ||
| 1551 | #ifdef REL_ALLOC_MMAP | 1555 | #ifdef USE_MMAP_FOR_BUFFERS |
| 1552 | if (b->text->beg == NULL) | 1556 | if (b->text->beg == NULL) |
| 1553 | { | 1557 | enlarge_buffer_text (b, 0); |
| 1554 | BLOCK_INPUT; | 1558 | #endif /* USE_MMAP_FOR_BUFFERS */ |
| 1555 | BUFFER_REALLOC (BUF_BEG_ADDR (b), | ||
| 1556 | (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) | ||
| 1557 | + BUF_GAP_SIZE (b) + 1)); | ||
| 1558 | UNBLOCK_INPUT; | ||
| 1559 | } | ||
| 1560 | #endif /* REL_ALLOC_MMAP */ | ||
| 1561 | 1559 | ||
| 1562 | if (current_buffer == b) | 1560 | if (current_buffer == b) |
| 1563 | return; | 1561 | return; |
| @@ -4061,6 +4059,543 @@ buffer_slot_type_mismatch (offset) | |||
| 4061 | } | 4059 | } |
| 4062 | 4060 | ||
| 4063 | 4061 | ||
| 4062 | /*********************************************************************** | ||
| 4063 | Allocation with mmap | ||
| 4064 | ***********************************************************************/ | ||
| 4065 | |||
| 4066 | #ifdef USE_MMAP_FOR_BUFFERS | ||
| 4067 | |||
| 4068 | #include <sys/types.h> | ||
| 4069 | #include <sys/mman.h> | ||
| 4070 | |||
| 4071 | #ifndef MAP_ANON | ||
| 4072 | #ifdef MAP_ANONYMOUS | ||
| 4073 | #define MAP_ANON MAP_ANONYMOUS | ||
| 4074 | #else | ||
| 4075 | #define MAP_ANON 0 | ||
| 4076 | #endif | ||
| 4077 | #endif | ||
| 4078 | |||
| 4079 | #include <stdio.h> | ||
| 4080 | #include <errno.h> | ||
| 4081 | |||
| 4082 | #if MAP_ANON == 0 | ||
| 4083 | #include <fcntl.h> | ||
| 4084 | #endif | ||
| 4085 | |||
| 4086 | #include "coding.h" | ||
| 4087 | |||
| 4088 | |||
| 4089 | /* Memory is allocated in regions which are mapped using mmap(2). | ||
| 4090 | The current implementation lets the system select mapped | ||
| 4091 | addresses; we're not using MAP_FIXED in general, except when | ||
| 4092 | trying to enlarge regions. | ||
| 4093 | |||
| 4094 | Each mapped region starts with a mmap_region structure, the user | ||
| 4095 | area starts after that structure, aligned to MEM_ALIGN. | ||
| 4096 | |||
| 4097 | +-----------------------+ | ||
| 4098 | | struct mmap_info + | | ||
| 4099 | | padding | | ||
| 4100 | +-----------------------+ | ||
| 4101 | | user data | | ||
| 4102 | | | | ||
| 4103 | | | | ||
| 4104 | +-----------------------+ */ | ||
| 4105 | |||
| 4106 | struct mmap_region | ||
| 4107 | { | ||
| 4108 | /* User-specified size. */ | ||
| 4109 | size_t nbytes_specified; | ||
| 4110 | |||
| 4111 | /* Number of bytes mapped */ | ||
| 4112 | size_t nbytes_mapped; | ||
| 4113 | |||
| 4114 | /* Pointer to the location holding the address of the memory | ||
| 4115 | allocated with the mmap'd block. The variable actually points | ||
| 4116 | after this structure. */ | ||
| 4117 | POINTER_TYPE **var; | ||
| 4118 | |||
| 4119 | /* Next and previous in list of all mmap'd regions. */ | ||
| 4120 | struct mmap_region *next, *prev; | ||
| 4121 | }; | ||
| 4122 | |||
| 4123 | /* Doubly-linked list of mmap'd regions. */ | ||
| 4124 | |||
| 4125 | static struct mmap_region *mmap_regions; | ||
| 4126 | |||
| 4127 | /* File descriptor for mmap. If we don't have anonymous mapping, | ||
| 4128 | /dev/zero will be opened on it. */ | ||
| 4129 | |||
| 4130 | static int mmap_fd; | ||
| 4131 | |||
| 4132 | /* Temporary storage for mmap_set_vars, see there. */ | ||
| 4133 | |||
| 4134 | static struct mmap_region *mmap_regions_1; | ||
| 4135 | static int mmap_fd_1; | ||
| 4136 | |||
| 4137 | /* Page size on this system. */ | ||
| 4138 | |||
| 4139 | static int mmap_page_size; | ||
| 4140 | |||
| 4141 | /* 1 means mmap has been intialized. */ | ||
| 4142 | |||
| 4143 | static int mmap_initialized_p; | ||
| 4144 | |||
| 4145 | /* Value is X rounded up to the next multiple of N. */ | ||
| 4146 | |||
| 4147 | #define ROUND(X, N) (((X) + (N) - 1) / (N) * (N)) | ||
| 4148 | |||
| 4149 | /* Size of mmap_region structure plus padding. */ | ||
| 4150 | |||
| 4151 | #define MMAP_REGION_STRUCT_SIZE \ | ||
| 4152 | ROUND (sizeof (struct mmap_region), MEM_ALIGN) | ||
| 4153 | |||
| 4154 | /* Given a pointer P to the start of the user-visible part of a mapped | ||
| 4155 | region, return a pointer to the start of the region. */ | ||
| 4156 | |||
| 4157 | #define MMAP_REGION(P) \ | ||
| 4158 | ((struct mmap_region *) ((char *) (P) - MMAP_REGION_STRUCT_SIZE)) | ||
| 4159 | |||
| 4160 | /* Given a pointer P to the start of a mapped region, return a pointer | ||
| 4161 | to the start of the user-visible part of the region. */ | ||
| 4162 | |||
| 4163 | #define MMAP_USER_AREA(P) \ | ||
| 4164 | ((POINTER_TYPE *) ((char *) (P) + MMAP_REGION_STRUCT_SIZE)) | ||
| 4165 | |||
| 4166 | #define MEM_ALIGN sizeof (double) | ||
| 4167 | |||
| 4168 | /* Function prototypes. */ | ||
| 4169 | |||
| 4170 | static int mmap_free_1 P_ ((struct mmap_region *)); | ||
| 4171 | static int mmap_enlarge P_ ((struct mmap_region *, int)); | ||
| 4172 | static struct mmap_region *mmap_find P_ ((POINTER_TYPE *, POINTER_TYPE *)); | ||
| 4173 | static POINTER_TYPE *mmap_alloc P_ ((POINTER_TYPE **, size_t)); | ||
| 4174 | static POINTER_TYPE *mmap_realloc P_ ((POINTER_TYPE **, size_t)); | ||
| 4175 | static void mmap_free P_ ((POINTER_TYPE **ptr)); | ||
| 4176 | static void mmap_init P_ ((void)); | ||
| 4177 | |||
| 4178 | |||
| 4179 | /* Return a region overlapping address range START...END, or null if | ||
| 4180 | none. END is not including, i.e. the last byte in the range | ||
| 4181 | is at END - 1. */ | ||
| 4182 | |||
| 4183 | static struct mmap_region * | ||
| 4184 | mmap_find (start, end) | ||
| 4185 | POINTER_TYPE *start, *end; | ||
| 4186 | { | ||
| 4187 | struct mmap_region *r; | ||
| 4188 | char *s = (char *) start, *e = (char *) end; | ||
| 4189 | |||
| 4190 | for (r = mmap_regions; r; r = r->next) | ||
| 4191 | { | ||
| 4192 | char *rstart = (char *) r; | ||
| 4193 | char *rend = rstart + r->nbytes_mapped; | ||
| 4194 | |||
| 4195 | if (/* First byte of range, i.e. START, in this region? */ | ||
| 4196 | (s >= rstart && s < rend) | ||
| 4197 | /* Last byte of range, i.e. END - 1, in this region? */ | ||
| 4198 | || (e > rstart && e <= rend) | ||
| 4199 | /* First byte of this region in the range? */ | ||
| 4200 | || (rstart >= s && rstart < e) | ||
| 4201 | /* Last byte of this region in the range? */ | ||
| 4202 | || (rend > s && rend <= e)) | ||
| 4203 | break; | ||
| 4204 | } | ||
| 4205 | |||
| 4206 | return r; | ||
| 4207 | } | ||
| 4208 | |||
| 4209 | |||
| 4210 | /* Unmap a region. P is a pointer to the start of the user-araa of | ||
| 4211 | the region. Value is non-zero if successful. */ | ||
| 4212 | |||
| 4213 | static int | ||
| 4214 | mmap_free_1 (r) | ||
| 4215 | struct mmap_region *r; | ||
| 4216 | { | ||
| 4217 | if (r->next) | ||
| 4218 | r->next->prev = r->prev; | ||
| 4219 | if (r->prev) | ||
| 4220 | r->prev->next = r->next; | ||
| 4221 | else | ||
| 4222 | mmap_regions = r->next; | ||
| 4223 | |||
| 4224 | if (munmap (r, r->nbytes_mapped) == -1) | ||
| 4225 | { | ||
| 4226 | fprintf (stderr, "munmap: %s\n", emacs_strerror (errno)); | ||
| 4227 | return 0; | ||
| 4228 | } | ||
| 4229 | |||
| 4230 | return 1; | ||
| 4231 | } | ||
| 4232 | |||
| 4233 | |||
| 4234 | /* Enlarge region R by NPAGES pages. NPAGES < 0 means shrink R. | ||
| 4235 | Value is non-zero if successful. */ | ||
| 4236 | |||
| 4237 | static int | ||
| 4238 | mmap_enlarge (r, npages) | ||
| 4239 | struct mmap_region *r; | ||
| 4240 | int npages; | ||
| 4241 | { | ||
| 4242 | char *region_end = (char *) r + r->nbytes_mapped; | ||
| 4243 | size_t nbytes; | ||
| 4244 | int success = 0; | ||
| 4245 | |||
| 4246 | if (npages < 0) | ||
| 4247 | { | ||
| 4248 | /* Unmap pages at the end of the region. */ | ||
| 4249 | nbytes = - npages * mmap_page_size; | ||
| 4250 | if (munmap (region_end - nbytes, nbytes) == -1) | ||
| 4251 | fprintf (stderr, "munmap: %s\n", emacs_strerror (errno)); | ||
| 4252 | else | ||
| 4253 | { | ||
| 4254 | r->nbytes_mapped -= nbytes; | ||
| 4255 | success = 1; | ||
| 4256 | } | ||
| 4257 | } | ||
| 4258 | else if (npages > 0) | ||
| 4259 | { | ||
| 4260 | struct mmap_region *r2; | ||
| 4261 | |||
| 4262 | nbytes = npages * mmap_page_size; | ||
| 4263 | |||
| 4264 | /* Try to map additional pages at the end of the region. We | ||
| 4265 | cannot do this if the address range is already occupied by | ||
| 4266 | something else because mmap deletes any previous mapping. | ||
| 4267 | I'm not sure this is worth doing, let's see. */ | ||
| 4268 | r2 = mmap_find (region_end, region_end + nbytes); | ||
| 4269 | if (r2 == NULL) | ||
| 4270 | { | ||
| 4271 | POINTER_TYPE *p; | ||
| 4272 | |||
| 4273 | p = mmap (region_end, nbytes, PROT_READ | PROT_WRITE, | ||
| 4274 | MAP_ANON | MAP_PRIVATE | MAP_FIXED, mmap_fd, 0); | ||
| 4275 | if (p == MAP_FAILED) | ||
| 4276 | fprintf (stderr, "mmap: %s\n", emacs_strerror (errno)); | ||
| 4277 | else if (p != (POINTER_TYPE *) region_end) | ||
| 4278 | { | ||
| 4279 | /* Kernels are free to choose a different address. In | ||
| 4280 | that case, unmap what we've mapped above; we have | ||
| 4281 | no use for it. */ | ||
| 4282 | if (munmap (p, nbytes) == -1) | ||
| 4283 | fprintf (stderr, "munmap: %s\n", emacs_strerror (errno)); | ||
| 4284 | } | ||
| 4285 | else | ||
| 4286 | { | ||
| 4287 | r->nbytes_mapped += nbytes; | ||
| 4288 | success = 1; | ||
| 4289 | } | ||
| 4290 | } | ||
| 4291 | } | ||
| 4292 | |||
| 4293 | return success; | ||
| 4294 | } | ||
| 4295 | |||
| 4296 | |||
| 4297 | /* Set or reset variables holding references to mapped regions. If | ||
| 4298 | RESTORE_P is zero, set all variables to null. If RESTORE_P is | ||
| 4299 | non-zero, set all variables to the start of the user-areas | ||
| 4300 | of mapped regions. | ||
| 4301 | |||
| 4302 | This function is called from Fdump_emacs to ensure that the dumped | ||
| 4303 | Emacs doesn't contain references to memory that won't be mapped | ||
| 4304 | when Emacs starts. */ | ||
| 4305 | |||
| 4306 | void | ||
| 4307 | mmap_set_vars (restore_p) | ||
| 4308 | int restore_p; | ||
| 4309 | { | ||
| 4310 | struct mmap_region *r; | ||
| 4311 | |||
| 4312 | if (restore_p) | ||
| 4313 | { | ||
| 4314 | mmap_regions = mmap_regions_1; | ||
| 4315 | mmap_fd = mmap_fd_1; | ||
| 4316 | for (r = mmap_regions; r; r = r->next) | ||
| 4317 | *r->var = MMAP_USER_AREA (r); | ||
| 4318 | } | ||
| 4319 | else | ||
| 4320 | { | ||
| 4321 | for (r = mmap_regions; r; r = r->next) | ||
| 4322 | *r->var = NULL; | ||
| 4323 | mmap_regions_1 = mmap_regions; | ||
| 4324 | mmap_regions = NULL; | ||
| 4325 | mmap_fd_1 = mmap_fd; | ||
| 4326 | mmap_fd = -1; | ||
| 4327 | } | ||
| 4328 | } | ||
| 4329 | |||
| 4330 | |||
| 4331 | /* Allocate a block of storage large enough to hold NBYTES bytes of | ||
| 4332 | data. A pointer to the data is returned in *VAR. VAR is thus the | ||
| 4333 | address of some variable which will use the data area. | ||
| 4334 | |||
| 4335 | The allocation of 0 bytes is valid. | ||
| 4336 | |||
| 4337 | If we can't allocate the necessary memory, set *VAR to null, and | ||
| 4338 | return null. */ | ||
| 4339 | |||
| 4340 | static POINTER_TYPE * | ||
| 4341 | mmap_alloc (var, nbytes) | ||
| 4342 | POINTER_TYPE **var; | ||
| 4343 | size_t nbytes; | ||
| 4344 | { | ||
| 4345 | void *p; | ||
| 4346 | size_t map; | ||
| 4347 | |||
| 4348 | mmap_init (); | ||
| 4349 | |||
| 4350 | map = ROUND (nbytes + MMAP_REGION_STRUCT_SIZE, mmap_page_size); | ||
| 4351 | p = mmap (NULL, map, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, | ||
| 4352 | mmap_fd, 0); | ||
| 4353 | |||
| 4354 | if (p == MAP_FAILED) | ||
| 4355 | { | ||
| 4356 | if (errno != ENOMEM) | ||
| 4357 | fprintf (stderr, "mmap: %s\n", emacs_strerror (errno)); | ||
| 4358 | p = NULL; | ||
| 4359 | } | ||
| 4360 | else | ||
| 4361 | { | ||
| 4362 | struct mmap_region *r = (struct mmap_region *) p; | ||
| 4363 | |||
| 4364 | r->nbytes_specified = nbytes; | ||
| 4365 | r->nbytes_mapped = map; | ||
| 4366 | r->var = var; | ||
| 4367 | r->prev = NULL; | ||
| 4368 | r->next = mmap_regions; | ||
| 4369 | if (r->next) | ||
| 4370 | r->next->prev = r; | ||
| 4371 | mmap_regions = r; | ||
| 4372 | |||
| 4373 | p = MMAP_USER_AREA (p); | ||
| 4374 | } | ||
| 4375 | |||
| 4376 | return *var = p; | ||
| 4377 | } | ||
| 4378 | |||
| 4379 | |||
| 4380 | /* Given a pointer at address VAR to data allocated with mmap_alloc, | ||
| 4381 | resize it to size NBYTES. Change *VAR to reflect the new block, | ||
| 4382 | and return this value. If more memory cannot be allocated, then | ||
| 4383 | leave *VAR unchanged, and return null. */ | ||
| 4384 | |||
| 4385 | static POINTER_TYPE * | ||
| 4386 | mmap_realloc (var, nbytes) | ||
| 4387 | POINTER_TYPE **var; | ||
| 4388 | size_t nbytes; | ||
| 4389 | { | ||
| 4390 | POINTER_TYPE *result; | ||
| 4391 | |||
| 4392 | mmap_init (); | ||
| 4393 | |||
| 4394 | if (*var == NULL) | ||
| 4395 | result = mmap_alloc (var, nbytes); | ||
| 4396 | else if (nbytes == 0) | ||
| 4397 | { | ||
| 4398 | mmap_free (var); | ||
| 4399 | result = mmap_alloc (var, nbytes); | ||
| 4400 | } | ||
| 4401 | else | ||
| 4402 | { | ||
| 4403 | struct mmap_region *r = MMAP_REGION (*var); | ||
| 4404 | size_t room = r->nbytes_mapped - MMAP_REGION_STRUCT_SIZE; | ||
| 4405 | |||
| 4406 | if (room < nbytes) | ||
| 4407 | { | ||
| 4408 | /* Must enlarge. */ | ||
| 4409 | POINTER_TYPE *old_ptr = *var; | ||
| 4410 | |||
| 4411 | /* Try to map additional pages at the end of the region. | ||
| 4412 | If that fails, allocate a new region, copy data | ||
| 4413 | from the old region, then free it. */ | ||
| 4414 | if (mmap_enlarge (r, (ROUND (nbytes - room, mmap_page_size) | ||
| 4415 | / mmap_page_size))) | ||
| 4416 | { | ||
| 4417 | r->nbytes_specified = nbytes; | ||
| 4418 | *var = result = old_ptr; | ||
| 4419 | } | ||
| 4420 | else if (mmap_alloc (var, nbytes)) | ||
| 4421 | { | ||
| 4422 | bcopy (old_ptr, *var, r->nbytes_specified); | ||
| 4423 | mmap_free_1 (MMAP_REGION (old_ptr)); | ||
| 4424 | result = *var; | ||
| 4425 | r = MMAP_REGION (result); | ||
| 4426 | r->nbytes_specified = nbytes; | ||
| 4427 | } | ||
| 4428 | else | ||
| 4429 | { | ||
| 4430 | *var = old_ptr; | ||
| 4431 | result = NULL; | ||
| 4432 | } | ||
| 4433 | } | ||
| 4434 | else if (room - nbytes >= mmap_page_size) | ||
| 4435 | { | ||
| 4436 | /* Shrinking by at least a page. Let's give some | ||
| 4437 | memory back to the system. */ | ||
| 4438 | mmap_enlarge (r, - (room - nbytes) / mmap_page_size); | ||
| 4439 | result = *var; | ||
| 4440 | r->nbytes_specified = nbytes; | ||
| 4441 | } | ||
| 4442 | else | ||
| 4443 | { | ||
| 4444 | /* Leave it alone. */ | ||
| 4445 | result = *var; | ||
| 4446 | r->nbytes_specified = nbytes; | ||
| 4447 | } | ||
| 4448 | } | ||
| 4449 | |||
| 4450 | return result; | ||
| 4451 | } | ||
| 4452 | |||
| 4453 | |||
| 4454 | /* Free a block of relocatable storage whose data is pointed to by | ||
| 4455 | PTR. Store 0 in *PTR to show there's no block allocated. */ | ||
| 4456 | |||
| 4457 | static void | ||
| 4458 | mmap_free (var) | ||
| 4459 | POINTER_TYPE **var; | ||
| 4460 | { | ||
| 4461 | mmap_init (); | ||
| 4462 | |||
| 4463 | if (*var) | ||
| 4464 | { | ||
| 4465 | mmap_free_1 (MMAP_REGION (*var)); | ||
| 4466 | *var = NULL; | ||
| 4467 | } | ||
| 4468 | } | ||
| 4469 | |||
| 4470 | |||
| 4471 | /* Perform necessary intializations for the use of mmap. */ | ||
| 4472 | |||
| 4473 | static void | ||
| 4474 | mmap_init () | ||
| 4475 | { | ||
| 4476 | #if MAP_ANON == 0 | ||
| 4477 | /* The value of mmap_fd is initially 0 in temacs, and -1 | ||
| 4478 | in a dumped Emacs. */ | ||
| 4479 | if (mmap_fd <= 0) | ||
| 4480 | { | ||
| 4481 | /* No anonymous mmap -- we need the file descriptor. */ | ||
| 4482 | mmap_fd = open ("/dev/zero", O_RDONLY); | ||
| 4483 | if (mmap_fd == -1) | ||
| 4484 | fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno)); | ||
| 4485 | } | ||
| 4486 | #endif /* MAP_ANON == 0 */ | ||
| 4487 | |||
| 4488 | if (mmap_initialized_p) | ||
| 4489 | return; | ||
| 4490 | mmap_initialized_p = 1; | ||
| 4491 | |||
| 4492 | #if MAP_ANON != 0 | ||
| 4493 | mmap_fd = -1; | ||
| 4494 | #endif | ||
| 4495 | |||
| 4496 | mmap_page_size = getpagesize (); | ||
| 4497 | } | ||
| 4498 | |||
| 4499 | #endif /* USE_MMAP_FOR_BUFFERS */ | ||
| 4500 | |||
| 4501 | |||
| 4502 | |||
| 4503 | /*********************************************************************** | ||
| 4504 | Buffer-text Allocation | ||
| 4505 | ***********************************************************************/ | ||
| 4506 | |||
| 4507 | #ifdef REL_ALLOC | ||
| 4508 | extern POINTER_TYPE *r_alloc P_ ((POINTER_TYPE **, size_t)); | ||
| 4509 | extern POINTER_TYPE *r_re_alloc P_ ((POINTER_TYPE **, size_t)); | ||
| 4510 | extern void r_alloc_free P_ ((POINTER_TYPE **ptr)); | ||
| 4511 | #endif /* REL_ALLOC */ | ||
| 4512 | |||
| 4513 | |||
| 4514 | /* Allocate NBYTES bytes for buffer B's text buffer. */ | ||
| 4515 | |||
| 4516 | static void | ||
| 4517 | alloc_buffer_text (b, nbytes) | ||
| 4518 | struct buffer *b; | ||
| 4519 | size_t nbytes; | ||
| 4520 | { | ||
| 4521 | POINTER_TYPE *p; | ||
| 4522 | |||
| 4523 | BLOCK_INPUT; | ||
| 4524 | #if defined USE_MMAP_FOR_BUFFERS | ||
| 4525 | p = mmap_alloc ((POINTER_TYPE **) &b->text->beg, nbytes); | ||
| 4526 | #elif defined REL_ALLOC | ||
| 4527 | p = r_alloc ((POINTER_TYPE **) &b->text->beg, nbytes); | ||
| 4528 | #else | ||
| 4529 | p = xmalloc (b->text->beg, nbytes); | ||
| 4530 | #endif | ||
| 4531 | |||
| 4532 | if (p == NULL) | ||
| 4533 | { | ||
| 4534 | UNBLOCK_INPUT; | ||
| 4535 | memory_full (); | ||
| 4536 | } | ||
| 4537 | |||
| 4538 | b->text->beg = (unsigned char *) p; | ||
| 4539 | UNBLOCK_INPUT; | ||
| 4540 | } | ||
| 4541 | |||
| 4542 | /* Enlarge buffer B's text buffer by DELTA bytes. DELTA < 0 means | ||
| 4543 | shrink it. */ | ||
| 4544 | |||
| 4545 | void | ||
| 4546 | enlarge_buffer_text (b, delta) | ||
| 4547 | struct buffer *b; | ||
| 4548 | int delta; | ||
| 4549 | { | ||
| 4550 | POINTER_TYPE *p; | ||
| 4551 | size_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1 | ||
| 4552 | + delta); | ||
| 4553 | BLOCK_INPUT; | ||
| 4554 | #if defined USE_MMAP_FOR_BUFFERS | ||
| 4555 | p = mmap_realloc ((POINTER_TYPE **) &b->text->beg, nbytes); | ||
| 4556 | #elif defined REL_ALLOC | ||
| 4557 | p = r_re_alloc ((POINTER_TYPE **) &b->text->beg, nbytes); | ||
| 4558 | #else | ||
| 4559 | p = xrealloc (b->text->beg, nbytes); | ||
| 4560 | #endif | ||
| 4561 | |||
| 4562 | if (p == NULL) | ||
| 4563 | { | ||
| 4564 | UNBLOCK_INPUT; | ||
| 4565 | memory_full (); | ||
| 4566 | } | ||
| 4567 | |||
| 4568 | BUF_BEG_ADDR (b) = (unsigned char *) p; | ||
| 4569 | UNBLOCK_INPUT; | ||
| 4570 | } | ||
| 4571 | |||
| 4572 | |||
| 4573 | /* Free buffer B's text buffer. */ | ||
| 4574 | |||
| 4575 | static void | ||
| 4576 | free_buffer_text (b) | ||
| 4577 | struct buffer *b; | ||
| 4578 | { | ||
| 4579 | BLOCK_INPUT; | ||
| 4580 | |||
| 4581 | #if defined USE_MMAP_FOR_BUFFERS | ||
| 4582 | mmap_free ((POINTER_TYPE **) &b->text->beg); | ||
| 4583 | #elif defined REL_ALLOC | ||
| 4584 | r_alloc_free ((POINTER_TYPE **) &b->text->beg); | ||
| 4585 | #else | ||
| 4586 | xfree (b->text->beg); | ||
| 4587 | #endif | ||
| 4588 | |||
| 4589 | BUF_BEG_ADDR (b) = NULL; | ||
| 4590 | UNBLOCK_INPUT; | ||
| 4591 | } | ||
| 4592 | |||
| 4593 | |||
| 4594 | |||
| 4595 | /*********************************************************************** | ||
| 4596 | Initialization | ||
| 4597 | ***********************************************************************/ | ||
| 4598 | |||
| 4064 | void | 4599 | void |
| 4065 | init_buffer_once () | 4600 | init_buffer_once () |
| 4066 | { | 4601 | { |
| @@ -4234,22 +4769,18 @@ init_buffer () | |||
| 4234 | Lisp_Object temp; | 4769 | Lisp_Object temp; |
| 4235 | int rc; | 4770 | int rc; |
| 4236 | 4771 | ||
| 4237 | #ifdef REL_ALLOC_MMAP | 4772 | #ifdef USE_MMAP_FOR_BUFFERS |
| 4238 | { | 4773 | { |
| 4239 | /* When using the ralloc implementation based on mmap(2), buffer | 4774 | /* When using the ralloc implementation based on mmap(2), buffer |
| 4240 | text pointers will have been set to null in the dumped Emacs. | 4775 | text pointers will have been set to null in the dumped Emacs. |
| 4241 | Map new memory. */ | 4776 | Map new memory. */ |
| 4242 | struct buffer *b; | 4777 | struct buffer *b; |
| 4243 | 4778 | ||
| 4244 | BLOCK_INPUT; | ||
| 4245 | for (b = all_buffers; b; b = b->next) | 4779 | for (b = all_buffers; b; b = b->next) |
| 4246 | if (b->text->beg == NULL) | 4780 | if (b->text->beg == NULL) |
| 4247 | BUFFER_REALLOC (BUF_BEG_ADDR (b), | 4781 | enlarge_buffer_text (b, 0); |
| 4248 | (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) | ||
| 4249 | + BUF_GAP_SIZE (b) + 1)); | ||
| 4250 | UNBLOCK_INPUT; | ||
| 4251 | } | 4782 | } |
| 4252 | #endif /* REL_ALLOC_MMAP */ | 4783 | #endif /* USE_MMAP_FOR_BUFFERS */ |
| 4253 | 4784 | ||
| 4254 | Fset_buffer (Fget_buffer_create (build_string ("*scratch*"))); | 4785 | Fset_buffer (Fget_buffer_create (build_string ("*scratch*"))); |
| 4255 | if (NILP (buffer_defaults.enable_multibyte_characters)) | 4786 | if (NILP (buffer_defaults.enable_multibyte_characters)) |