LCOV - code coverage report
Current view: top level - spdk/lib/notify - notify.c (source / functions) Hit Total Coverage
Test: Combined Lines: 40 48 83.3 %
Date: 2024-07-15 15:19:34 Functions: 5 5 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 27 44 61.4 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2018 Intel Corporation.
       3                 :            :  *   All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include <sys/queue.h>
       7                 :            : 
       8                 :            : #include "spdk/stdinc.h"
       9                 :            : #include "spdk/util.h"
      10                 :            : #include "spdk/queue.h"
      11                 :            : #include "spdk/string.h"
      12                 :            : #include "spdk/log.h"
      13                 :            : 
      14                 :            : #include "spdk/notify.h"
      15                 :            : 
      16                 :            : #define SPDK_NOTIFY_MAX_EVENTS  1024
      17                 :            : 
      18                 :            : struct spdk_notify_type {
      19                 :            :         char name[SPDK_NOTIFY_MAX_NAME_SIZE];
      20                 :            :         TAILQ_ENTRY(spdk_notify_type) tailq;
      21                 :            : };
      22                 :            : 
      23                 :            : pthread_mutex_t g_events_lock = PTHREAD_MUTEX_INITIALIZER;
      24                 :            : static struct spdk_notify_event g_events[SPDK_NOTIFY_MAX_EVENTS];
      25                 :            : static uint64_t g_events_head;
      26                 :            : 
      27                 :            : static TAILQ_HEAD(, spdk_notify_type) g_notify_types = TAILQ_HEAD_INITIALIZER(g_notify_types);
      28                 :            : 
      29                 :            : struct spdk_notify_type *
      30                 :       4446 : spdk_notify_type_register(const char *type)
      31                 :            : {
      32                 :       4446 :         struct spdk_notify_type *it = NULL;
      33                 :            : 
      34         [ -  + ]:       4446 :         if (!type) {
      35                 :          0 :                 SPDK_ERRLOG("Invalid notification type %p\n", type);
      36                 :          0 :                 return NULL;
      37   [ +  -  -  +  :       4446 :         } else if (!type[0] || strlen(type) >= SPDK_NOTIFY_MAX_NAME_SIZE) {
                   -  + ]
      38                 :          0 :                 SPDK_ERRLOG("Notification type '%s' too short or too long\n", type);
      39                 :          0 :                 return NULL;
      40                 :            :         }
      41                 :            : 
      42                 :       4446 :         pthread_mutex_lock(&g_events_lock);
      43         [ +  + ]:       6669 :         TAILQ_FOREACH(it, &g_notify_types, tailq) {
      44   [ +  +  -  +  :       2337 :                 if (strcmp(type, it->name) == 0) {
                   +  + ]
      45                 :        114 :                         SPDK_NOTICELOG("Notification type '%s' already registered.\n", type);
      46                 :        114 :                         goto out;
      47                 :            :                 }
      48                 :            :         }
      49                 :            : 
      50                 :       4332 :         it = calloc(1, sizeof(*it));
      51         [ -  + ]:       4332 :         if (it == NULL) {
      52                 :          0 :                 goto out;
      53                 :            :         }
      54                 :            : 
      55                 :       4332 :         snprintf(it->name, sizeof(it->name), "%s", type);
      56                 :       4332 :         TAILQ_INSERT_TAIL(&g_notify_types, it, tailq);
      57                 :            : 
      58                 :       4446 : out:
      59                 :       4446 :         pthread_mutex_unlock(&g_events_lock);
      60                 :       4446 :         return it;
      61                 :            : }
      62                 :            : 
      63                 :            : const char *
      64                 :         34 : spdk_notify_type_get_name(const struct spdk_notify_type *type)
      65                 :            : {
      66                 :         34 :         return type->name;
      67                 :            : }
      68                 :            : 
      69                 :            : 
      70                 :            : void
      71                 :         13 : spdk_notify_foreach_type(spdk_notify_foreach_type_cb cb, void *ctx)
      72                 :            : {
      73                 :            :         struct spdk_notify_type *it;
      74                 :            : 
      75         [ -  + ]:         13 :         pthread_mutex_lock(&g_events_lock);
      76         [ +  + ]:         39 :         TAILQ_FOREACH(it, &g_notify_types, tailq) {
      77         [ -  + ]:         26 :                 if (cb(it, ctx)) {
      78                 :          0 :                         break;
      79                 :            :                 }
      80                 :            :         }
      81         [ -  + ]:         13 :         pthread_mutex_unlock(&g_events_lock);
      82                 :         13 : }
      83                 :            : 
      84                 :            : uint64_t
      85                 :      16078 : spdk_notify_send(const char *type, const char *ctx)
      86                 :            : {
      87                 :            :         uint64_t head;
      88                 :            :         struct spdk_notify_event *ev;
      89                 :            : 
      90         [ -  + ]:      16078 :         pthread_mutex_lock(&g_events_lock);
      91                 :      16078 :         head = g_events_head;
      92                 :      16078 :         g_events_head++;
      93                 :            : 
      94                 :      16078 :         ev = &g_events[head % SPDK_NOTIFY_MAX_EVENTS];
      95                 :      16078 :         spdk_strcpy_pad(ev->type, type, sizeof(ev->type), '\0');
      96                 :      16078 :         spdk_strcpy_pad(ev->ctx, ctx, sizeof(ev->ctx), '\0');
      97         [ -  + ]:      16078 :         pthread_mutex_unlock(&g_events_lock);
      98                 :            : 
      99                 :      16078 :         return head;
     100                 :            : }
     101                 :            : 
     102                 :            : uint64_t
     103                 :         45 : spdk_notify_foreach_event(uint64_t start_idx, uint64_t max,
     104                 :            :                           spdk_notify_foreach_event_cb cb_fn, void *ctx)
     105                 :            : {
     106                 :            :         uint64_t i;
     107                 :            : 
     108         [ -  + ]:         45 :         pthread_mutex_lock(&g_events_lock);
     109                 :            : 
     110   [ -  +  -  - ]:         45 :         if (g_events_head > SPDK_NOTIFY_MAX_EVENTS && start_idx < g_events_head - SPDK_NOTIFY_MAX_EVENTS) {
     111                 :          0 :                 start_idx = g_events_head - SPDK_NOTIFY_MAX_EVENTS;
     112                 :            :         }
     113                 :            : 
     114   [ +  +  +  + ]:        160 :         for (i = 0; start_idx < g_events_head && i < max; start_idx++, i++) {
     115         [ -  + ]:        115 :                 if (cb_fn(start_idx, &g_events[start_idx % SPDK_NOTIFY_MAX_EVENTS], ctx)) {
     116                 :          0 :                         break;
     117                 :            :                 }
     118                 :            :         }
     119         [ -  + ]:         45 :         pthread_mutex_unlock(&g_events_lock);
     120                 :            : 
     121                 :         45 :         return i;
     122                 :            : }

Generated by: LCOV version 1.14