diff options
Diffstat (limited to 'libglusterfs/src/stack.h')
-rw-r--r-- | libglusterfs/src/stack.h | 52 |
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)); } |