/* showsw.macro.allegro 96/06/18 /* Copyright (c) 1991 Allegro Consultants, Inc. /* Author: Stan Sieler mac str22 (sss : str) {if strlen (sss) >= #22 then return sss; return str (sss + strrpt (' ', #22), 1, #22))} mac str32 (sss : str) {if strlen (sss) >= #32 then return sss; return str (sss + strrpt (' ', #32), 1, #32))} mac cm_lev_to_user { /* returns a level number to go "back" to */ /* typically returns 1 or more */ loc ktr 0; /* used to prevent going back too far */ cm; ignore quiet; { while typeof (cmpc) = 'SYS' do { loc ktr ktr + 1; if ktr > 10 then return 1; /* give up */ lev ktr; }; return ktr; }; return 1; /* if an error occurred above */ } mac nm_lev_to_user { /* returns a level number to go "back" to. */ /* typically returns 1 or more */ loc ktr 0; /* used to prevent going back too far */ /* nm; not needed */ ignore quiet; { while str (nmproc (sr4.rp), 1, 1) <> '?' do { loc ktr ktr + 1; if ktr > 10 then return 1; /* give up */ lev ktr; }; return ktr; }; return 1; /* if an error occurred above */ } mac show_cm_user { env term_loud false; /* suppress error msgs from LEV cmd */ env error 0; loc ans ''; ignore quiet; { loc user_lev cm_lev_to_user; var cm_to_nm cm_to_nm + 1; lev user_lev; if lptr (cmpc) = 0.$ffffffff then loc ans str22 ('switch marker') + ': ' else loc ans str22 (cmproc (cmpc)) + ': '; if user_lev > 0 then { lev user_lev - 1; loc ans ans + str22 (cmproc (cmpc)); if user_lev > 2 then { lev 1; loc ans ans + '(' + asc (user_lev, "D") + ')... ' + cmproc (cmpc); }; }; env term_loud true; wl "C>n ", ans; }; } mac show_nm_user { env term_loud false; /* suppress error msgs from LEV cmd */ env error 0; loc ans ''; ignore quiet; { loc user_lev nm_lev_to_user; var nm_to_cm nm_to_cm + 1; lev user_lev; if user_lev > 0 then { loc ans str32 (nmproc (sr4.rp)) + ': '; if user_lev > 1 then { lev 1; loc ans ans + str32 (nmproc (pc)); }; } else loc ans str32 (nmproc (pc)); env term_loud true; wl " n>C ", ans; }; } macro show_sw (want_cn : bool = true, want_nc : bool = true) { nm; if bound ("cm_to_nm") = "UNDEFINED" then { var cm_to_nm 0; var nm_to_cm 0; }; if want_cn then { env error 0; ignore quiet; { b nmaddr ("SWT"),,quiet,{show_cm_user; c}; /* the above breakpoint seems to trap ALL switches to NM, /* and is cheaper than doing the following: /* cm /* b ?switch'to'nm' ,,quiet,{show_cm_user; c} /* b ?sw'to'nm'name ,,quiet,{show_cm_user; c} /* b ?HPSWTONMPLABEL,,quiet,{show_cm_user; c} /* b ?HPSWTONMNAME ,,quiet,{show_cm_user; c} }; if error = 0 then wl "Installed CM -> NM switch watcher." else { wl "Failed to install CM -> NM watcher:"; = errmsg (error); }; }; if want_cn then { env error 0; ignore quiet; { /* following breakpoint seems to trap ALL switches to CM. b switch_to_cm, , quiet, {show_nm_user; c}; }; if error = 0 then wl "Installed NM -> CM switch watcher." else { wl "Failed to install NM -> CM watcher:"; = errmsg (error); }; }; ignore quiet; b terminate_process, , , {show_counters; c}; } macro count_sw { nm; if bound ("cm_to_nm") = "UNDEFINED" then { var cm_to_nm 0; var nm_to_cm 0; }; env error 0; ignore quiet; { b nmaddr ("SWT"),,quiet, {var cm_to_nm cm_to_nm + 1; c}; b switch_to_cm, , quiet, {var nm_to_cm nm_to_cm + 1; c}; b terminate_process, , , {show_counters; c}; }; if error = 0 then wl "Installed switch counters." else { wl "Failed to install switch counters:"; = errmsg (error); }; wl "To see value of counters, enter: show_counters"; } macro clear_sw { bd @; wl "Removed all breakpoints for process."; } macro show_counters { wl "# Switches from CM to NM: ", cm_to_nm:"#W8"; wl "# Switches from NM to CM: ", nm_to_cm:"#W8"; } macro zero_counters { var cm_to_nm 0; var nm_to_cm 0; }; zero_counters; wl; wl "Macros of interest:"; wl " show_sw ... arms CM -> NM and/or NM -> CM watchers & counters"; wl " count_sw ... arms CM -> NM and/or NM -> CM counters"; wl " show_counters... reports # of switches in each direction."; wl " zero_counters... sets the two counter values to 0."; wl " clear_sw ... removes *all* breakpoints for process"; wl " "; wl "Typical usage:"; wl " :run editor.pub.sys;debug"; wl " use showsw.macro.allegro"; wl " show_sw"; wl " c"; wl " ...interact with editor, watching breakpoints..."; wl " ...about 84 switches will occur before first editor prompt."; wl " Note: these macros install breakpoints that dramatically"; wl " slow down your program!"; wl " Note: both show_sw and count_sw should report a summary when"; wl " your process terminates."; wl;