/* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ /* An abstracted interface for recording fs statistics data */ #include #include #include #include #include #include #include #include #include #include "viced.h" #include "fs_stats.h" void fsstats_StartOp(struct fsstats *stats, int index) { assert(index >= 0 && index < FS_STATS_NUM_RPC_OPS); stats->opP = &(afs_FullPerfStats.det.rpcOpTimes[index]); FS_LOCK; (stats->opP->numOps)++; FS_UNLOCK; gettimeofday(&stats->opStartTime, NULL); } void fsstats_FinishOp(struct fsstats *stats, int code) { struct timeval opStopTime, elapsedTime; gettimeofday(&opStopTime, NULL); if (code == 0) { FS_LOCK; (stats->opP->numSuccesses)++; fs_stats_GetDiff(elapsedTime, stats->opStartTime, opStopTime); fs_stats_AddTo((stats->opP->sumTime), elapsedTime); fs_stats_SquareAddTo((stats->opP->sqrTime), elapsedTime); if (fs_stats_TimeLessThan(elapsedTime, (stats->opP->minTime))) { fs_stats_TimeAssign((stats->opP->minTime), elapsedTime); } if (fs_stats_TimeGreaterThan(elapsedTime, (stats->opP->maxTime))) { fs_stats_TimeAssign((stats->opP->maxTime), elapsedTime); } FS_UNLOCK; } } void fsstats_StartXfer(struct fsstats *stats, int index) { assert(index >= 0 && index < FS_STATS_NUM_XFER_OPS); gettimeofday(&stats->xferStartTime, NULL); stats->xferP = &(afs_FullPerfStats.det.xferOpTimes[index]); } void fsstats_FinishXfer(struct fsstats *stats, int code, afs_sfsize_t bytesToXfer, afs_sfsize_t bytesXferred, int *remainder) { struct timeval xferStopTime; struct timeval elapsedTime; /* * At this point, the data transfer is done, for good or ill. Remember * when the transfer ended, bump the number of successes/failures, and * integrate the transfer size and elapsed time into the stats. If the * operation failed, we jump to the appropriate point. */ gettimeofday(&xferStopTime, 0); FS_LOCK; (stats->xferP->numXfers)++; if (code == 0) { (stats->xferP->numSuccesses)++; /* * Bump the xfer sum by the number of bytes actually sent, NOT the * target number. */ *remainder += bytesXferred; (stats->xferP->sumBytes) += (*remainder >> 10); *remainder &= 0x3FF; if (bytesXferred < stats->xferP->minBytes) stats->xferP->minBytes = bytesXferred; if (bytesXferred > stats->xferP->maxBytes) stats->xferP->maxBytes = bytesXferred; /* * Tally the size of the object. Note: we tally the actual size, * NOT the number of bytes that made it out over the wire. */ if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET0) (stats->xferP->count[0])++; else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET1) (stats->xferP->count[1])++; else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET2) (stats->xferP->count[2])++; else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET3) (stats->xferP->count[3])++; else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET4) (stats->xferP->count[4])++; else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET5) (stats->xferP->count[5])++; else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET6) (stats->xferP->count[6])++; else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET7) (stats->xferP->count[7])++; else (stats->xferP->count[8])++; fs_stats_GetDiff(elapsedTime, stats->xferStartTime, xferStopTime); fs_stats_AddTo((stats->xferP->sumTime), elapsedTime); fs_stats_SquareAddTo((stats->xferP->sqrTime), elapsedTime); if (fs_stats_TimeLessThan(elapsedTime, (stats->xferP->minTime))) { fs_stats_TimeAssign((stats->xferP->minTime), elapsedTime); } if (fs_stats_TimeGreaterThan(elapsedTime, (stats->xferP->maxTime))) { fs_stats_TimeAssign((stats->xferP->maxTime), elapsedTime); } } FS_UNLOCK; }