summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/stack.h
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/stack.h')
-rw-r--r--libglusterfs/src/stack.h52
1 files changed, 33 insertions, 19 deletions
diff --git a/libglusterfs/src/stack.h b/libglusterfs/src/stack.h
index 856a9a4786e..8a617377bc7 100644
--- a/libglusterfs/src/stack.h
+++ b/libglusterfs/src/stack.h
@@ -32,6 +32,7 @@ typedef struct call_pool call_pool_t;
#include "lkowner.h"
#include "client_t.h"
#include "libglusterfs-messages.h"
+#include "timespec.h"
#define NFS_PID 1
#define LOW_PRIO_PROC_PID -1
@@ -72,9 +73,9 @@ struct _call_frame {
void *cookie; /* unique cookie */
gf_boolean_t complete;
- glusterfs_fop_t op;
- struct timeval begin; /* when this frame was created */
- struct timeval end; /* when this frame completed */
+ glusterfs_fop_t op;
+ struct timespec begin; /* when this frame was created */
+ struct timespec end; /* when this frame completed */
const char *wind_from;
const char *wind_to;
const char *unwind_from;
@@ -112,7 +113,7 @@ struct _call_stack {
int32_t op;
int8_t type;
- struct timeval tv;
+ struct timespec tv;
xlator_t *err_xl;
int32_t error;
};
@@ -129,18 +130,17 @@ struct _call_stack {
struct xlator_fops;
+void gf_update_latency (call_frame_t *frame);
-void
-gf_latency_begin (call_frame_t *frame, void *fn);
-
-void
-gf_latency_end (call_frame_t *frame);
static inline void
FRAME_DESTROY (call_frame_t *frame)
{
void *local = NULL;
+ if (frame->root->ctx->measure_latency)
+ gf_update_latency (frame);
+
list_del_init (&frame->frames);
if (frame->local) {
local = frame->local;
@@ -225,6 +225,18 @@ STACK_RESET (call_stack_t *stack)
} while (0); \
+/* NOTE: make sure to keep this as an macro, mainly because, we need 'fn'
+ field here to be the proper fn ptr, so its address is valid entry in
+ 'xlator_fops' struct.
+ To understand this, check the `xlator.h:struct xlator_fops`, and then
+ see a STACK_WIND call, which generally calls `subvol->fops->fop`, so
+ the address offset should give the index */
+
+/* +1 is required as 0 means NULL fop, and we don't have a variable for it */
+#define get_fop_index_from_fn(xl, fn) \
+ (1 + (((long)&(fn) - (long)&((xl)->fops->stat)) / sizeof (void *)))
+
+
/* make a call without switching frames */
#define STACK_WIND_TAIL(frame, obj, fn, params ...) \
do { \
@@ -295,7 +307,8 @@ STACK_RESET (call_stack_t *stack)
frame->root, old_THIS->name, \
THIS->name); \
if (obj->ctx->measure_latency) \
- gf_latency_begin (_new, fn); \
+ timespec_now (&_new->begin); \
+ _new->op = get_fop_index_from_fn ((_new->this), (fn)); \
fn (_new, obj, params); \
THIS = old_THIS; \
} while (0)
@@ -304,9 +317,9 @@ STACK_RESET (call_stack_t *stack)
#define STACK_UNWIND STACK_UNWIND_STRICT
/* return from function in type-safe way */
-#define STACK_UNWIND_STRICT(op, frame, op_ret, op_errno, params ...) \
+#define STACK_UNWIND_STRICT(fop, frame, op_ret, op_errno, params ...) \
do { \
- fop_##op##_cbk_t fn = NULL; \
+ fop_##fop##_cbk_t fn = NULL; \
call_frame_t *_parent = NULL; \
xlator_t *old_THIS = NULL; \
\
@@ -329,7 +342,7 @@ STACK_RESET (call_stack_t *stack)
frame->root, THIS->name, \
(int32_t)(op_ret)); \
} \
- fn = (fop_##op##_cbk_t )frame->ret; \
+ fn = (fop_##fop##_cbk_t)frame->ret; \
_parent = frame->parent; \
LOCK(&frame->root->stack_lock); \
{ \
@@ -348,8 +361,12 @@ STACK_RESET (call_stack_t *stack)
THIS = _parent->this; \
frame->complete = _gf_true; \
frame->unwind_from = __FUNCTION__; \
- if (frame->this->ctx->measure_latency) \
- gf_latency_end (frame); \
+ if (frame->this->ctx->measure_latency) { \
+ timespec_now (&frame->end); \
+ /* required for top most xlator */ \
+ if (_parent->ret == NULL) \
+ timespec_now (&_parent->end); \
+ } \
fn (_parent, frame->cookie, _parent->this, op_ret, \
op_errno, params); \
THIS = old_THIS; \
@@ -454,10 +471,7 @@ copy_frame (call_frame_t *frame)
newstack->ctx = oldstack->ctx;
if (newstack->ctx->measure_latency) {
- if (gettimeofday (&newstack->tv, NULL) == -1)
- gf_msg ("stack", GF_LOG_ERROR, errno,
- LG_MSG_GETTIMEOFDAY_FAILED,
- "gettimeofday () failed.");
+ timespec_now (&newstack->tv);
memcpy (&newframe->begin, &newstack->tv,
sizeof (newstack->tv));
}