Mercurial > emacs
comparison src/alloc.c @ 58818:f8cddae7d959
* gtkutil.c: Include signal.h and syssignal.h.
(xg_get_file_name): Block and unblock __SIGRTMIN if defined.
* alloc.c: If HAVE_GTK_AND_PTHREAD, include pthread.h,
new variables main_thread and alloc_mutex,
define (UN)BLOCK_INPUT_ALLOC to use alloc_mutex to protect
emacs_blocked_* calls and only do (UN)BLOCK_INPUT in the main thread.
If not HAVE_GTK_AND_PTHREAD, (UN)BLOCK_INPUT_ALLOC is the same as
(UN)BLOCK_INPUT.
(emacs_blocked_free, emacs_blocked_malloc)
(emacs_blocked_realloc): Use (UN)BLOCK_INPUT_ALLOC.
(uninterrupt_malloc): Initialize main_thread and alloc_mutex.
(reset_malloc_hooks): New function.
* lisp.h: Declare reset_malloc_hooks.
* emacs.c (Fdump_emacs): Call reset_malloc_hooks.
* keyboard.c: Conditionally include pthread.h
(handle_async_inpu, input_available_signalt): If not in the main
thread, block signal, send signal to main thread and return.
author | Jan Djärv <jan.h.d@swipnet.se> |
---|---|
date | Tue, 07 Dec 2004 08:25:43 +0000 |
parents | 57741ce4cd6b |
children | 408c5135b0a2 549734260e34 |
comparison
equal
deleted
inserted
replaced
58817:65f1b18b7f66 | 58818:f8cddae7d959 |
---|---|
28 #endif | 28 #endif |
29 | 29 |
30 /* Note that this declares bzero on OSF/1. How dumb. */ | 30 /* Note that this declares bzero on OSF/1. How dumb. */ |
31 | 31 |
32 #include <signal.h> | 32 #include <signal.h> |
33 | |
34 #ifdef HAVE_GTK_AND_PTHREAD | |
35 #include <pthread.h> | |
36 #endif | |
33 | 37 |
34 /* This file is part of the core Lisp implementation, and thus must | 38 /* This file is part of the core Lisp implementation, and thus must |
35 deal with the real data structures. If the Lisp implementation is | 39 deal with the real data structures. If the Lisp implementation is |
36 replaced, this file likely will not be used. */ | 40 replaced, this file likely will not be used. */ |
37 | 41 |
82 #define __malloc_size_t size_t | 86 #define __malloc_size_t size_t |
83 extern __malloc_size_t _bytes_used; | 87 extern __malloc_size_t _bytes_used; |
84 extern __malloc_size_t __malloc_extra_blocks; | 88 extern __malloc_size_t __malloc_extra_blocks; |
85 | 89 |
86 #endif /* not DOUG_LEA_MALLOC */ | 90 #endif /* not DOUG_LEA_MALLOC */ |
91 | |
92 #if ! defined (SYSTEM_MALLOC) && defined (HAVE_GTK_AND_PTHREAD) | |
93 | |
94 static pthread_mutex_t alloc_mutex; | |
95 pthread_t main_thread; | |
96 | |
97 #define BLOCK_INPUT_ALLOC \ | |
98 do \ | |
99 { \ | |
100 pthread_mutex_lock (&alloc_mutex); \ | |
101 if (pthread_self () == main_thread) \ | |
102 BLOCK_INPUT; \ | |
103 } \ | |
104 while (0) | |
105 #define UNBLOCK_INPUT_ALLOC \ | |
106 do \ | |
107 { \ | |
108 if (pthread_self () == main_thread) \ | |
109 UNBLOCK_INPUT; \ | |
110 pthread_mutex_unlock (&alloc_mutex); \ | |
111 } \ | |
112 while (0) | |
113 | |
114 #else /* SYSTEM_MALLOC || not HAVE_GTK_AND_PTHREAD */ | |
115 | |
116 #define BLOCK_INPUT_ALLOC BLOCK_INPUT | |
117 #define UNBLOCK_INPUT_ALLOC UNBLOCK_INPUT | |
118 | |
119 #endif /* SYSTEM_MALLOC || not HAVE_GTK_AND_PTHREAD */ | |
87 | 120 |
88 /* Value of _bytes_used, when spare_memory was freed. */ | 121 /* Value of _bytes_used, when spare_memory was freed. */ |
89 | 122 |
90 static __malloc_size_t bytes_used_when_full; | 123 static __malloc_size_t bytes_used_when_full; |
91 | 124 |
1066 | 1099 |
1067 static void | 1100 static void |
1068 emacs_blocked_free (ptr) | 1101 emacs_blocked_free (ptr) |
1069 void *ptr; | 1102 void *ptr; |
1070 { | 1103 { |
1071 BLOCK_INPUT; | 1104 BLOCK_INPUT_ALLOC; |
1072 | 1105 |
1073 #ifdef GC_MALLOC_CHECK | 1106 #ifdef GC_MALLOC_CHECK |
1074 if (ptr) | 1107 if (ptr) |
1075 { | 1108 { |
1076 struct mem_node *m; | 1109 struct mem_node *m; |
1104 && (bytes_used_when_full | 1137 && (bytes_used_when_full |
1105 > BYTES_USED + max (malloc_hysteresis, 4) * SPARE_MEMORY)) | 1138 > BYTES_USED + max (malloc_hysteresis, 4) * SPARE_MEMORY)) |
1106 spare_memory = (char *) malloc ((size_t) SPARE_MEMORY); | 1139 spare_memory = (char *) malloc ((size_t) SPARE_MEMORY); |
1107 | 1140 |
1108 __free_hook = emacs_blocked_free; | 1141 __free_hook = emacs_blocked_free; |
1109 UNBLOCK_INPUT; | 1142 UNBLOCK_INPUT_ALLOC; |
1110 } | 1143 } |
1111 | 1144 |
1112 | 1145 |
1113 /* If we released our reserve (due to running out of memory), | 1146 /* If we released our reserve (due to running out of memory), |
1114 and we have a fair amount free once again, | 1147 and we have a fair amount free once again, |
1130 emacs_blocked_malloc (size) | 1163 emacs_blocked_malloc (size) |
1131 size_t size; | 1164 size_t size; |
1132 { | 1165 { |
1133 void *value; | 1166 void *value; |
1134 | 1167 |
1135 BLOCK_INPUT; | 1168 BLOCK_INPUT_ALLOC; |
1136 __malloc_hook = old_malloc_hook; | 1169 __malloc_hook = old_malloc_hook; |
1137 #ifdef DOUG_LEA_MALLOC | 1170 #ifdef DOUG_LEA_MALLOC |
1138 mallopt (M_TOP_PAD, malloc_hysteresis * 4096); | 1171 mallopt (M_TOP_PAD, malloc_hysteresis * 4096); |
1139 #else | 1172 #else |
1140 __malloc_extra_blocks = malloc_hysteresis; | 1173 __malloc_extra_blocks = malloc_hysteresis; |
1162 } | 1195 } |
1163 } | 1196 } |
1164 #endif /* GC_MALLOC_CHECK */ | 1197 #endif /* GC_MALLOC_CHECK */ |
1165 | 1198 |
1166 __malloc_hook = emacs_blocked_malloc; | 1199 __malloc_hook = emacs_blocked_malloc; |
1167 UNBLOCK_INPUT; | 1200 UNBLOCK_INPUT_ALLOC; |
1168 | 1201 |
1169 /* fprintf (stderr, "%p malloc\n", value); */ | 1202 /* fprintf (stderr, "%p malloc\n", value); */ |
1170 return value; | 1203 return value; |
1171 } | 1204 } |
1172 | 1205 |
1178 void *ptr; | 1211 void *ptr; |
1179 size_t size; | 1212 size_t size; |
1180 { | 1213 { |
1181 void *value; | 1214 void *value; |
1182 | 1215 |
1183 BLOCK_INPUT; | 1216 BLOCK_INPUT_ALLOC; |
1184 __realloc_hook = old_realloc_hook; | 1217 __realloc_hook = old_realloc_hook; |
1185 | 1218 |
1186 #ifdef GC_MALLOC_CHECK | 1219 #ifdef GC_MALLOC_CHECK |
1187 if (ptr) | 1220 if (ptr) |
1188 { | 1221 { |
1223 | 1256 |
1224 /* fprintf (stderr, "%p <- realloc\n", value); */ | 1257 /* fprintf (stderr, "%p <- realloc\n", value); */ |
1225 #endif /* GC_MALLOC_CHECK */ | 1258 #endif /* GC_MALLOC_CHECK */ |
1226 | 1259 |
1227 __realloc_hook = emacs_blocked_realloc; | 1260 __realloc_hook = emacs_blocked_realloc; |
1228 UNBLOCK_INPUT; | 1261 UNBLOCK_INPUT_ALLOC; |
1229 | 1262 |
1230 return value; | 1263 return value; |
1231 } | 1264 } |
1265 | |
1266 | |
1267 #ifdef HAVE_GTK_AND_PTHREAD | |
1268 /* Called from Fdump_emacs so that when the dumped Emacs starts, it has a | |
1269 normal malloc. Some thread implementations need this as they call | |
1270 malloc before main. The pthread_self call in BLOCK_INPUT_ALLOC then | |
1271 calls malloc because it is the first call, and we have an endless loop. */ | |
1272 | |
1273 void | |
1274 reset_malloc_hooks () | |
1275 { | |
1276 __free_hook = 0; | |
1277 __malloc_hook = 0; | |
1278 __realloc_hook = 0; | |
1279 } | |
1280 #endif /* HAVE_GTK_AND_PTHREAD */ | |
1232 | 1281 |
1233 | 1282 |
1234 /* Called from main to set up malloc to use our hooks. */ | 1283 /* Called from main to set up malloc to use our hooks. */ |
1235 | 1284 |
1236 void | 1285 void |
1237 uninterrupt_malloc () | 1286 uninterrupt_malloc () |
1238 { | 1287 { |
1288 #ifdef HAVE_GTK_AND_PTHREAD | |
1289 pthread_mutexattr_t attr; | |
1290 | |
1291 /* GLIBC has a faster way to do this, but lets keep it portable. | |
1292 This is according to the Single UNIX Specification. */ | |
1293 pthread_mutexattr_init (&attr); | |
1294 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); | |
1295 pthread_mutex_init (&alloc_mutex, &attr); | |
1296 | |
1297 main_thread = pthread_self (); | |
1298 #endif /* HAVE_GTK_AND_PTHREAD */ | |
1299 | |
1239 if (__free_hook != emacs_blocked_free) | 1300 if (__free_hook != emacs_blocked_free) |
1240 old_free_hook = __free_hook; | 1301 old_free_hook = __free_hook; |
1241 __free_hook = emacs_blocked_free; | 1302 __free_hook = emacs_blocked_free; |
1242 | 1303 |
1243 if (__malloc_hook != emacs_blocked_malloc) | 1304 if (__malloc_hook != emacs_blocked_malloc) |