Mercurial > hg > xemacs-beta
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); |