"Fossies" - the Fresh Open Source Software Archive

Member "glusterfs-8.2/libglusterfs/src/circ-buff.c" (16 Sep 2020, 5643 Bytes) of package /linux/misc/glusterfs-8.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "circ-buff.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2   Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
    3   This file is part of GlusterFS.
    4 
    5   This file is licensed to you under your choice of the GNU Lesser
    6   General Public License, version 3 or any later version (LGPLv3 or
    7   later), or the GNU General Public License, version 2 (GPLv2), in all
    8   cases as published by the Free Software Foundation.
    9 */
   10 
   11 #include "glusterfs/circ-buff.h"
   12 #include "glusterfs/libglusterfs-messages.h"
   13 
   14 void
   15 cb_destroy_data(circular_buffer_t *cb, void (*destroy_buffer_data)(void *data))
   16 {
   17     if (destroy_buffer_data)
   18         destroy_buffer_data(cb->data);
   19     GF_FREE(cb->data);
   20     return;
   21 }
   22 
   23 /* hold lock while calling this function */
   24 int
   25 __cb_add_entry_buffer(buffer_t *buffer, void *item)
   26 {
   27     circular_buffer_t *ptr = NULL;
   28     int ret = -1;
   29     // DO we really need the assert here?
   30     GF_ASSERT(buffer->used_len <= buffer->size_buffer);
   31 
   32     if (buffer->use_once == _gf_true &&
   33         buffer->used_len == buffer->size_buffer) {
   34         gf_msg("circ-buff", GF_LOG_WARNING, 0, LG_MSG_BUFFER_ERROR,
   35                "buffer %p is use once buffer", buffer);
   36         return -1;
   37     } else {
   38         if (buffer->used_len == buffer->size_buffer) {
   39             if (buffer->cb[buffer->w_index]) {
   40                 ptr = buffer->cb[buffer->w_index];
   41                 if (ptr->data) {
   42                     cb_destroy_data(ptr, buffer->destroy_buffer_data);
   43                     ptr->data = NULL;
   44                     GF_FREE(ptr);
   45                 }
   46                 buffer->cb[buffer->w_index] = NULL;
   47                 ptr = NULL;
   48             }
   49         }
   50 
   51         buffer->cb[buffer->w_index] = GF_CALLOC(1, sizeof(circular_buffer_t),
   52                                                 gf_common_mt_circular_buffer_t);
   53         if (!buffer->cb[buffer->w_index])
   54             return -1;
   55 
   56         buffer->cb[buffer->w_index]->data = item;
   57         ret = gettimeofday(&buffer->cb[buffer->w_index]->tv, NULL);
   58         if (ret == -1)
   59             gf_msg_callingfn("circ-buff", GF_LOG_WARNING, 0,
   60                              LG_MSG_GETTIMEOFDAY_FAILED,
   61                              "getting time of the day failed");
   62         buffer->w_index++;
   63         buffer->w_index %= buffer->size_buffer;
   64         // used_buffer size cannot be greater than the total buffer size
   65 
   66         if (buffer->used_len < buffer->size_buffer)
   67             buffer->used_len++;
   68         return buffer->w_index;
   69     }
   70 }
   71 
   72 int
   73 cb_add_entry_buffer(buffer_t *buffer, void *item)
   74 {
   75     int write_index = -1;
   76 
   77     pthread_mutex_lock(&buffer->lock);
   78     {
   79         write_index = __cb_add_entry_buffer(buffer, item);
   80     }
   81     pthread_mutex_unlock(&buffer->lock);
   82 
   83     return write_index;
   84 }
   85 
   86 void
   87 cb_buffer_show(buffer_t *buffer)
   88 {
   89     pthread_mutex_lock(&buffer->lock);
   90     {
   91         gf_msg_debug("circ-buff", 0,
   92                      "w_index: %d, size: %" GF_PRI_SIZET " used_buffer: %d",
   93                      buffer->w_index, buffer->size_buffer, buffer->used_len);
   94     }
   95     pthread_mutex_unlock(&buffer->lock);
   96 }
   97 
   98 void
   99 cb_buffer_dump(buffer_t *buffer, void *data,
  100                int(fn)(circular_buffer_t *buffer, void *data))
  101 {
  102     int index = 0;
  103     circular_buffer_t *entry = NULL;
  104     int entries = 0;
  105     int ul = 0;
  106     int w_ind = 0;
  107     int size_buff = 0;
  108     int i = 0;
  109 
  110     ul = buffer->used_len;
  111     w_ind = buffer->w_index;
  112     size_buff = buffer->size_buffer;
  113 
  114     pthread_mutex_lock(&buffer->lock);
  115     {
  116         if (buffer->use_once == _gf_false) {
  117             index = (size_buff + (w_ind - ul)) % size_buff;
  118             for (entries = 0; entries < buffer->used_len; entries++) {
  119                 entry = buffer->cb[index];
  120                 if (entry)
  121                     fn(entry, data);
  122                 else
  123                     gf_msg_callingfn("circ-buff", GF_LOG_WARNING, 0,
  124                                      LG_MSG_NULL_PTR,
  125                                      "Null entry in "
  126                                      "circular buffer at "
  127                                      "index %d.",
  128                                      index);
  129 
  130                 index++;
  131                 index %= buffer->size_buffer;
  132             }
  133         } else {
  134             for (i = 0; i < buffer->used_len; i++) {
  135                 entry = buffer->cb[i];
  136                 fn(entry, data);
  137             }
  138         }
  139     }
  140     pthread_mutex_unlock(&buffer->lock);
  141 }
  142 
  143 buffer_t *
  144 cb_buffer_new(size_t buffer_size, gf_boolean_t use_once,
  145               void (*destroy_buffer_data)(void *data))
  146 {
  147     buffer_t *buffer = NULL;
  148 
  149     buffer = GF_CALLOC(1, sizeof(*buffer), gf_common_mt_buffer_t);
  150     if (!buffer) {
  151         goto out;
  152     }
  153 
  154     buffer->cb = GF_CALLOC(buffer_size, sizeof(circular_buffer_t *),
  155                            gf_common_mt_circular_buffer_t);
  156     if (!buffer->cb) {
  157         GF_FREE(buffer);
  158         buffer = NULL;
  159         goto out;
  160     }
  161 
  162     buffer->w_index = 0;
  163     buffer->size_buffer = buffer_size;
  164     buffer->use_once = use_once;
  165     buffer->used_len = 0;
  166     buffer->destroy_buffer_data = destroy_buffer_data;
  167     pthread_mutex_init(&buffer->lock, NULL);
  168 
  169 out:
  170     return buffer;
  171 }
  172 
  173 void
  174 cb_buffer_destroy(buffer_t *buffer)
  175 {
  176     int i = 0;
  177     circular_buffer_t *ptr = NULL;
  178     if (buffer) {
  179         if (buffer->cb) {
  180             for (i = 0; i < buffer->used_len; i++) {
  181                 ptr = buffer->cb[i];
  182                 if (ptr->data) {
  183                     cb_destroy_data(ptr, buffer->destroy_buffer_data);
  184                     ptr->data = NULL;
  185                     GF_FREE(ptr);
  186                 }
  187             }
  188             GF_FREE(buffer->cb);
  189         }
  190         pthread_mutex_destroy(&buffer->lock);
  191         GF_FREE(buffer);
  192     }
  193 }