LCOV - code coverage report
Current view: top level - lib/notify - notify.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 32 48 66.7 %
Date: 2024-12-15 03:48:28 Functions: 4 5 80.0 %

          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             : static 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           4 : spdk_notify_type_register(const char *type)
      31             : {
      32           4 :         struct spdk_notify_type *it = NULL;
      33             : 
      34           4 :         if (!type) {
      35           0 :                 SPDK_ERRLOG("Invalid notification type %p\n", type);
      36           0 :                 return NULL;
      37           4 :         } 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           4 :         pthread_mutex_lock(&g_events_lock);
      43           6 :         TAILQ_FOREACH(it, &g_notify_types, tailq) {
      44           2 :                 if (strcmp(type, it->name) == 0) {
      45           0 :                         SPDK_NOTICELOG("Notification type '%s' already registered.\n", type);
      46           0 :                         goto out;
      47             :                 }
      48             :         }
      49             : 
      50           4 :         it = calloc(1, sizeof(*it));
      51           4 :         if (it == NULL) {
      52           0 :                 goto out;
      53             :         }
      54             : 
      55           4 :         snprintf(it->name, sizeof(it->name), "%s", type);
      56           4 :         TAILQ_INSERT_TAIL(&g_notify_types, it, tailq);
      57             : 
      58           4 : out:
      59           4 :         pthread_mutex_unlock(&g_events_lock);
      60           4 :         return it;
      61             : }
      62             : 
      63             : const char *
      64           2 : spdk_notify_type_get_name(const struct spdk_notify_type *type)
      65             : {
      66           2 :         return type->name;
      67             : }
      68             : 
      69             : 
      70             : void
      71           0 : spdk_notify_foreach_type(spdk_notify_foreach_type_cb cb, void *ctx)
      72             : {
      73             :         struct spdk_notify_type *it;
      74             : 
      75           0 :         pthread_mutex_lock(&g_events_lock);
      76           0 :         TAILQ_FOREACH(it, &g_notify_types, tailq) {
      77           0 :                 if (cb(it, ctx)) {
      78           0 :                         break;
      79             :                 }
      80             :         }
      81           0 :         pthread_mutex_unlock(&g_events_lock);
      82           0 : }
      83             : 
      84             : uint64_t
      85          80 : spdk_notify_send(const char *type, const char *ctx)
      86             : {
      87             :         uint64_t head;
      88             :         struct spdk_notify_event *ev;
      89             : 
      90          80 :         pthread_mutex_lock(&g_events_lock);
      91          80 :         head = g_events_head;
      92          80 :         g_events_head++;
      93             : 
      94          80 :         ev = &g_events[head % SPDK_NOTIFY_MAX_EVENTS];
      95          80 :         spdk_strcpy_pad(ev->type, type, sizeof(ev->type), '\0');
      96          80 :         spdk_strcpy_pad(ev->ctx, ctx, sizeof(ev->ctx), '\0');
      97          80 :         pthread_mutex_unlock(&g_events_lock);
      98             : 
      99          80 :         return head;
     100             : }
     101             : 
     102             : uint64_t
     103           3 : 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           3 :         pthread_mutex_lock(&g_events_lock);
     109             : 
     110           3 :         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           5 :         for (i = 0; start_idx < g_events_head && i < max; start_idx++, i++) {
     115           2 :                 if (cb_fn(start_idx, &g_events[start_idx % SPDK_NOTIFY_MAX_EVENTS], ctx)) {
     116           0 :                         break;
     117             :                 }
     118             :         }
     119           3 :         pthread_mutex_unlock(&g_events_lock);
     120             : 
     121           3 :         return i;
     122             : }

Generated by: LCOV version 1.15