static int rxi_monitor_peerStats = 0;
+
+void
+rxi_ClearRPCOpStat(rx_function_entry_v1_p rpc_stat)
+{
+ rpc_stat->invocations = 0;
+ rpc_stat->bytes_sent = 0;
+ rpc_stat->bytes_rcvd = 0;
+ rpc_stat->queue_time_sum.sec = 0;
+ rpc_stat->queue_time_sum.usec = 0;
+ rpc_stat->queue_time_sum_sqr.sec = 0;
+ rpc_stat->queue_time_sum_sqr.usec = 0;
+ rpc_stat->queue_time_min.sec = 9999999;
+ rpc_stat->queue_time_min.usec = 9999999;
+ rpc_stat->queue_time_max.sec = 0;
+ rpc_stat->queue_time_max.usec = 0;
+ rpc_stat->execution_time_sum.sec = 0;
+ rpc_stat->execution_time_sum.usec = 0;
+ rpc_stat->execution_time_sum_sqr.sec = 0;
+ rpc_stat->execution_time_sum_sqr.usec = 0;
+ rpc_stat->execution_time_min.sec = 9999999;
+ rpc_stat->execution_time_min.usec = 9999999;
+ rpc_stat->execution_time_max.sec = 0;
+ rpc_stat->execution_time_max.usec = 0;
+}
+
/*!
* Given all of the information for a particular rpc
- * call, create (if needed) and update the stat totals for the rpc.
+ * call, find or create (if requested) the stat structure for the rpc.
*
* @param stats
* the queue of stats that will be updated with the new value
* @param rxInterface
* a unique number that identifies the rpc interface
*
- * @param currentFunc
- * the index of the function being invoked
- *
* @param totalFunc
- * the total number of functions in this interface
- *
- * @param queueTime
- * the amount of time this function waited for a thread
- *
- * @param execTime
- * the amount of time this function invocation took to execute
- *
- * @param bytesSent
- * the number bytes sent by this invocation
- *
- * @param bytesRcvd
- * the number bytes received by this invocation
+ * the total number of functions in this interface. this is only
+ * required if create is true
*
* @param isServer
* if true, this invocation was made to a server
*
* @param remoteHost
- * the ip address of the remote host
+ * the ip address of the remote host. this is only required if create
+ * and addToPeerList are true
*
* @param remotePort
- * the port of the remote host
+ * the port of the remote host. this is only required if create
+ * and addToPeerList are true
*
* @param addToPeerList
* if != 0, add newly created stat to the global peer list
*
* @param counter
* if a new stats structure is allocated, the counter will
- * be updated with the new number of allocated stat structures
+ * be updated with the new number of allocated stat structures.
+ * only required if create is true
+ *
+ * @param create
+ * if no stats structure exists, allocate one
*
*/
-static int
-rxi_AddRpcStat(struct rx_queue *stats, afs_uint32 rxInterface,
- afs_uint32 currentFunc, afs_uint32 totalFunc,
- struct clock *queueTime, struct clock *execTime,
- afs_uint64 bytesSent, afs_uint64 bytesRcvd, int isServer,
- afs_uint32 remoteHost, afs_uint32 remotePort,
- int addToPeerList, unsigned int *counter)
+static rx_interface_stat_p
+rxi_FindRpcStat(struct rx_queue *stats, afs_uint32 rxInterface,
+ afs_uint32 totalFunc, int isServer, afs_uint32 remoteHost,
+ afs_uint32 remotePort, int addToPeerList,
+ unsigned int *counter, int create)
{
- int rc = 0;
rx_interface_stat_p rpc_stat, nrpc_stat;
-
/*
* See if there's already a structure for this interface
*/
break;
}
+ /* if they didn't ask us to create, we're done */
+ if (!create)
+ return rpc_stat;
+
+ /* can't proceed without these */
+ if (!totalFunc || !counter)
+ return NULL;
+
/*
* Didn't find a match so allocate a new structure and add it to the
* queue.
totalFunc * sizeof(rx_function_entry_v1_t);
rpc_stat = rxi_Alloc(space);
- if (rpc_stat == NULL) {
- rc = 1;
- goto fail;
- }
+ if (rpc_stat == NULL)
+ return NULL;
+
*counter += totalFunc;
for (i = 0; i < totalFunc; i++) {
+ rxi_ClearRPCOpStat(&(rpc_stat->stats[i]));
rpc_stat->stats[i].remote_peer = remoteHost;
rpc_stat->stats[i].remote_port = remotePort;
rpc_stat->stats[i].remote_is_server = isServer;
rpc_stat->stats[i].interfaceId = rxInterface;
rpc_stat->stats[i].func_total = totalFunc;
rpc_stat->stats[i].func_index = i;
- rpc_stat->stats[i].invocations = 0;
- rpc_stat->stats[i].bytes_sent = 0;
- rpc_stat->stats[i].bytes_rcvd = 0;
- rpc_stat->stats[i].queue_time_sum.sec = 0;
- rpc_stat->stats[i].queue_time_sum.usec = 0;
- rpc_stat->stats[i].queue_time_sum_sqr.sec = 0;
- rpc_stat->stats[i].queue_time_sum_sqr.usec = 0;
- rpc_stat->stats[i].queue_time_min.sec = 9999999;
- rpc_stat->stats[i].queue_time_min.usec = 9999999;
- rpc_stat->stats[i].queue_time_max.sec = 0;
- rpc_stat->stats[i].queue_time_max.usec = 0;
- rpc_stat->stats[i].execution_time_sum.sec = 0;
- rpc_stat->stats[i].execution_time_sum.usec = 0;
- rpc_stat->stats[i].execution_time_sum_sqr.sec = 0;
- rpc_stat->stats[i].execution_time_sum_sqr.usec = 0;
- rpc_stat->stats[i].execution_time_min.sec = 9999999;
- rpc_stat->stats[i].execution_time_min.usec = 9999999;
- rpc_stat->stats[i].execution_time_max.sec = 0;
- rpc_stat->stats[i].execution_time_max.usec = 0;
}
queue_Prepend(stats, rpc_stat);
if (addToPeerList) {
queue_Prepend(&peerStats, &rpc_stat->all_peers);
}
}
+ return rpc_stat;
+}
+
+void
+rx_ClearProcessRPCStats(afs_int32 rxInterface)
+{
+ rx_interface_stat_p rpc_stat;
+ int totalFunc, i;
+
+ if (rxInterface == -1)
+ return;
+
+ MUTEX_ENTER(&rx_rpc_stats);
+ rpc_stat = rxi_FindRpcStat(&processStats, rxInterface, 0, 0,
+ 0, 0, 0, 0, 0);
+ if (rpc_stat) {
+ totalFunc = rpc_stat->stats[0].func_total;
+ for (i = 0; i < totalFunc; i++)
+ rxi_ClearRPCOpStat(&(rpc_stat->stats[i]));
+ }
+ MUTEX_EXIT(&rx_rpc_stats);
+ return;
+}
+
+void
+rx_ClearPeerRPCStats(afs_int32 rxInterface, afs_uint32 peerHost, afs_uint16 peerPort)
+{
+ rx_interface_stat_p rpc_stat;
+ int totalFunc, i;
+ struct rx_peer * peer;
+
+ if (rxInterface == -1)
+ return;
+
+ peer = rxi_FindPeer(peerHost, peerPort, 0, 0);
+ if (!peer)
+ return;
+
+ MUTEX_ENTER(&rx_rpc_stats);
+ rpc_stat = rxi_FindRpcStat(&peer->rpcStats, rxInterface, 0, 1,
+ 0, 0, 0, 0, 0);
+ if (rpc_stat) {
+ totalFunc = rpc_stat->stats[0].func_total;
+ for (i = 0; i < totalFunc; i++)
+ rxi_ClearRPCOpStat(&(rpc_stat->stats[i]));
+ }
+ MUTEX_EXIT(&rx_rpc_stats);
+ return;
+}
+
+void *
+rx_CopyProcessRPCStats(afs_uint64 op)
+{
+ rx_interface_stat_p rpc_stat;
+ rx_function_entry_v1_p rpcop_stat =
+ rxi_Alloc(sizeof(rx_function_entry_v1_t));
+ int currentFunc = (op & MAX_AFS_UINT32);
+ afs_int32 rxInterface = (op >> 32);
+
+ if (!rxi_monitor_processStats)
+ return NULL;
+
+ if (rxInterface == -1)
+ return NULL;
+
+ MUTEX_ENTER(&rx_rpc_stats);
+ rpc_stat = rxi_FindRpcStat(&processStats, rxInterface, 0, 0,
+ 0, 0, 0, 0, 0);
+ if (rpc_stat)
+ memcpy(rpcop_stat, &(rpc_stat->stats[currentFunc]),
+ sizeof(rx_function_entry_v1_t));
+ MUTEX_EXIT(&rx_rpc_stats);
+ if (!rpc_stat) {
+ rxi_Free(rpcop_stat, sizeof(rx_function_entry_v1_t));
+ return NULL;
+ }
+ return rpcop_stat;
+}
+
+void *
+rx_CopyPeerRPCStats(afs_uint64 op, afs_uint32 peerHost, afs_uint16 peerPort)
+{
+ rx_interface_stat_p rpc_stat;
+ rx_function_entry_v1_p rpcop_stat =
+ rxi_Alloc(sizeof(rx_function_entry_v1_t));
+ int currentFunc = (op & MAX_AFS_UINT32);
+ afs_int32 rxInterface = (op >> 32);
+ struct rx_peer *peer;
+
+ if (!rxi_monitor_peerStats)
+ return NULL;
+
+ if (rxInterface == -1)
+ return NULL;
+
+ peer = rxi_FindPeer(peerHost, peerPort, 0, 0);
+ if (!peer)
+ return NULL;
+
+ MUTEX_ENTER(&rx_rpc_stats);
+ rpc_stat = rxi_FindRpcStat(&peer->rpcStats, rxInterface, 0, 1,
+ 0, 0, 0, 0, 0);
+ if (rpc_stat)
+ memcpy(rpcop_stat, &(rpc_stat->stats[currentFunc]),
+ sizeof(rx_function_entry_v1_t));
+ MUTEX_EXIT(&rx_rpc_stats);
+ if (!rpc_stat) {
+ rxi_Free(rpcop_stat, sizeof(rx_function_entry_v1_t));
+ return NULL;
+ }
+ return rpcop_stat;
+}
+
+void
+rx_ReleaseRPCStats(void *stats)
+{
+ if (stats)
+ rxi_Free(stats, sizeof(rx_function_entry_v1_t));
+}
+
+/*!
+ * Given all of the information for a particular rpc
+ * call, create (if needed) and update the stat totals for the rpc.
+ *
+ * @param stats
+ * the queue of stats that will be updated with the new value
+ *
+ * @param rxInterface
+ * a unique number that identifies the rpc interface
+ *
+ * @param currentFunc
+ * the index of the function being invoked
+ *
+ * @param totalFunc
+ * the total number of functions in this interface
+ *
+ * @param queueTime
+ * the amount of time this function waited for a thread
+ *
+ * @param execTime
+ * the amount of time this function invocation took to execute
+ *
+ * @param bytesSent
+ * the number bytes sent by this invocation
+ *
+ * @param bytesRcvd
+ * the number bytes received by this invocation
+ *
+ * @param isServer
+ * if true, this invocation was made to a server
+ *
+ * @param remoteHost
+ * the ip address of the remote host
+ *
+ * @param remotePort
+ * the port of the remote host
+ *
+ * @param addToPeerList
+ * if != 0, add newly created stat to the global peer list
+ *
+ * @param counter
+ * if a new stats structure is allocated, the counter will
+ * be updated with the new number of allocated stat structures
+ *
+ */
+
+static int
+rxi_AddRpcStat(struct rx_queue *stats, afs_uint32 rxInterface,
+ afs_uint32 currentFunc, afs_uint32 totalFunc,
+ struct clock *queueTime, struct clock *execTime,
+ afs_uint64 bytesSent, afs_uint64 bytesRcvd, int isServer,
+ afs_uint32 remoteHost, afs_uint32 remotePort,
+ int addToPeerList, unsigned int *counter)
+{
+ int rc = 0;
+ rx_interface_stat_p rpc_stat;
+
+ rpc_stat = rxi_FindRpcStat(stats, rxInterface, totalFunc, isServer,
+ remoteHost, remotePort, addToPeerList, counter,
+ 1);
+ if (!rpc_stat) {
+ rc = -1;
+ goto fail;
+ }
/*
* Increment the stats for this function
#include "rx_prototypes.h"
#endif
+static_inline afs_uint32
+RPCOpStat_Peer(void *blob) {
+ rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
+ return rpcop_stat->remote_peer;
+}
+
+static_inline afs_uint32
+RPCOpStat_Port(void *blob) {
+ rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
+ return rpcop_stat->remote_port;
+}
+
+static_inline afs_uint32
+RPCOpStat_IsServer(void *blob) {
+ rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
+ return rpcop_stat->remote_is_server;
+}
+
+static_inline afs_uint32
+RPCOpStat_InterfaceId(void *blob) {
+ rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
+ return rpcop_stat->interfaceId;
+}
+
+static_inline afs_uint32
+RPCOpStat_NumFuncs(void *blob) {
+ rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
+ return rpcop_stat->func_total;
+}
+
+static_inline afs_uint32
+RPCOpStat_CurFunc(void *blob) {
+ rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
+ return rpcop_stat->func_index;
+}
+
+static_inline struct clock *
+RPCOpStat_QTimeSum(void *blob) {
+ rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
+ return &(rpcop_stat->queue_time_sum);
+}
+
+static_inline struct clock *
+RPCOpStat_QTimeSumSqr(void *blob) {
+ rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
+ return &(rpcop_stat->queue_time_sum_sqr);
+}
+
+static_inline struct clock *
+RPCOpStat_QTimeSumMin(void *blob) {
+ rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
+ return &(rpcop_stat->queue_time_min);
+}
+
+static_inline struct clock *
+RPCOpStat_QTimeSumMax(void *blob) {
+ rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
+ return &(rpcop_stat->queue_time_max);
+}
+
+static_inline struct clock *
+RPCOpStat_ExecTimeSum(void *blob) {
+ rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
+ return &(rpcop_stat->execution_time_sum);
+}
+
+static_inline struct clock *
+RPCOpStat_ExecTimeSumSqr(void *blob) {
+ rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
+ return &(rpcop_stat->execution_time_sum_sqr);
+}
+
+static_inline struct clock *
+RPCOpStat_ExecTimeSumMin(void *blob) {
+ rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
+ return &(rpcop_stat->execution_time_min);
+}
+
+static_inline struct clock *
+RPCOpStat_ExecTimeSumMax(void *blob) {
+ rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
+ return &(rpcop_stat->execution_time_max);
+}
+
+static_inline afs_uint64
+RPCOpStat_NumCalls(void *blob) {
+ rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
+ return rpcop_stat->invocations;
+}
+
+static_inline afs_uint64
+RPCOpStat_BytesSent(void *blob) {
+ rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
+ return rpcop_stat->bytes_sent;
+}
+
+static_inline afs_uint64
+RPCOpStat_BytesRcvd(void *blob) {
+ rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
+ return rpcop_stat->bytes_rcvd;
+}
#endif /* !KDUMP_RX_LOCK */
static void er_ProcProcsArray_setup(void);
static void er_ProcMainBody_setup(void);
static void er_HeadofOldStyleProc_setup(void);
+static void er_HeadofOldStyleProc_setup2(void);
static void er_BodyofOldStyleProc_setup(void);
+static void er_BodyofOldStyleProc_setup2(void);
static void proc_er_case(definition * defp);
static void er_TailofOldStyleProc_setup(void);
+static void er_TailofOldStyleProc_setup2(void);
prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
function_list_index++;
+ defp->statindex = no_of_stat_funcs;
no_of_stat_funcs_header[PackageIndex]++;
no_of_stat_funcs++;
*Proc_listp = NULL;
er_HeadofOldStyleProc_setup();
er_BodyofOldStyleProc_setup();
er_TailofOldStyleProc_setup();
+ er_HeadofOldStyleProc_setup2();
+ er_BodyofOldStyleProc_setup2();
+ er_TailofOldStyleProc_setup2();
} else {
er_ProcDeclExterns_setup();
er_ProcProcsArray_setup();
PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
f_print(fout, "\treturn opnames%d[op - %sLOWEST_OPCODE];\n}\n",
PackageIndex, PackagePrefix[PackageIndex]);
+ f_print(fout, "struct %sstats *%sOpCodeStats(int op)\n{\n",
+ PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
+ f_print(fout, "\tif (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\treturn NULL;\n",
+ PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
+ f_print(fout, "\treturn NULL;/*%d %s*/\n}\n",
+ PackageIndex, PackagePrefix[PackageIndex]);
+
return;
}
f_print(fout, "int %s%sExecuteRequest(struct rx_call *z_call)\n",
f_print(fout, "\treturn hton_syserr_conv(z_result);\n}\n");
}
+static void
+er_HeadofOldStyleProc_setup2(void)
+{
+ if ( cflag ) {
+ f_print(fout, "int %sOpCodeIndex(int op)\n{\n", (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
+ f_print(fout, "\tswitch (op) {\n");
+ }
+}
static void
er_HeadofOldStyleProc_setup(void)
f_print(fout, "\t\t\tbreak;\n");
}
+static void
+proc_op_case(definition * defp)
+{
+ f_print(fout, "\t\tcase %d:", defp->pc.proc_opcodenum);
+ f_print(fout, "\treturn %d;\n",
+ defp->statindex);
+}
+
+static void
+er_BodyofOldStyleProc_setup2(void)
+{
+ list *listp;
+
+ if (!cflag)
+ return;
+ if (combinepackages) {
+ int temp = PackageIndex;
+ for (PackageIndex = 0; PackageIndex <= temp; PackageIndex++) {
+ for (listp = proc_defined[PackageIndex]; listp != NULL;
+ listp = listp->next)
+ proc_op_case((definition *) listp->val);
+ }
+ PackageIndex = temp;
+ } else {
+ for (listp = proc_defined[PackageIndex]; listp != NULL;
+ listp = listp->next)
+ proc_op_case((definition *) listp->val);
+ }
+}
+
+static void
+er_TailofOldStyleProc_setup2(void)
+{
+ if ( cflag ) {
+ f_print(fout, "\t\tdefault:\n");
+ f_print(fout, "\t\t\treturn -1;\n\t}\n}\n");
+ }
+}
static void
er_TailofOldStyleProc_setup(void)
static void
h_HeadofOldStyleProc_setup(void)
{
+ char *pprefix = (combinepackages ? MasterPrefix :
+ PackagePrefix[PackageIndex]);
+ f_print(fout,"\nstruct %sstats{\n\tint statsver;\n};", pprefix);
f_print(fout,"\nextern int %s%sExecuteRequest(struct rx_call *);\n",
- prefix,
- (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
+ prefix, pprefix);
f_print(fout,"\nextern int %sOpCodeIndex(int op);\n", PackagePrefix[PackageIndex]);
}