Mercurial > emacs
comparison src/buffer.c @ 31604:91e7cea32eaa
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.
| author | Gerd Moellmann <gerd@gnu.org> |
|---|---|
| date | Thu, 14 Sep 2000 15:14:02 +0000 |
| parents | 9b8c5bea5e8d |
| children | 2050f93e8cef |
comparison
equal
deleted
inserted
replaced
| 31603:04e50cacc23f | 31604:91e7cea32eaa |
|---|---|
| 174 | 174 |
| 175 Lisp_Object Qmodification_hooks; | 175 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 |
| 182 void | 186 void |
| 183 nsberror (spec) | 187 nsberror (spec) |
| 345 | 349 |
| 346 BUF_GAP_SIZE (b) = 20; | 350 BUF_GAP_SIZE (b) = 20; |
| 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 (); |
| 354 | 358 |
| 355 BUF_PT (b) = 1; | 359 BUF_PT (b) = 1; |
| 1299 | 1303 |
| 1300 b->name = Qnil; | 1304 b->name = Qnil; |
| 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 { |
| 1308 free_region_cache (b->newline_cache); | 1312 free_region_cache (b->newline_cache); |
| 1309 b->newline_cache = 0; | 1313 b->newline_cache = 0; |
| 1546 { | 1550 { |
| 1547 register struct buffer *old_buf; | 1551 register struct buffer *old_buf; |
| 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; |
| 1564 | 1562 |
| 1565 old_buf = current_buffer; | 1563 old_buf = current_buffer; |
| 4059 error ("Only %s should be stored in the buffer-local variable %s", | 4057 error ("Only %s should be stored in the buffer-local variable %s", |
| 4060 type_name, XSYMBOL (sym)->name->data); | 4058 type_name, XSYMBOL (sym)->name->data); |
| 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 { |
| 4067 int idx; | 4602 int idx; |
| 4068 | 4603 |
| 4232 char *pwd; | 4767 char *pwd; |
| 4233 struct stat dotstat, pwdstat; | 4768 struct stat dotstat, pwdstat; |
| 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)) |
| 4256 Fset_buffer_multibyte (Qnil); | 4787 Fset_buffer_multibyte (Qnil); |
| 4257 | 4788 |
