From 0805802bb88a2f3ce763034ff165caa81f3c0c69 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Mon, 28 Aug 2023 10:39:11 +0200 Subject: [PATCH] fix performance issues (too many proc infowindow calls) on large schematics introduced by previous two commits --- src/netlist.c | 7 ------- src/node_hash.c | 1 - src/scheduler.c | 33 ++++++++++++++++++++++++--------- src/select.c | 36 +++++++++++++++++++++--------------- src/xinit.c | 2 ++ src/xschem.h | 1 + src/xschem.tcl | 13 +++++++------ 7 files changed, 55 insertions(+), 38 deletions(-) diff --git a/src/netlist.c b/src/netlist.c index 1e596413..3d4d0025 100644 --- a/src/netlist.c +++ b/src/netlist.c @@ -279,7 +279,6 @@ static int hash_inst_pin(int what, int i, int j) xctx->inst[i].name, j, prop_ptr); statusmsg(str,2); err |= 1; - tclvareval("show_infotext ", my_itoa(err), NULL); /* critical error: force ERC window showing */ if(!xctx->netlist_count) { xctx->inst[i].color = -PINLAYER; xctx->hilight_nets=1; @@ -655,7 +654,6 @@ static int signal_short( const char *tag, const char *n1, const char *n2) my_snprintf(str, S(str), "Error: %s shorted: %s - %s", tag, n1, n2); dbg(1, "signal_short(): signal_short: shorted: %s - %s", n1, n2); statusmsg(str,2); - tclvareval("show_infotext ", my_itoa(err), NULL); /* critical error: force ERC window showing */ if(!xctx->netlist_count) { bus_hilight_hash_lookup(n1, xctx->hilight_color, XINSERT); if(tclgetboolvar("incr_hilight")) incr_hilight_color(); @@ -1359,7 +1357,6 @@ int warning_overlapped_symbols(int sel) xctx->inst[i].instname, xctx->inst[i].name, xctx->inst[found->value].instname); statusmsg(str,2); err |= 1; - tclvareval("show_infotext ", my_itoa(err), NULL); /* critical error: force ERC window showing */ } } int_hash_free(&table); @@ -1528,7 +1525,6 @@ int sym_vs_sch_pins() my_snprintf(str, S(str), " %s <--> %s", type, pin_dir); statusmsg(str,2); err |= 1; - tclvareval("show_infotext ", my_itoa(err), NULL); /* critical error: force ERC window showing */ for(j = 0; j < xctx->instances; ++j) { if(!xctx->x_strcmp(get_sym_name(j, 9999, 1), xctx->sym[i].name)) { xctx->inst[j].color = -PINLAYER; @@ -1547,7 +1543,6 @@ int sym_vs_sch_pins() xctx->sym[i].name, lab); statusmsg(str,2); err |= 1; - tclvareval("show_infotext ", my_itoa(err), NULL); /* critical error: force ERC window showing */ for(j = 0; j < xctx->instances; ++j) { dbg(1, "inst.name=%s, sym.name=%s\n", tcl_hook2(xctx->inst[j].name), xctx->sym[i].name); if(!xctx->x_strcmp(get_sym_name(j, 9999, 1), xctx->sym[i].name)) { @@ -1583,7 +1578,6 @@ int sym_vs_sch_pins() xctx->sym[i].name, rects, pin_cnt); statusmsg(str,2); err |= 1; - tclvareval("show_infotext ", my_itoa(err), NULL); /* critical error: force ERC window showing */ for(j = 0; j < xctx->instances; ++j) { if(!xctx->x_strcmp(get_sym_name(j, 9999, 1), xctx->sym[i].name)) { xctx->inst[j].color = -PINLAYER; @@ -1608,7 +1602,6 @@ int sym_vs_sch_pins() xctx->sym[i].name, pin_name ? pin_name : ""); statusmsg(str,2); err |= 1; - tclvareval("show_infotext ", my_itoa(err), NULL); /* critical error: force ERC window showing */ for(k = 0; k < xctx->instances; ++k) { if(!xctx->x_strcmp(get_sym_name(k, 9999, 1), xctx->sym[i].name)) { xctx->inst[k].color = -PINLAYER; diff --git a/src/node_hash.c b/src/node_hash.c index 54814714..0c1b7429 100644 --- a/src/node_hash.c +++ b/src/node_hash.c @@ -214,7 +214,6 @@ int traverse_node_hash() if(incr_hi) incr_hilight_color(); statusmsg(str, 2); err |= 1; - tclvareval("show_infotext ", my_itoa(err), NULL); /* critical error: force ERC window showing */ } else if(entry->d.out + entry->d.inout + entry->d.in == 1) { diff --git a/src/scheduler.c b/src/scheduler.c index 0604e2f7..44083dd6 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -22,22 +22,28 @@ #include "xschem.h" +/* n=1: messages in status bar + * n=2: append str in ERC window messages + * n=3: set ERC messages to str */ void statusmsg(char str[],int n) { if(!str) return; if(str[0]== '\0') { - tclsetvar("infowindow_text", ""); + my_free(_ALLOC_ID_, &xctx->infowindow_text); } else { - if(n == 2) { - tcleval("if {$infowindow_text ne {}} {append infowindow_text \\n}"); - tclvareval("append infowindow_text {", str, "}", NULL); + if(n == 3) { + my_strdup(_ALLOC_ID_, &xctx->infowindow_text, str); + } else if(n == 2) { + if(xctx->infowindow_text && xctx->infowindow_text[0]) { + my_strcat(_ALLOC_ID_, &xctx->infowindow_text, "\n"); + } + my_strcat(_ALLOC_ID_, &xctx->infowindow_text, str); } } if(!has_x) return; - if(n==2) { + if(n == 2 || n == 3) { dbg(3, "statusmsg(): n = 2, str = %s\n", str); - tcleval("infowindow"); } else { tclvareval(xctx->top_path, ".statusbar.1 configure -text {", str, "}", NULL); @@ -942,7 +948,13 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg } break; case 'i': - if(!strcmp(argv[2], "instances")) { /* number of instances in schematic */ + if(!strcmp(argv[2], "infowindow_text")) { /* ERC messages */ + if(xctx && xctx->infowindow_text) + Tcl_SetResult(interp, xctx->infowindow_text, TCL_VOLATILE); + else + Tcl_SetResult(interp, "", TCL_STATIC); + } + else if(!strcmp(argv[2], "instances")) { /* number of instances in schematic */ Tcl_SetResult(interp, my_itoa(xctx->instances), TCL_VOLATILE); } break; @@ -2298,7 +2310,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg yyparse_error = 0; my_strdup(_ALLOC_ID_, &saveshow, tclgetvar("show_infowindow_after_netlist")); my_strncpy(save, tclgetvar("netlist_dir"), S(save)); - if(argc > 2 && strcmp(argv[2], "-erc")) { /* xschem netlist NOT invoked from GUI */ + if(argc <= 2 || (argc > 2 && strcmp(argv[2], "-erc"))) { /* xschem netlist NOT invoked from GUI */ tclsetvar("show_infowindow_after_netlist", "never"); } if(argc > 2) { @@ -2334,7 +2346,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg set_netlist_dir(1, save); } if(messages) { - Tcl_SetResult(interp, (char *)tclgetvar("infowindow_text"), TCL_VOLATILE); + Tcl_SetResult(interp, xctx->infowindow_text, TCL_VOLATILE); } else { Tcl_SetResult(interp, my_itoa(err), TCL_VOLATILE); } @@ -3398,6 +3410,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg else if(!strcmp(argv[2], "hide_symbols")) { /* set to 0,1,2 for various hiding level of symbols */ xctx->hide_symbols=atoi(argv[3]); } + else if(!strcmp(argv[2], "infowindow_text")) { /* ERC messages */ + my_strdup(_ALLOC_ID_, &xctx->infowindow_text, argv[3]); + } } else { /* argv[2][0] >= 'n' */ if(!strcmp(argv[2], "netlist_name")) { /* set custom netlist name */ my_strncpy(xctx->netlist_name, argv[3], S(xctx->netlist_name)); diff --git a/src/select.c b/src/select.c index 91765b1c..c1c0c0e1 100644 --- a/src/select.c +++ b/src/select.c @@ -734,7 +734,6 @@ void unselect_all(int dr) drawtempline(xctx->gctiled,END, 0.0, 0.0, 0.0, 0.0); } xctx->ui_state &= ~SELECTION; - /*\statusmsg("",2); */ my_snprintf(str, S(str), "%s/%s", user_conf_dir, ".selection.sch"); /* 20161115 PWD->HOME */ xunlink(str); dbg(2, "unselect_all(1): done\n"); @@ -749,13 +748,14 @@ void select_wire(int i,unsigned short select_mode, int fast) my_snprintf(str, S(str), "Info: selected wire: n=%d end1=%d end2=%d\nnode=%s",i, xctx->wire[i].end1, xctx->wire[i].end2, xctx->wire[i].prop_ptr? xctx->wire[i].prop_ptr: "(null)"); - statusmsg(str,2); + statusmsg(str,3); + tcleval("infowindow"); - my_snprintf(str, S(str), "n=%4d x = %.16g y = %.16g w = %.16g h = %.16g", + my_snprintf(str, S(str), "n=%4d x = %.16g y = %.16g w = %.16g h = %.16g", i, xctx->wire[i].x1, xctx->wire[i].y1, xctx->wire[i].x2-xctx->wire[i].x1, xctx->wire[i].y2-xctx->wire[i].y1 - ); - statusmsg(str,1); + ); + statusmsg(str,1); } if( ((xctx->wire[i].sel|select_mode) == (SELECTED1|SELECTED2)) || ((xctx->wire[i].sel == SELECTED) && select_mode) ) @@ -789,15 +789,15 @@ void select_element(int i,unsigned short select_mode, int fast, int override_loc my_strncpy(s,xctx->inst[i].prop_ptr!=NULL?xctx->inst[i].prop_ptr:"",S(s)); if( !fast ) { - my_snprintf(str, S(str), "Info: selected element %d: %s properties: %s", i, xctx->inst[i].name,s); - statusmsg(str,2); - my_snprintf(str, S(str), "symbol name=%s", xctx->inst[i].name==NULL?"(null)":xctx->inst[i].name); - statusmsg(str,2); + my_snprintf(str, S(str), "Info: selected element %d: %s\nproperties:\n%s", i, + xctx->inst[i].name ? xctx->inst[i].name : "" , s); + statusmsg(str,3); /* 20190526 */ /*Why this? 20191125 only on small schematics. slow down on big schematics */ if(xctx->instances < 150) { prepare_netlist_structs(0); if(xctx->inst[i].ptr != -1) for(j=0;j< (xctx->inst[i].ptr+ xctx->sym)->rects[PINLAYER] ; ++j) { + if(j == 0) statusmsg("pinlist:", 2); if(xctx->inst[i].node && (xctx->inst[i].ptr+ xctx->sym)->rect[PINLAYER][j].prop_ptr) { my_snprintf(str, S(str), "pin:%s -> %s", @@ -808,6 +808,7 @@ void select_element(int i,unsigned short select_mode, int fast, int override_loc } } } + tcleval("infowindow"); my_snprintf(str, S(str), "n=%4d x = %.16g y = %.16g w = %.16g h = %.16g",i, xctx->inst[i].xx1, xctx->inst[i].yy1, xctx->inst[i].xx2-xctx->inst[i].xx1, xctx->inst[i].yy2-xctx->inst[i].yy1 @@ -837,7 +838,8 @@ void select_text(int i,unsigned short select_mode, int fast) if(!fast) { my_strncpy(s,xctx->text[i].prop_ptr!=NULL?xctx->text[i].prop_ptr:"",S(s)); my_snprintf(str, S(str), "Info: selected text %d: properties: %s", i,s); - statusmsg(str,2); + statusmsg(str,3); + tcleval("infowindow"); my_snprintf(str, S(str), "n=%4d x = %.16g y = %.16g", i, xctx->text[i].x0, xctx->text[i].y0); statusmsg(str,1); } @@ -875,7 +877,8 @@ void select_box(int c, int i, unsigned short select_mode, int fast, int override { my_strncpy(s,xctx->rect[c][i].prop_ptr!=NULL?xctx->rect[c][i].prop_ptr:"",S(s)); my_snprintf(str, S(str), "Info: selected box : layer=%d, n=%d properties: %s",c-4,i,s); - statusmsg(str,2); + statusmsg(str,3); + tcleval("infowindow"); my_snprintf(str, S(str), "n=%4d x = %.16g y = %.16g w = %.16g h = %.16g", i, xctx->rect[c][i].x1, xctx->rect[c][i].y1, @@ -914,8 +917,9 @@ void select_arc(int c, int i, unsigned short select_mode, int fast) { my_strncpy(s,xctx->rect[c][i].prop_ptr!=NULL?xctx->rect[c][i].prop_ptr:"",S(s)); my_snprintf(str, S(str), "Info: selected arc : layer=%d, n=%d properties: %s",c-4,i,s); - statusmsg(str,2); - + statusmsg(str,3); + tcleval("infowindow"); + my_snprintf(str, S(str), "n=%4d x = %.16g y = %.16g r = %.16g a = %.16g b = %.16g", i, xctx->arc[c][i].x, xctx->arc[c][i].y, xctx->arc[c][i].r, xctx->arc[c][i].a, xctx->arc[c][i].b); statusmsg(str,1); @@ -943,7 +947,8 @@ void select_polygon(int c, int i, unsigned short select_mode, int fast ) { my_strncpy(s,xctx->poly[c][i].prop_ptr!=NULL?xctx->poly[c][i].prop_ptr:"",S(s)); my_snprintf(str, S(str), "Info: selected polygon: layer=%d, n=%d properties: %s",c-4,i,s); - statusmsg(str,2); + statusmsg(str,3); + tcleval("infowindow"); my_snprintf(str, S(str), "n=%4d x0 = %.16g y0 = %.16g ...", i, xctx->poly[c][i].x[0], xctx->poly[c][i].y[0]); statusmsg(str,1); @@ -965,7 +970,8 @@ void select_line(int c, int i, unsigned short select_mode, int fast ) { my_strncpy(s,xctx->line[c][i].prop_ptr!=NULL?xctx->line[c][i].prop_ptr:"",S(s)); my_snprintf(str, S(str), "Info: selected line: layer=%d, n=%d properties: %s",c-4,i,s); - statusmsg(str,2); + statusmsg(str,3); + tcleval("infowindow"); my_snprintf(str, S(str), "n=%4d x = %.16g y = %.16g w = %.16g h = %.16g", i, xctx->line[c][i].x1, xctx->line[c][i].y1, diff --git a/src/xinit.c b/src/xinit.c index 4c81540d..e913180b 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -420,6 +420,7 @@ static void alloc_xschem_data(const char *top_path, const char *win_path) xctx->head_undo_ptr = 0; xctx->tail_undo_ptr = 0; xctx->undo_dirname = NULL; + xctx->infowindow_text = NULL; if(!strcmp(tclgetvar("undo_type"), "disk")) { xctx->undo_type = 0; @@ -854,6 +855,7 @@ static void xwin_exit(void) } tcleval("catch { ngspice::resetdata }"); /* remove ngspice annotation data if any */ /* "1" parameter means to force exit even if there are modified tabs/windows */ + if(xctx->infowindow_text) my_free(_ALLOC_ID_, &xctx->infowindow_text); if(has_x) new_schematic("destroy_all", "1", NULL); delete_schematic_data(1); if(has_x) { diff --git a/src/xschem.h b/src/xschem.h index 6d4a5ecf..c2fac514 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -909,6 +909,7 @@ typedef struct { int n_active_layers; int *active_layer; char *undo_dirname; + char *infowindow_text; /* ERC messages */ int cur_undo_ptr; int tail_undo_ptr; int head_undo_ptr; diff --git a/src/xschem.tcl b/src/xschem.tcl index 4a08b02b..7a61cb46 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -4413,19 +4413,20 @@ proc show_infotext {{err 0}} { if {$s == 0} { set s onerror} if {($s eq {always}) || ($err != 0 && $s eq {onerror})} { if {[info exists has_x]} { + infowindow wm deiconify .infotext } else { - puts stderr $infowindow_text + puts stderr [xschem get infowindow_text] } } } proc infowindow {} { - global infowindow_text - - set infotxt $infowindow_text + global infowindow_text has_x + set infowindow_text [xschem get infowindow_text] + if {![info exists has_x]} { return } set z {.infotext} - if ![string compare $infotxt ""] { + if ![string compare $infowindow_text ""] { if [winfo exists $z] { $z.f1.text delete 1.0 end } @@ -4456,7 +4457,7 @@ proc infowindow {} { bind $z "wm withdraw $z; set show_infowindow 0" } $z.f1.text delete 1.0 end - $z.f1.text insert 1.0 $infotxt + $z.f1.text insert 1.0 $infowindow_text set lines [$z.f1.text count -displaylines 1.0 end] $z.f1.text see ${lines}.0 return {}