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)