diff options
| author | Jan Djärv | 2004-12-07 08:25:43 +0000 |
|---|---|---|
| committer | Jan Djärv | 2004-12-07 08:25:43 +0000 |
| commit | aa477689e55b559de0a1c3598f6d793b0625a48f (patch) | |
| tree | 64f5e96dcc75b656bb34d672707371006dcbbaa7 /src/alloc.c | |
| parent | ded997c16032a6c658e345452d7e5ec275c0642e (diff) | |
| download | emacs-aa477689e55b559de0a1c3598f6d793b0625a48f.tar.gz emacs-aa477689e55b559de0a1c3598f6d793b0625a48f.zip | |
* 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.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 73 |
1 files changed, 67 insertions, 6 deletions
diff --git a/src/alloc.c b/src/alloc.c index e0c14e8bb9c..4f3a0d6f2c4 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -31,6 +31,10 @@ Boston, MA 02111-1307, USA. */ | |||
| 31 | 31 | ||
| 32 | #include <signal.h> | 32 | #include <signal.h> |
| 33 | 33 | ||
| 34 | #ifdef HAVE_GTK_AND_PTHREAD | ||
| 35 | #include <pthread.h> | ||
| 36 | #endif | ||
| 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. */ |
| @@ -85,6 +89,35 @@ extern __malloc_size_t __malloc_extra_blocks; | |||
| 85 | 89 | ||
| 86 | #endif /* not DOUG_LEA_MALLOC */ | 90 | #endif /* not DOUG_LEA_MALLOC */ |
| 87 | 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 */ | ||
| 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; |
| @@ -1068,7 +1101,7 @@ 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) |
| @@ -1106,7 +1139,7 @@ emacs_blocked_free (ptr) | |||
| 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 | ||
| @@ -1132,7 +1165,7 @@ emacs_blocked_malloc (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); |
| @@ -1164,7 +1197,7 @@ emacs_blocked_malloc (size) | |||
| 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; |
| @@ -1180,7 +1213,7 @@ emacs_blocked_realloc (ptr, 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 |
| @@ -1225,17 +1258,45 @@ emacs_blocked_realloc (ptr, size) | |||
| 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 | } |
| 1232 | 1265 | ||
| 1233 | 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 */ | ||
| 1281 | |||
| 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; |