comparison src/event-stream.c @ 1292:f3437b56874d

[xemacs-hg @ 2003-02-13 09:57:04 by ben] profile updates profile.c: Major reworking. Keep track of new information -- total function timing (includes descendants), GC usage, total GC usage (includes descendants). New functions to be called appropriately from eval.c, alloc.c to keep track of this information. Keep track of when we're actually in a function vs. in its profile, for more accurate timing counts. Track profile overhead separately. Create new mechanism for specifying "internal sections" that are tracked just like regular Lisp functions and even appear in the backtrace if `backtrace-with-internal-sections' is non-nil (t by default for error-checking builds). Add some KKCC information for the straight (non-Elisp) hash table used by profile, which contains Lisp objects in its keys -- but not used yet. Remove old ad-hoc methods for tracking garbage collection, redisplay (which was incorrect anyway when Lisp was called within these sections). Don't record any tick info when blocking under MS Windows, since the timer there is in real time rather than in process time. Make `start-profiling', `stop-profiling' interactive. Be consistent wrt. recursive functions and functions currently on the stack when starting or stopping -- together these make implementing the `total' values extremely difficult. When we start profiling, we act as if we just entered all the functions currently on the stack. Likewise when exiting. Create vars in_profile for tracking time spent inside of profiling, and profiling_lock for setting exclusive access to the main hash table when reading from it or modifying it. (protects against getting screwed up by the signal handle going off at the same time. profile.h: New file. Create macros for declaring internal profiling sections. lisp.h: Move profile-related stuff to profile.h. alloc.c: Keep track of total consing, for profile. Tell profile when we are consing. Use new profile-section method for noting garbage-collection. alloc.c: Abort if we attempt to call the allocator reentrantly. backtrace.h, eval.c: Add info for use by profile in the backtrace frame and transfer PUSH_BACKTRACE/POP_BACKTRACE from eval.c, for use with profile. elhash.c: Author comment. eval.c, lisp.h: New Lisp var `backtrace-with-internal-sections'. Set to t when error-checking is on. eval.c: When unwinding, eval.c: Report to profile when we are about-to-call and just-called wrt. a function. alloc.c, eval.c: Allow for "fake" backtrace frames, for internal sections (used by profile and `backtrace-with-internal-sections'. event-Xt.c, event-gtk.c, event-msw.c, event-tty.c: Record when we are actually blocking on an event, for profile's sake. event-stream.c: Record internal profiling sections for getting, dispatching events. extents.c: Record internal profiling sections for map_extents. hash.c, hash.h: Add pregrow_hash_table_if_necessary(). (Used in profile code since the signal handler is the main grower but can't allow a realloc(). We make sure, at critical points, that the table is large enough.) lread.c: Create internal profiling sections for `load' (which may be triggered internally by autoload, etc.). redisplay.c: Remove old profile_redisplay_flag. Use new macros to declare internal profiling section for redisplay. text.c: Use new macros to declare internal profiling sections for char-byte conversion and internal-external conversion. SEMI-UNRELATED CHANGES: ----------------------- text.c: Update the long comments.
author ben
date Thu, 13 Feb 2003 09:57:08 +0000
parents cd0abfdb9e9d
children 70921960b980
comparison
equal deleted inserted replaced
1291:3d99b5e6c6ec 1292:f3437b56874d
88 #include "keymap.h" 88 #include "keymap.h"
89 #include "lstream.h" 89 #include "lstream.h"
90 #include "macros.h" /* for defining_keyboard_macro */ 90 #include "macros.h" /* for defining_keyboard_macro */
91 #include "menubar.h" /* #### for evil kludges. */ 91 #include "menubar.h" /* #### for evil kludges. */
92 #include "process.h" 92 #include "process.h"
93 #include "profile.h"
93 #include "window-impl.h" 94 #include "window-impl.h"
94 95
95 #include "sysdep.h" /* init_poll_for_quit() */ 96 #include "sysdep.h" /* init_poll_for_quit() */
96 #include "syssignal.h" /* SIGCHLD, etc. */ 97 #include "syssignal.h" /* SIGCHLD, etc. */
97 #include "sysfile.h" 98 #include "sysfile.h"
246 247
247 int in_modal_loop; 248 int in_modal_loop;
248 249
249 /* the number of keyboard characters read. callint.c wants this. */ 250 /* the number of keyboard characters read. callint.c wants this. */
250 Charcount num_input_chars; 251 Charcount num_input_chars;
252
253 static Lisp_Object Qnext_event, Qdispatch_event, QSnext_event_internal;
254 static Lisp_Object QSexecute_internal_event;
251 255
252 #ifdef DEBUG_XEMACS 256 #ifdef DEBUG_XEMACS
253 Fixnum debug_emacs_events; 257 Fixnum debug_emacs_events;
254 258
255 static void 259 static void
2101 2105
2102 static void 2106 static void
2103 next_event_internal (Lisp_Object target_event, int allow_queued) 2107 next_event_internal (Lisp_Object target_event, int allow_queued)
2104 { 2108 {
2105 struct gcpro gcpro1; 2109 struct gcpro gcpro1;
2110 PROFILE_DECLARE ();
2111
2106 QUIT; 2112 QUIT;
2113
2114 PROFILE_RECORD_ENTERING_SECTION (QSnext_event_internal);
2107 2115
2108 assert (NILP (XEVENT_NEXT (target_event))); 2116 assert (NILP (XEVENT_NEXT (target_event)));
2109 2117
2110 GCPRO1 (target_event); 2118 GCPRO1 (target_event);
2111 2119
2156 QUIT; 2164 QUIT;
2157 } 2165 }
2158 } 2166 }
2159 2167
2160 UNGCPRO; 2168 UNGCPRO;
2169
2170 PROFILE_RECORD_EXITING_SECTION (QSnext_event_internal);
2161 } 2171 }
2162 2172
2163 void 2173 void
2164 run_pre_idle_hook (void) 2174 run_pre_idle_hook (void)
2165 { 2175 {
2226 struct command_builder *command_builder = 2236 struct command_builder *command_builder =
2227 XCOMMAND_BUILDER (con->command_builder); 2237 XCOMMAND_BUILDER (con->command_builder);
2228 int store_this_key = 0; 2238 int store_this_key = 0;
2229 struct gcpro gcpro1; 2239 struct gcpro gcpro1;
2230 int depth; 2240 int depth;
2241 PROFILE_DECLARE ();
2231 2242
2232 GCPRO1 (event); 2243 GCPRO1 (event);
2233 2244
2234 /* This is not strictly necessary. Trying to retrieve an event inside of 2245 /* This is not strictly necessary. Trying to retrieve an event inside of
2235 a modal loop can cause major problems (see event_stream_quit_p()), but 2246 a modal loop can cause major problems (see event_stream_quit_p()), but
2249 because event-msw.c specifically calls Fnext_event() inside of a modal 2260 because event-msw.c specifically calls Fnext_event() inside of a modal
2250 loop to clear the dispatch queue. --ben */ 2261 loop to clear the dispatch queue. --ben */
2251 if (in_menu_callback) 2262 if (in_menu_callback)
2252 invalid_operation ("Attempt to call next-event inside menu callback", 2263 invalid_operation ("Attempt to call next-event inside menu callback",
2253 Qunbound); 2264 Qunbound);
2265
2266 PROFILE_RECORD_ENTERING_SECTION (Qnext_event);
2254 2267
2255 depth = begin_dont_check_for_quit (); 2268 depth = begin_dont_check_for_quit ();
2256 2269
2257 if (NILP (event)) 2270 if (NILP (event))
2258 event = Fmake_event (Qnil, Qnil); 2271 event = Fmake_event (Qnil, Qnil);
2475 2488
2476 RETURN: 2489 RETURN:
2477 Vquit_flag = Qnil; /* see begin_dont_check_for_quit() */ 2490 Vquit_flag = Qnil; /* see begin_dont_check_for_quit() */
2478 unbind_to (depth); 2491 unbind_to (depth);
2479 2492
2493 PROFILE_RECORD_EXITING_SECTION (Qnext_event);
2494
2480 UNGCPRO; 2495 UNGCPRO;
2481 2496
2482 return event; 2497 return event;
2483 } 2498 }
2484 2499
3020 /**********************************************************************/ 3035 /**********************************************************************/
3021 3036
3022 static void 3037 static void
3023 execute_internal_event (Lisp_Object event) 3038 execute_internal_event (Lisp_Object event)
3024 { 3039 {
3040 PROFILE_DECLARE ();
3041
3025 /* events on dead channels get silently eaten */ 3042 /* events on dead channels get silently eaten */
3026 if (object_dead_p (XEVENT (event)->channel)) 3043 if (object_dead_p (XEVENT (event)->channel))
3027 return; 3044 return;
3028 3045
3046 PROFILE_RECORD_ENTERING_SECTION (QSexecute_internal_event);
3047
3029 /* This function can GC */ 3048 /* This function can GC */
3030 switch (XEVENT_TYPE (event)) 3049 switch (XEVENT_TYPE (event))
3031 { 3050 {
3032 case empty_event: 3051 case empty_event:
3033 return; 3052 goto done;
3034 3053
3035 case eval_event: 3054 case eval_event:
3036 { 3055 {
3037 call1 (XEVENT_EVAL_FUNCTION (event), 3056 call1 (XEVENT_EVAL_FUNCTION (event),
3038 XEVENT_EVAL_OBJECT (event)); 3057 XEVENT_EVAL_OBJECT (event));
3039 return; 3058 goto done;
3040 } 3059 }
3041 3060
3042 case magic_eval_event: 3061 case magic_eval_event:
3043 { 3062 {
3044 XEVENT_MAGIC_EVAL_INTERNAL_FUNCTION (event) 3063 XEVENT_MAGIC_EVAL_INTERNAL_FUNCTION (event)
3045 XEVENT_MAGIC_EVAL_OBJECT (event); 3064 XEVENT_MAGIC_EVAL_OBJECT (event);
3046 return; 3065 goto done;
3047 } 3066 }
3048 3067
3049 case pointer_motion_event: 3068 case pointer_motion_event:
3050 { 3069 {
3051 if (!NILP (Vmouse_motion_handler)) 3070 if (!NILP (Vmouse_motion_handler))
3052 call1 (Vmouse_motion_handler, event); 3071 call1 (Vmouse_motion_handler, event);
3053 return; 3072 goto done;
3054 } 3073 }
3055 3074
3056 case process_event: 3075 case process_event:
3057 { 3076 {
3058 Lisp_Object p = XEVENT_PROCESS_PROCESS (event); 3077 Lisp_Object p = XEVENT_PROCESS_PROCESS (event);
3140 It's safe for the filter to signal an error because 3159 It's safe for the filter to signal an error because
3141 status_notify() will be called on return to top-level. 3160 status_notify() will be called on return to top-level.
3142 */ 3161 */
3143 status_notify (); 3162 status_notify ();
3144 } 3163 }
3145 return; 3164 goto done;
3146 } 3165 }
3147 3166
3148 case timeout_event: 3167 case timeout_event:
3149 { 3168 {
3150 Lisp_Event *e = XEVENT (event); 3169 Lisp_Event *e = XEVENT (event);
3151 3170
3152 if (!NILP (EVENT_TIMEOUT_FUNCTION (e))) 3171 if (!NILP (EVENT_TIMEOUT_FUNCTION (e)))
3153 call1 (EVENT_TIMEOUT_FUNCTION (e), 3172 call1 (EVENT_TIMEOUT_FUNCTION (e),
3154 EVENT_TIMEOUT_OBJECT (e)); 3173 EVENT_TIMEOUT_OBJECT (e));
3155 return; 3174 goto done;
3156 } 3175 }
3157 case magic_event: 3176 case magic_event:
3158 event_stream_handle_magic_event (XEVENT (event)); 3177 event_stream_handle_magic_event (XEVENT (event));
3159 return; 3178 goto done;
3160 default: 3179 default:
3161 abort (); 3180 abort ();
3162 } 3181 }
3182
3183 done:
3184 PROFILE_RECORD_EXITING_SECTION (QSexecute_internal_event);
3163 } 3185 }
3164 3186
3165 3187
3166 3188
3167 static void 3189 static void
4339 /* This function can GC */ 4361 /* This function can GC */
4340 struct command_builder *command_builder; 4362 struct command_builder *command_builder;
4341 Lisp_Event *ev; 4363 Lisp_Event *ev;
4342 Lisp_Object console; 4364 Lisp_Object console;
4343 Lisp_Object channel; 4365 Lisp_Object channel;
4366 PROFILE_DECLARE ();
4344 4367
4345 CHECK_LIVE_EVENT (event); 4368 CHECK_LIVE_EVENT (event);
4346 ev = XEVENT (event); 4369 ev = XEVENT (event);
4347 4370
4348 /* events on dead channels get silently eaten */ 4371 /* events on dead channels get silently eaten */
4349 channel = EVENT_CHANNEL (ev); 4372 channel = EVENT_CHANNEL (ev);
4350 if (object_dead_p (channel)) 4373 if (object_dead_p (channel))
4351 return Qnil; 4374 return Qnil;
4375
4376 PROFILE_RECORD_ENTERING_SECTION (Qdispatch_event);
4352 4377
4353 /* Some events don't have channels (e.g. eval events). */ 4378 /* Some events don't have channels (e.g. eval events). */
4354 console = CDFW_CONSOLE (channel); 4379 console = CDFW_CONSOLE (channel);
4355 if (NILP (console)) 4380 if (NILP (console))
4356 console = Vselected_console; 4381 console = Vselected_console;
4546 } 4571 }
4547 default: 4572 default:
4548 execute_internal_event (event); 4573 execute_internal_event (event);
4549 break; 4574 break;
4550 } 4575 }
4576
4577 PROFILE_RECORD_EXITING_SECTION (Qdispatch_event);
4551 return Qnil; 4578 return Qnil;
4552 } 4579 }
4553 4580
4554 DEFUN ("read-key-sequence", Fread_key_sequence, 1, 3, 0, /* 4581 DEFUN ("read-key-sequence", Fread_key_sequence, 1, 3, 0, /*
4555 Read a sequence of keystrokes or mouse clicks. 4582 Read a sequence of keystrokes or mouse clicks.
4816 DEFSYMBOL (Qretry_undefined_key_binding_unshifted); 4843 DEFSYMBOL (Qretry_undefined_key_binding_unshifted);
4817 DEFSYMBOL (Qauto_show_make_point_visible); 4844 DEFSYMBOL (Qauto_show_make_point_visible);
4818 4845
4819 DEFSYMBOL (Qself_insert_defer_undo); 4846 DEFSYMBOL (Qself_insert_defer_undo);
4820 DEFSYMBOL (Qcancel_mode_internal); 4847 DEFSYMBOL (Qcancel_mode_internal);
4848
4849 DEFSYMBOL (Qnext_event);
4850 DEFSYMBOL (Qdispatch_event);
4821 } 4851 }
4822 4852
4823 void 4853 void
4824 reinit_vars_of_event_stream (void) 4854 reinit_vars_of_event_stream (void)
4825 { 4855 {
4871 pending_async_timeout_list = Qnil; 4901 pending_async_timeout_list = Qnil;
4872 staticpro (&pending_async_timeout_list); 4902 staticpro (&pending_async_timeout_list);
4873 4903
4874 last_point_position_buffer = Qnil; 4904 last_point_position_buffer = Qnil;
4875 staticpro (&last_point_position_buffer); 4905 staticpro (&last_point_position_buffer);
4906
4907 QSnext_event_internal = build_string ("next_event_internal()");
4908 staticpro (&QSnext_event_internal);
4909 QSexecute_internal_event = build_string ("execute_internal_event()");
4910 staticpro (&QSexecute_internal_event);
4876 4911
4877 DEFVAR_LISP ("echo-keystrokes", &Vecho_keystrokes /* 4912 DEFVAR_LISP ("echo-keystrokes", &Vecho_keystrokes /*
4878 *Nonzero means echo unfinished commands after this many seconds of pause. 4913 *Nonzero means echo unfinished commands after this many seconds of pause.
4879 */ ); 4914 */ );
4880 Vecho_keystrokes = make_int (1); 4915 Vecho_keystrokes = make_int (1);