Changeset 2079


Ignore:
Timestamp:
Feb 2, 2011, 4:01:51 PM (9 years ago)
Author:
mmc
Message:

Misc fixes that have been pending in my local directory for a while.
Added "usage mark" and "usage measure" options to the usage command,
for better handling of simulation times.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/README

    r217 r2079  
    2727----------------------------------------------------------------------
    2828
    29  Developed by Michael McLennan, Derrick Kearney, and Carol Song.
     29 Developed by Michael McLennan, George Howlett, and Derrick Kearney.
     30 Special thanks to Ben Rafferty for Java bindings and the Rappture
     31 tester, and Ben Haley for Ruby bindings.
    3032
  • trunk/gui/scripts/tool.tcl

    r2078 r2079  
    351351itcl::body Rappture::Tool::_output {data} {
    352352    if {[string length $_outputcb] > 0} {
    353         uplevel #0 [list $_outputcb $data]
    354     }
    355 }
     353        uplevel #0 $_outputcb [list $data]
     354    }
     355}
  • trunk/lang/tcl/scripts/library.tcl

    r1142 r2079  
    200200    public method copy {path from args}
    201201    public method remove {{path ""}}
    202     public method xml {}
     202    public method xml {{path ""}}
    203203
    204204    public method diff {libobj}
     
    648648
    649649# ----------------------------------------------------------------------
    650 # USAGE: xml
     650# USAGE: xml ?<path>?
    651651#
    652652# Returns a string representing the XML information for the information
    653653# in this library.
    654654# ----------------------------------------------------------------------
    655 itcl::body Rappture::LibraryObj::xml {} {
    656     return [$_node asXML]
     655itcl::body Rappture::LibraryObj::xml {{path ""}} {
     656    if {"" != $path} {
     657        set n [find $path]
     658    } else {
     659        set n $_node
     660    }
     661    return [$n asXML]
    657662}
    658663
  • trunk/lang/tcl/src/RpRusage.c

    r1018 r2079  
    3535
    3636static RpRusageStats RpRusage_Start;      /* time at start of program */
    37 static RpRusageStats RpRusage_MarkStats;  /* stats from last "mark" */
    38 
    3937
    4038static Tcl_ObjCmdProc RpRusageCmd;
     39static Tcl_ObjCmdProc RpRusageForgetOp;
    4140static Tcl_ObjCmdProc RpRusageMarkOp;
    4241static Tcl_ObjCmdProc RpRusageMeasureOp;
     
    4645static double RpRusageTimeDiff _ANSI_ARGS_((struct timeval *currptr,
    4746    struct timeval *prevptr));
     47static void RpDestroyMarkNames _ANSI_ARGS_((ClientData cdata,
     48    Tcl_Interp *interp));
    4849
    4950/*
     
    5152 */
    5253static Rp_OpSpec rusageOps[] = {
    53     {"mark",    2, RpRusageMarkOp, 2, 2, "",},
    54     {"measure", 2, RpRusageMeasureOp, 2, 2, "",},
     54    {"forget", 1, RpRusageForgetOp, 2, 0, "?name...?",},
     55    {"mark",    2, RpRusageMarkOp, 2, 3, "?name?",},
     56    {"measure", 2, RpRusageMeasureOp, 2, 3, "?name?",},
    5557};
    5658static int nRusageOps = sizeof(rusageOps) / sizeof(Rp_OpSpec);
     
    6870    Tcl_Interp *interp;  /* interpreter being initialized */
    6971{
     72    Tcl_HashTable *markNamesPtr;
     73
    7074    Tcl_CreateObjCommand(interp, "::Rappture::rusage", RpRusageCmd,
    7175        NULL, NULL);
    7276
    73     /* set an initial mark automatically */
     77    /* set up a hash table for different mark names */
     78    markNamesPtr = (Tcl_HashTable*)ckalloc(sizeof(Tcl_HashTable));
     79    Tcl_InitHashTable(markNamesPtr, TCL_STRING_KEYS);
     80
     81    Tcl_SetAssocData(interp, "RpRusageMarks",
     82        RpDestroyMarkNames, (ClientData)markNamesPtr);
     83
     84    /* capture the starting time for this program */
     85    if (RpRusageCapture(interp, &RpRusage_Start) != TCL_OK) {
     86        return TCL_ERROR;
     87    }
     88
     89    /* set an initial "global" mark automatically */
    7490    if (RpRusageMarkOp(NULL, interp, 0, (Tcl_Obj**)NULL) != TCL_OK) {
    7591        return TCL_ERROR;
    7692    }
    77 
    78     /* capture the starting time for this program */
    79     memcpy(&RpRusage_Start, &RpRusage_MarkStats, sizeof(RpRusageStats));
    8093
    8194    return TCL_OK;
     
    121134 *  the start of an execution.  Handles the following syntax:
    122135 *
    123  *      rusage mark
     136 *      rusage mark ?name?
    124137 *
    125138 *  Returns TCL_OK on success, and TCL_ERROR (along with an error
     
    132145    Tcl_Interp *interp;       /* interpreter handling this request */
    133146    int objc;                 /* number of command line args */
    134     Tcl_Obj *const *objv;             /* strings for command line args */
    135 {
    136     return RpRusageCapture(interp, &RpRusage_MarkStats);
     147    Tcl_Obj *const *objv;     /* strings for command line args */
     148{
     149    char *markName;
     150    Tcl_HashTable *markNamesPtr;
     151    Tcl_HashEntry *entryPtr;
     152    int newEntry;
     153    RpRusageStats *markPtr;
     154
     155    markNamesPtr = (Tcl_HashTable *)
     156        Tcl_GetAssocData(interp, "RpRusageMarks", NULL);
     157
     158    markName = (objc > 2) ? Tcl_GetString(objv[2]): "global";
     159    entryPtr = Tcl_CreateHashEntry(markNamesPtr, markName, &newEntry);
     160    if (newEntry) {
     161        markPtr = (RpRusageStats*)ckalloc(sizeof(RpRusageStats));
     162        Tcl_SetHashValue(entryPtr, (ClientData)markPtr);
     163    } else {
     164        markPtr = (RpRusageStats*)Tcl_GetHashValue(entryPtr);
     165    }
     166
     167    return RpRusageCapture(interp, markPtr);
    137168}
    138169
     
    145176 *  the following syntax:
    146177 *
    147  *      rusage measure
     178 *      rusage measure ?name?
    148179 *
    149180 *  Returns TCL_OK on success, and TCL_ERROR (along with an error
     
    158189    Tcl_Obj *const *objv;     /* strings for command line args */
    159190{
     191    char *markName;
     192    Tcl_HashTable *markNamesPtr;
     193    Tcl_HashEntry *entryPtr;
     194    RpRusageStats *markPtr;
    160195    double tval;
    161196    RpRusageStats curstats;
     
    166201    }
    167202
     203    markNamesPtr = (Tcl_HashTable *)
     204        Tcl_GetAssocData(interp, "RpRusageMarks", NULL);
     205
     206    markName = (objc > 2) ? Tcl_GetString(objv[2]): "global";
     207    entryPtr = Tcl_FindHashEntry(markNamesPtr, markName);
     208    if (entryPtr == NULL) {
     209        Tcl_AppendResult(interp, "mark \"", markName,
     210            "\" doesn't exist", NULL);
     211        return TCL_ERROR;
     212    }
     213    markPtr = (RpRusageStats*)Tcl_GetHashValue(entryPtr);
     214
    168215    /*
    169216     * Compute: START TIME
    170217     */
    171218    Tcl_AppendElement(interp, "start");
    172     tval = RpRusageTimeDiff(&RpRusage_MarkStats.times, &RpRusage_Start.times);
     219    tval = RpRusageTimeDiff(&markPtr->times, &RpRusage_Start.times);
    173220    Tcl_PrintDouble(interp, tval, buffer);
    174221    Tcl_AppendElement(interp, buffer);
     
    178225     */
    179226    Tcl_AppendElement(interp, "walltime");
    180     tval = RpRusageTimeDiff(&curstats.times, &RpRusage_MarkStats.times);
     227    tval = RpRusageTimeDiff(&curstats.times, &markPtr->times);
    181228    Tcl_PrintDouble(interp, tval, buffer);
    182229    Tcl_AppendElement(interp, buffer);
     
    187234    Tcl_AppendElement(interp, "cputime");
    188235    tval = RpRusageTimeDiff(&curstats.resources.ru_utime,
    189              &RpRusage_MarkStats.resources.ru_utime)
     236             &markPtr->resources.ru_utime)
    190237         + RpRusageTimeDiff(&curstats.resources.ru_stime,
    191              &RpRusage_MarkStats.resources.ru_stime);
     238             &markPtr->resources.ru_stime);
    192239    Tcl_PrintDouble(interp, tval, buffer);
    193240    Tcl_AppendElement(interp, buffer);
    194241
     242    return TCL_OK;
     243}
     244
     245/*
     246 * ------------------------------------------------------------------------
     247 *  RpRusageForgetOp()
     248 *
     249 *  Invoked whenever someone uses the "rusage forget" command to release
     250 *  information previous set by "rusage mark".  With no args, it releases
     251 *  all known marks; otherwise, it releases just the specified mark
     252 *  names.  This isn't usually needed, but if a program creates thousands
     253 *  of marks, this gives a way to avoid a huge memory leak.
     254 *  Handles the following syntax:
     255 *
     256 *      rusage forget ?name name...?
     257 *
     258 *  Returns TCL_OK on success, and TCL_ERROR (along with an error
     259 *  message in the interpreter) if anything goes wrong.
     260 * ------------------------------------------------------------------------
     261 */
     262static int
     263RpRusageForgetOp(cdata, interp, objc, objv)
     264    ClientData cdata;         /* not used */
     265    Tcl_Interp *interp;       /* interpreter handling this request */
     266    int objc;                 /* number of command line args */
     267    Tcl_Obj *const *objv;     /* strings for command line args */
     268{
     269    int i;
     270    char *markName;
     271    Tcl_HashTable *markNamesPtr;
     272    Tcl_HashEntry *entryPtr;
     273    Tcl_HashSearch search;
     274
     275    markNamesPtr = (Tcl_HashTable *)
     276        Tcl_GetAssocData(interp, "RpRusageMarks", NULL);
     277
     278    /*
     279     * No args? Then clear all entries in the hash table.
     280     */
     281    if (objc == 2) {
     282        for (entryPtr = Tcl_FirstHashEntry(markNamesPtr, &search);
     283             entryPtr != NULL;
     284             entryPtr = Tcl_NextHashEntry(&search)) {
     285            ckfree((char *)Tcl_GetHashValue(entryPtr));
     286        }
     287        Tcl_DeleteHashTable(markNamesPtr);
     288        Tcl_InitHashTable(markNamesPtr, TCL_STRING_KEYS);
     289    }
     290
     291    /*
     292     * Otherwise, delete only the specified marks.  Be forgiving.
     293     * If a mark isn't recognized, ignore it.
     294     */
     295    else {
     296        for (i=2; i < objc; i++) {
     297            markName = Tcl_GetString(objv[i]);
     298            entryPtr = Tcl_FindHashEntry(markNamesPtr, markName);
     299            if (entryPtr) {
     300                ckfree((char *)Tcl_GetHashValue(entryPtr));
     301                Tcl_DeleteHashEntry(entryPtr);
     302            }
     303        }
     304    }
    195305    return TCL_OK;
    196306}
     
    256366}
    257367
     368/*
     369 * ------------------------------------------------------------------------
     370 *  RpDestroyMarkNames()
     371 *
     372 *  Used internally to clean up the marker names when the interpreter
     373 *  that owns them is being destroyed.
     374 * ------------------------------------------------------------------------
     375 */
     376static void
     377RpDestroyMarkNames(cdata, interp)
     378    ClientData cdata;         /* data being destroyed */
     379    Tcl_Interp *interp;       /* interpreter that owned the data */
     380{
     381    Tcl_HashTable *markNamesPtr;
     382    Tcl_HashEntry *entryPtr;
     383    Tcl_HashSearch search;
     384
     385    for (entryPtr=Tcl_FirstHashEntry(markNamesPtr, &search);
     386         entryPtr != NULL;
     387         entryPtr = Tcl_NextHashEntry(&search)) {
     388        ckfree( (char*)Tcl_GetHashValue(entryPtr) );
     389    }
     390    Tcl_DeleteHashTable(markNamesPtr);
     391    ckfree((char*)markNamesPtr);
     392}
Note: See TracChangeset for help on using the changeset viewer.