diff options
author | Raghavendra Bhat <raghavendrabhat@gluster.com> | 2012-02-20 18:42:37 +0530 |
---|---|---|
committer | Vijay Bellur <vijay@gluster.com> | 2012-02-20 06:59:11 -0800 |
commit | db20a0f8a99f715a77366e518720612f043d5c9e (patch) | |
tree | 8d0a52e8e8833686e5b9358f3c492a94757c93ea /libglusterfs/src/circ-buff.c | |
parent | f764516c2e526624ce0088963924ff2d88304553 (diff) |
libglusterfs: Implement circular buffer and event history
Implement circular buffer framework, so that it can be used by other components
such as event history management. And event history is implemented which can
be used by xlator to dump some information to a file (such as information of some
structure etc).
Through statedump, history of each xlator can be dumped. An option called history
should be given to the statedump command.
Change-Id: I7c5e8f6bd1018584eaee856e933e7c4b94c6709c
BUG: 795419
Signed-off-by: Raghavendra Bhat <raghavendrabhat@gluster.com>
Reviewed-on: http://review.gluster.com/2769
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vijay@gluster.com>
Diffstat (limited to 'libglusterfs/src/circ-buff.c')
-rw-r--r-- | libglusterfs/src/circ-buff.c | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/libglusterfs/src/circ-buff.c b/libglusterfs/src/circ-buff.c new file mode 100644 index 00000000000..36f8eeb7b9a --- /dev/null +++ b/libglusterfs/src/circ-buff.c @@ -0,0 +1,180 @@ +/* + Copyright (c) 2012 Gluster, Inc. <http://www.gluster.com> + This file is part of GlusterFS. + + GlusterFS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3 of the License, + or (at your option) any later version. + + GlusterFS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see + <http://www.gnu.org/licenses/>. +*/ + +#include "circ-buff.h" + +/* hold lock while calling this function */ +int +__cb_add_entry_buffer (buffer_t *buffer, void *item) +{ + circular_buffer_t *ptr = NULL; + int ret = -1; + //DO we really need the assert here? + GF_ASSERT (buffer->used_len <= buffer->size_buffer); + + if (buffer->use_once == _gf_true && + buffer->used_len == buffer->size_buffer) { + gf_log ("", GF_LOG_WARNING, "buffer %p is use once buffer", + buffer); + return -1; + } else { + if (buffer->used_len == buffer->size_buffer) { + if (buffer->cb[buffer->w_index]) { + ptr = buffer->cb[buffer->w_index]; + if (ptr->data) { + GF_FREE (ptr->data); + ptr->data = NULL; + GF_FREE (ptr); + } + buffer->cb[buffer->w_index] = NULL; + ptr = NULL; + } + } + + buffer->cb[buffer->w_index] = + GF_CALLOC (1, sizeof (circular_buffer_t), + gf_common_mt_circular_buffer_t); + if (!buffer->cb[buffer->w_index]) + return -1; + + buffer->cb[buffer->w_index]->data = item; + ret = gettimeofday (&buffer->cb[buffer->w_index]->tv, NULL); + if (ret == -1) + gf_log_callingfn ("", GF_LOG_WARNING, "getting time of" + "the day failed"); + + buffer->w_index++; + buffer->w_index %= buffer->size_buffer - 1; + //used_buffer size cannot be greater than the total buffer size + + if (buffer->used_len < buffer->size_buffer) + buffer->used_len++; + return buffer->w_index; + } +} + +int +cb_add_entry_buffer (buffer_t *buffer, void *item) +{ + int write_index = -1; + + pthread_mutex_lock (&buffer->lock); + { + write_index = __cb_add_entry_buffer (buffer, item); + } + pthread_mutex_unlock (&buffer->lock); + + return write_index; +} + +void +cb_buffer_show (buffer_t *buffer) +{ + pthread_mutex_lock (&buffer->lock); + { + gf_log ("", GF_LOG_DEBUG, "w_index: %d, size: %"GF_PRI_SIZET + " used_buffer: %d", buffer->w_index, + buffer->size_buffer, + buffer->used_len); + } + pthread_mutex_unlock (&buffer->lock); +} + +void +cb_buffer_dump (buffer_t *buffer, void *data, + int (fn) (circular_buffer_t *buffer, void *data)) +{ + int i = 0; + circular_buffer_t *entry = NULL; + int entries = 0; + + pthread_mutex_lock (&buffer->lock); + { + if (buffer->use_once == _gf_false) { + for (i = (buffer->w_index - 1) ; entries < + buffer->used_len ; entries++) { + entry = buffer->cb[i]; + if (entry) + fn (entry, data); + if (0 == i) + i = buffer->used_len - 1; + else + i = (i - 1) % (buffer->used_len - 1); + } + } else { + for (i = 0; i < buffer->used_len ; i++) { + entry = buffer->cb[i]; + fn (entry, data); + } + } + } + pthread_mutex_unlock (&buffer->lock); +} + +buffer_t * +cb_buffer_new (size_t buffer_size, gf_boolean_t use_once) +{ + buffer_t *buffer = NULL; + + buffer = GF_CALLOC (1, sizeof (*buffer), gf_common_mt_buffer_t); + if (!buffer) { + gf_log ("", GF_LOG_ERROR, "could not allocate the " + "buffer"); + goto out; + } + + buffer->cb = GF_CALLOC (buffer_size, + sizeof (circular_buffer_t *), + gf_common_mt_circular_buffer_t); + if (!buffer->cb) { + gf_log ("", GF_LOG_ERROR, "could not allocate the " + "memory for the circular buffer"); + GF_FREE (buffer); + buffer = NULL; + goto out; + } + + buffer->w_index = 0; + buffer->size_buffer = buffer_size; + buffer->use_once = use_once; + buffer->used_len = 0; + pthread_mutex_init (&buffer->lock, NULL); + +out: + return buffer; +} + +void +cb_buffer_destroy (buffer_t *buffer) +{ + int i = 0; + + if (buffer) { + if (buffer->cb) { + for (i = 0; i < buffer->used_len ; i++) { + if (buffer->cb[i]) + GF_FREE (buffer->cb[i]); + } + GF_FREE (buffer->cb); + } + pthread_mutex_destroy (&buffer->lock); + GF_FREE (buffer); + } +} + |