LCOV - code coverage report
Current view: top level - spdk/test/unit/lib/thread/iobuf.c - iobuf_ut.c (source / functions) Hit Total Coverage
Test: Combined Lines: 405 405 100.0 %
Date: 2024-12-17 07:41:55 Functions: 6 6 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 841 1668 50.4 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2023 Intel Corporation. All rights reserved.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "spdk_internal/cunit.h"
       6                 :            : 
       7                 :            : #include "common/lib/ut_multithread.c"
       8                 :            : #include "unit/lib/json_mock.c"
       9                 :            : 
      10                 :            : #include "spdk/config.h"
      11                 :            : #include "spdk/thread.h"
      12                 :            : 
      13                 :            : #include "thread/iobuf.c"
      14                 :            : 
      15                 :            : struct ut_iobuf_entry {
      16                 :            :         struct spdk_iobuf_channel       *ioch;
      17                 :            :         struct spdk_iobuf_entry         iobuf;
      18                 :            :         void                            *buf;
      19                 :            :         uint32_t                        thread_id;
      20                 :            :         const char                      *module;
      21                 :            : };
      22                 :            : 
      23                 :            : static void
      24                 :         12 : ut_iobuf_finish_cb(void *ctx)
      25                 :            : {
      26         [ +  - ]:         12 :         *(int *)ctx = 1;
      27                 :         12 : }
      28                 :            : 
      29                 :            : static void
      30                 :         72 : ut_iobuf_get_buf_cb(struct spdk_iobuf_entry *entry, void *buf)
      31                 :            : {
      32                 :         72 :         struct ut_iobuf_entry *ut_entry = SPDK_CONTAINEROF(entry, struct ut_iobuf_entry, iobuf);
      33                 :            : 
      34   [ +  -  +  - ]:         72 :         ut_entry->buf = buf;
      35                 :         72 : }
      36                 :            : 
      37                 :            : static int
      38                 :         48 : ut_iobuf_foreach_cb(struct spdk_iobuf_channel *ch, struct spdk_iobuf_entry *entry, void *cb_arg)
      39                 :            : {
      40                 :         48 :         struct ut_iobuf_entry *ut_entry = SPDK_CONTAINEROF(entry, struct ut_iobuf_entry, iobuf);
      41                 :            : 
      42   [ +  -  +  - ]:         48 :         ut_entry->buf = cb_arg;
      43                 :            : 
      44                 :         48 :         return 0;
      45                 :          8 : }
      46                 :            : 
      47                 :            : #define SMALL_BUFSIZE 4096
      48                 :            : #define LARGE_BUFSIZE 8192
      49                 :            : 
      50                 :            : static void
      51                 :          6 : iobuf(void)
      52                 :            : {
      53                 :          6 :         struct spdk_iobuf_opts opts = {
      54                 :            :                 .small_pool_count = 2,
      55                 :            :                 .large_pool_count = 2,
      56                 :            :                 .small_bufsize = SMALL_BUFSIZE,
      57                 :            :                 .large_bufsize = LARGE_BUFSIZE,
      58                 :            :         };
      59                 :          1 :         struct ut_iobuf_entry *entry;
      60                 :          5 :         struct spdk_iobuf_channel mod0_ch[2], mod1_ch[2];
      61                 :          6 :         struct ut_iobuf_entry mod0_entries[] = {
      62                 :            :                 { .thread_id = 0, .module = "ut_module0", },
      63                 :            :                 { .thread_id = 0, .module = "ut_module0", },
      64                 :            :                 { .thread_id = 0, .module = "ut_module0", },
      65                 :            :                 { .thread_id = 0, .module = "ut_module0", },
      66                 :            :                 { .thread_id = 1, .module = "ut_module0", },
      67                 :            :                 { .thread_id = 1, .module = "ut_module0", },
      68                 :            :                 { .thread_id = 1, .module = "ut_module0", },
      69                 :            :                 { .thread_id = 1, .module = "ut_module0", },
      70                 :            :         };
      71                 :          6 :         struct ut_iobuf_entry mod1_entries[] = {
      72                 :            :                 { .thread_id = 0, .module = "ut_module1", },
      73                 :            :                 { .thread_id = 0, .module = "ut_module1", },
      74                 :            :                 { .thread_id = 0, .module = "ut_module1", },
      75                 :            :                 { .thread_id = 0, .module = "ut_module1", },
      76                 :            :                 { .thread_id = 1, .module = "ut_module1", },
      77                 :            :                 { .thread_id = 1, .module = "ut_module1", },
      78                 :            :                 { .thread_id = 1, .module = "ut_module1", },
      79                 :            :                 { .thread_id = 1, .module = "ut_module1", },
      80                 :            :         };
      81                 :          6 :         int rc, finish = 0;
      82                 :          1 :         uint32_t i;
      83                 :            : 
      84                 :          6 :         allocate_cores(2);
      85                 :          6 :         allocate_threads(2);
      86                 :            : 
      87                 :          6 :         set_thread(0);
      88                 :            : 
      89                 :            :         /* We cannot use spdk_iobuf_set_opts(), as it won't allow us to use such small pools */
      90                 :          6 :         g_iobuf.opts = opts;
      91                 :          6 :         rc = spdk_iobuf_initialize();
      92                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
      93                 :            : 
      94                 :          6 :         rc = spdk_iobuf_register_module("ut_module0");
      95                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
      96                 :            : 
      97                 :          6 :         rc = spdk_iobuf_register_module("ut_module1");
      98                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
      99                 :            : 
     100                 :          6 :         set_thread(0);
     101   [ +  -  +  - ]:          6 :         rc = spdk_iobuf_channel_init(&mod0_ch[0], "ut_module0", 0, 0);
     102                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     103                 :          6 :         set_thread(1);
     104   [ +  -  +  - ]:          6 :         rc = spdk_iobuf_channel_init(&mod0_ch[1], "ut_module0", 0, 0);
     105                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     106         [ +  + ]:         54 :         for (i = 0; i < SPDK_COUNTOF(mod0_entries); ++i) {
     107   [ +  -  +  -  :         48 :                 mod0_entries[i].ioch = &mod0_ch[mod0_entries[i].thread_id];
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     108                 :          8 :         }
     109                 :          6 :         set_thread(0);
     110   [ +  -  +  - ]:          6 :         rc = spdk_iobuf_channel_init(&mod1_ch[0], "ut_module1", 0, 0);
     111                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     112                 :          6 :         set_thread(1);
     113   [ +  -  +  - ]:          6 :         rc = spdk_iobuf_channel_init(&mod1_ch[1], "ut_module1", 0, 0);
     114                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     115         [ +  + ]:         54 :         for (i = 0; i < SPDK_COUNTOF(mod1_entries); ++i) {
     116   [ +  -  +  -  :         48 :                 mod1_entries[i].ioch = &mod1_ch[mod1_entries[i].thread_id];
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     117                 :          8 :         }
     118                 :            : 
     119                 :            :         /* First check that it's possible to retrieve the whole pools from a single module */
     120                 :          6 :         set_thread(0);
     121   [ +  -  +  - ]:          6 :         entry = &mod0_entries[0];
     122   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     123   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     124   [ +  -  +  - ]:          6 :         entry = &mod0_entries[1];
     125   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     126   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     127                 :            :         /* The next two should be put onto the large buf wait queue */
     128   [ +  -  +  - ]:          6 :         entry = &mod0_entries[2];
     129   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     130   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     131   [ +  -  +  - ]:          6 :         entry = &mod0_entries[3];
     132   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     133   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     134                 :            :         /* Pick the two next buffers from the small pool */
     135                 :          6 :         set_thread(1);
     136   [ +  -  +  - ]:          6 :         entry = &mod0_entries[4];
     137   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     138   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     139   [ +  -  +  - ]:          6 :         entry = &mod0_entries[5];
     140   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     141   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     142                 :            :         /* The next two should be put onto the small buf wait queue */
     143   [ +  -  +  - ]:          6 :         entry = &mod0_entries[6];
     144   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     145   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     146   [ +  -  +  - ]:          6 :         entry = &mod0_entries[7];
     147   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     148   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     149                 :            : 
     150                 :            :         /* Now return one of the large buffers to the pool and verify that the first request's
     151                 :            :          * (entry 2) callback was executed and it was removed from the wait queue.
     152                 :            :          */
     153                 :          6 :         set_thread(0);
     154   [ +  -  +  - ]:          6 :         entry = &mod0_entries[0];
     155   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, LARGE_BUFSIZE);
             +  -  +  - ]
     156   [ +  -  +  - ]:          6 :         entry = &mod0_entries[2];
     157   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     158   [ +  -  +  - ]:          6 :         entry = &mod0_entries[3];
     159   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     160                 :            : 
     161                 :            :         /* Return the second buffer and check that the other request is satisfied */
     162   [ +  -  +  - ]:          6 :         entry = &mod0_entries[1];
     163   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, LARGE_BUFSIZE);
             +  -  +  - ]
     164   [ +  -  +  - ]:          6 :         entry = &mod0_entries[3];
     165   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     166                 :            : 
     167                 :            :         /* Return the remaining two buffers */
     168   [ +  -  +  - ]:          6 :         entry = &mod0_entries[2];
     169   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, LARGE_BUFSIZE);
             +  -  +  - ]
     170   [ +  -  +  - ]:          6 :         entry = &mod0_entries[3];
     171   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, LARGE_BUFSIZE);
             +  -  +  - ]
     172                 :            : 
     173                 :            :         /* Check that it didn't change the requests waiting for the small buffers */
     174   [ +  -  +  - ]:          6 :         entry = &mod0_entries[6];
     175   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     176   [ +  -  +  - ]:          6 :         entry = &mod0_entries[7];
     177   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     178                 :            : 
     179                 :            :         /* Do the same test as above, this time using the small pool */
     180                 :          6 :         set_thread(1);
     181   [ +  -  +  - ]:          6 :         entry = &mod0_entries[4];
     182   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, SMALL_BUFSIZE);
             +  -  +  - ]
     183   [ +  -  +  - ]:          6 :         entry = &mod0_entries[6];
     184   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     185   [ +  -  +  - ]:          6 :         entry = &mod0_entries[7];
     186   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     187                 :            : 
     188                 :            :         /* Return the second buffer and check that the other request is satisfied */
     189   [ +  -  +  - ]:          6 :         entry = &mod0_entries[5];
     190   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, SMALL_BUFSIZE);
             +  -  +  - ]
     191   [ +  -  +  - ]:          6 :         entry = &mod0_entries[7];
     192   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     193                 :            : 
     194                 :            :         /* Return the remaining two buffers */
     195   [ +  -  +  - ]:          6 :         entry = &mod0_entries[6];
     196   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, SMALL_BUFSIZE);
             +  -  +  - ]
     197   [ +  -  +  - ]:          6 :         entry = &mod0_entries[7];
     198   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, SMALL_BUFSIZE);
             +  -  +  - ]
     199                 :            : 
     200                 :            :         /* Now check requesting buffers from different modules - first request all of them from one
     201                 :            :          * module, starting from the large pool
     202                 :            :          */
     203                 :          6 :         set_thread(0);
     204   [ +  -  +  - ]:          6 :         entry = &mod0_entries[0];
     205   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     206   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     207   [ +  -  +  - ]:          6 :         entry = &mod0_entries[1];
     208   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     209   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     210                 :            :         /* Request all of them from the small one */
     211                 :          6 :         set_thread(1);
     212   [ +  -  +  - ]:          6 :         entry = &mod0_entries[4];
     213   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     214   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     215   [ +  -  +  - ]:          6 :         entry = &mod0_entries[5];
     216   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     217   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     218                 :            : 
     219                 :            :         /* Request one buffer per module from each pool  */
     220                 :          6 :         set_thread(0);
     221   [ +  -  +  - ]:          6 :         entry = &mod1_entries[0];
     222   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     223   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     224   [ +  -  +  - ]:          6 :         entry = &mod0_entries[3];
     225   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     226   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     227                 :            :         /* Change the order from the small pool and request a buffer from mod0 first */
     228                 :          6 :         set_thread(1);
     229   [ +  -  +  - ]:          6 :         entry = &mod0_entries[6];
     230   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     231   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     232   [ +  -  +  - ]:          6 :         entry = &mod1_entries[4];
     233   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     234   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     235                 :            : 
     236                 :            :         /* Now return one buffer to the large pool */
     237                 :          6 :         set_thread(0);
     238   [ +  -  +  - ]:          6 :         entry = &mod0_entries[0];
     239   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, LARGE_BUFSIZE);
             +  -  +  - ]
     240                 :            : 
     241                 :            :         /* Make sure the request from mod1 got the buffer, as it was the first to request it */
     242   [ +  -  +  - ]:          6 :         entry = &mod1_entries[0];
     243   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     244   [ +  -  +  - ]:          6 :         entry = &mod0_entries[3];
     245   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     246                 :            : 
     247                 :            :         /* Return second buffer to the large pool and check the outstanding mod0 request */
     248   [ +  -  +  - ]:          6 :         entry = &mod0_entries[1];
     249   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, LARGE_BUFSIZE);
             +  -  +  - ]
     250   [ +  -  +  - ]:          6 :         entry = &mod0_entries[3];
     251   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     252                 :            : 
     253                 :            :         /* Return the remaining two buffers */
     254   [ +  -  +  - ]:          6 :         entry = &mod1_entries[0];
     255   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, LARGE_BUFSIZE);
             +  -  +  - ]
     256   [ +  -  +  - ]:          6 :         entry = &mod0_entries[3];
     257   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, LARGE_BUFSIZE);
             +  -  +  - ]
     258                 :            : 
     259                 :            :         /* Check the same for the small pool, but this time the order of the request is reversed
     260                 :            :          * (mod0 before mod1)
     261                 :            :          */
     262                 :          6 :         set_thread(1);
     263   [ +  -  +  - ]:          6 :         entry = &mod0_entries[4];
     264   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, SMALL_BUFSIZE);
             +  -  +  - ]
     265   [ +  -  +  - ]:          6 :         entry = &mod0_entries[6];
     266   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     267                 :            :         /* mod1 request was second in this case, so it still needs to wait */
     268   [ +  -  +  - ]:          6 :         entry = &mod1_entries[4];
     269   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     270                 :            : 
     271                 :            :         /* Return the second requested buffer */
     272   [ +  -  +  - ]:          6 :         entry = &mod0_entries[5];
     273   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, SMALL_BUFSIZE);
             +  -  +  - ]
     274   [ +  -  +  - ]:          6 :         entry = &mod1_entries[4];
     275   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     276                 :            : 
     277                 :            :         /* Return the remaining two buffers */
     278   [ +  -  +  - ]:          6 :         entry = &mod0_entries[6];
     279   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, SMALL_BUFSIZE);
             +  -  +  - ]
     280   [ +  -  +  - ]:          6 :         entry = &mod1_entries[4];
     281   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, SMALL_BUFSIZE);
             +  -  +  - ]
     282                 :            : 
     283                 :            :         /* Request buffers to make the pools empty */
     284                 :          6 :         set_thread(0);
     285   [ +  -  +  - ]:          6 :         entry = &mod0_entries[0];
     286   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     287   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     288   [ +  -  +  - ]:          6 :         entry = &mod1_entries[0];
     289   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     290   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     291   [ +  -  +  - ]:          6 :         entry = &mod0_entries[1];
     292   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     293   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     294   [ +  -  +  - ]:          6 :         entry = &mod1_entries[1];
     295   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     296   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     297                 :            : 
     298                 :            :         /* Queue more requests from both modules */
     299   [ +  -  +  - ]:          6 :         entry = &mod0_entries[2];
     300   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     301   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     302   [ +  -  +  - ]:          6 :         entry = &mod1_entries[2];
     303   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     304   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     305   [ +  -  +  - ]:          6 :         entry = &mod1_entries[3];
     306   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     307   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     308   [ +  -  +  - ]:          6 :         entry = &mod0_entries[3];
     309   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     310   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     311                 :            : 
     312                 :            :         /* Check that abort correctly remove an entry from the queue */
     313   [ +  -  +  - ]:          6 :         entry = &mod0_entries[2];
     314   [ +  -  +  -  :          6 :         spdk_iobuf_entry_abort(entry->ioch, &entry->iobuf, LARGE_BUFSIZE);
                   +  - ]
     315   [ +  -  +  - ]:          6 :         entry = &mod1_entries[3];
     316   [ +  -  +  -  :          6 :         spdk_iobuf_entry_abort(entry->ioch, &entry->iobuf, SMALL_BUFSIZE);
                   +  - ]
     317                 :            : 
     318   [ +  -  +  - ]:          6 :         entry = &mod0_entries[0];
     319   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, LARGE_BUFSIZE);
             +  -  +  - ]
     320   [ +  -  +  -  :          6 :         CU_ASSERT_PTR_NOT_NULL(mod1_entries[2].buf);
             +  -  +  - ]
     321   [ +  -  +  - ]:          6 :         entry = &mod0_entries[1];
     322   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, SMALL_BUFSIZE);
             +  -  +  - ]
     323   [ +  -  +  -  :          6 :         CU_ASSERT_PTR_NOT_NULL(mod0_entries[3].buf);
             +  -  +  - ]
     324                 :            : 
     325                 :            :         /* Clean up */
     326   [ +  -  +  - ]:          6 :         entry = &mod1_entries[0];
     327   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, LARGE_BUFSIZE);
             +  -  +  - ]
     328   [ +  -  +  - ]:          6 :         entry = &mod1_entries[2];
     329   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, LARGE_BUFSIZE);
             +  -  +  - ]
     330   [ +  -  +  - ]:          6 :         entry = &mod1_entries[1];
     331   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, SMALL_BUFSIZE);
             +  -  +  - ]
     332   [ +  -  +  - ]:          6 :         entry = &mod0_entries[3];
     333   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, SMALL_BUFSIZE);
             +  -  +  - ]
     334                 :            : 
     335                 :            :         /* Request buffers to make the pools empty */
     336                 :          6 :         set_thread(0);
     337   [ +  -  +  - ]:          6 :         entry = &mod0_entries[0];
     338   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     339   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     340   [ +  -  +  - ]:          6 :         entry = &mod1_entries[0];
     341   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     342   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     343   [ +  -  +  - ]:          6 :         entry = &mod0_entries[1];
     344   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     345   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     346   [ +  -  +  - ]:          6 :         entry = &mod1_entries[1];
     347   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     348   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     349                 :            : 
     350                 :            :         /* Request a buffer from each queue and each module on thread 0 */
     351                 :          6 :         set_thread(0);
     352   [ +  -  +  - ]:          6 :         entry = &mod0_entries[2];
     353   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     354   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     355   [ +  -  +  - ]:          6 :         entry = &mod1_entries[2];
     356   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     357   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     358   [ +  -  +  - ]:          6 :         entry = &mod0_entries[3];
     359   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     360   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     361   [ +  -  +  - ]:          6 :         entry = &mod1_entries[3];
     362   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     363   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     364                 :            : 
     365                 :            :         /* Do the same on thread 1 */
     366                 :          6 :         set_thread(1);
     367   [ +  -  +  - ]:          6 :         entry = &mod0_entries[6];
     368   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     369   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     370   [ +  -  +  - ]:          6 :         entry = &mod1_entries[6];
     371   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, LARGE_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     372   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     373   [ +  -  +  - ]:          6 :         entry = &mod0_entries[7];
     374   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     375   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     376   [ +  -  +  - ]:          6 :         entry = &mod1_entries[7];
     377   [ +  -  +  -  :          6 :         entry->buf = spdk_iobuf_get(entry->ioch, SMALL_BUFSIZE, &entry->iobuf, ut_iobuf_get_buf_cb);
          +  -  +  -  +  
                      - ]
     378   [ +  -  +  - ]:          6 :         CU_ASSERT_PTR_NULL(entry->buf);
     379                 :            : 
     380                 :            :         /* Now do the foreach and check that correct entries are iterated over by assigning their
     381                 :            :          * ->buf pointers to different values.
     382                 :            :          */
     383                 :          6 :         set_thread(0);
     384   [ +  -  +  -  :          6 :         rc = spdk_iobuf_for_each_entry(&mod0_ch[0], &mod0_ch[0].large,
             +  -  +  - ]
     385                 :            :                                        ut_iobuf_foreach_cb, (void *)0xdeadbeef);
     386                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     387   [ +  -  +  -  :          6 :         rc = spdk_iobuf_for_each_entry(&mod0_ch[0], &mod0_ch[0].small,
             +  -  +  - ]
     388                 :            :                                        ut_iobuf_foreach_cb, (void *)0xbeefdead);
     389                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     390   [ +  -  +  -  :          6 :         rc = spdk_iobuf_for_each_entry(&mod1_ch[0], &mod1_ch[0].large,
             +  -  +  - ]
     391                 :            :                                        ut_iobuf_foreach_cb, (void *)0xfeedbeef);
     392                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     393   [ +  -  +  -  :          6 :         rc = spdk_iobuf_for_each_entry(&mod1_ch[0], &mod1_ch[0].small,
             +  -  +  - ]
     394                 :            :                                        ut_iobuf_foreach_cb, (void *)0xbeeffeed);
     395                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     396                 :          6 :         set_thread(1);
     397   [ +  -  +  -  :          6 :         rc = spdk_iobuf_for_each_entry(&mod0_ch[1], &mod0_ch[1].large,
          +  -  +  -  +  
                      - ]
     398                 :            :                                        ut_iobuf_foreach_cb, (void *)0xcafebabe);
     399                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     400   [ +  -  +  -  :          6 :         rc = spdk_iobuf_for_each_entry(&mod0_ch[1], &mod0_ch[1].small,
          +  -  +  -  +  
                      - ]
     401                 :            :                                        ut_iobuf_foreach_cb, (void *)0xbabecafe);
     402                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     403   [ +  -  +  -  :          6 :         rc = spdk_iobuf_for_each_entry(&mod1_ch[1], &mod1_ch[1].large,
          +  -  +  -  +  
                      - ]
     404                 :            :                                        ut_iobuf_foreach_cb, (void *)0xbeefcafe);
     405                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     406   [ +  -  +  -  :          6 :         rc = spdk_iobuf_for_each_entry(&mod1_ch[1], &mod1_ch[1].small,
          +  -  +  -  +  
                      - ]
     407                 :            :                                        ut_iobuf_foreach_cb, (void *)0xcafebeef);
     408                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     409                 :            : 
     410                 :            :         /* thread 0 */
     411   [ +  -  +  -  :          6 :         CU_ASSERT_PTR_EQUAL(mod0_entries[2].buf, (void *)0xdeadbeef);
             +  -  +  - ]
     412   [ +  -  +  -  :          6 :         CU_ASSERT_PTR_EQUAL(mod0_entries[3].buf, (void *)0xbeefdead);
             +  -  +  - ]
     413   [ +  -  +  -  :          6 :         CU_ASSERT_PTR_EQUAL(mod1_entries[2].buf, (void *)0xfeedbeef);
             +  -  +  - ]
     414   [ +  -  +  -  :          6 :         CU_ASSERT_PTR_EQUAL(mod1_entries[3].buf, (void *)0xbeeffeed);
             +  -  +  - ]
     415                 :            :         /* thread 1 */
     416   [ +  -  +  -  :          6 :         CU_ASSERT_PTR_EQUAL(mod0_entries[6].buf, (void *)0xcafebabe);
             +  -  +  - ]
     417   [ +  -  +  -  :          6 :         CU_ASSERT_PTR_EQUAL(mod0_entries[7].buf, (void *)0xbabecafe);
             +  -  +  - ]
     418   [ +  -  +  -  :          6 :         CU_ASSERT_PTR_EQUAL(mod1_entries[6].buf, (void *)0xbeefcafe);
             +  -  +  - ]
     419   [ +  -  +  -  :          6 :         CU_ASSERT_PTR_EQUAL(mod1_entries[7].buf, (void *)0xcafebeef);
             +  -  +  - ]
     420                 :            : 
     421                 :            :         /* Clean everything up */
     422                 :          6 :         set_thread(0);
     423   [ +  -  +  - ]:          6 :         entry = &mod0_entries[2];
     424   [ +  -  +  -  :          6 :         spdk_iobuf_entry_abort(entry->ioch, &entry->iobuf, LARGE_BUFSIZE);
                   +  - ]
     425   [ +  -  +  - ]:          6 :         entry = &mod0_entries[3];
     426   [ +  -  +  -  :          6 :         spdk_iobuf_entry_abort(entry->ioch, &entry->iobuf, SMALL_BUFSIZE);
                   +  - ]
     427   [ +  -  +  - ]:          6 :         entry = &mod1_entries[2];
     428   [ +  -  +  -  :          6 :         spdk_iobuf_entry_abort(entry->ioch, &entry->iobuf, LARGE_BUFSIZE);
                   +  - ]
     429   [ +  -  +  - ]:          6 :         entry = &mod1_entries[3];
     430   [ +  -  +  -  :          6 :         spdk_iobuf_entry_abort(entry->ioch, &entry->iobuf, SMALL_BUFSIZE);
                   +  - ]
     431                 :            : 
     432   [ +  -  +  - ]:          6 :         entry = &mod0_entries[0];
     433   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, LARGE_BUFSIZE);
             +  -  +  - ]
     434   [ +  -  +  - ]:          6 :         entry = &mod1_entries[0];
     435   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, LARGE_BUFSIZE);
             +  -  +  - ]
     436   [ +  -  +  - ]:          6 :         entry = &mod0_entries[1];
     437   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, SMALL_BUFSIZE);
             +  -  +  - ]
     438   [ +  -  +  - ]:          6 :         entry = &mod1_entries[1];
     439   [ +  -  +  -  :          6 :         spdk_iobuf_put(entry->ioch, entry->buf, SMALL_BUFSIZE);
             +  -  +  - ]
     440                 :            : 
     441                 :          6 :         set_thread(1);
     442   [ +  -  +  - ]:          6 :         entry = &mod0_entries[6];
     443   [ +  -  +  -  :          6 :         spdk_iobuf_entry_abort(entry->ioch, &entry->iobuf, LARGE_BUFSIZE);
                   +  - ]
     444   [ +  -  +  - ]:          6 :         entry = &mod0_entries[7];
     445   [ +  -  +  -  :          6 :         spdk_iobuf_entry_abort(entry->ioch, &entry->iobuf, SMALL_BUFSIZE);
                   +  - ]
     446   [ +  -  +  - ]:          6 :         entry = &mod1_entries[6];
     447   [ +  -  +  -  :          6 :         spdk_iobuf_entry_abort(entry->ioch, &entry->iobuf, LARGE_BUFSIZE);
                   +  - ]
     448   [ +  -  +  - ]:          6 :         entry = &mod1_entries[7];
     449   [ +  -  +  -  :          6 :         spdk_iobuf_entry_abort(entry->ioch, &entry->iobuf, SMALL_BUFSIZE);
                   +  - ]
     450                 :            : 
     451                 :          6 :         set_thread(0);
     452   [ +  -  +  - ]:          6 :         spdk_iobuf_channel_fini(&mod0_ch[0]);
     453                 :          6 :         poll_threads();
     454   [ +  -  +  - ]:          6 :         spdk_iobuf_channel_fini(&mod1_ch[0]);
     455                 :          6 :         poll_threads();
     456                 :          6 :         set_thread(1);
     457   [ +  -  +  - ]:          6 :         spdk_iobuf_channel_fini(&mod0_ch[1]);
     458                 :          6 :         poll_threads();
     459   [ +  -  +  - ]:          6 :         spdk_iobuf_channel_fini(&mod1_ch[1]);
     460                 :          6 :         poll_threads();
     461                 :            : 
     462                 :          6 :         spdk_iobuf_finish(ut_iobuf_finish_cb, &finish);
     463                 :          6 :         poll_threads();
     464                 :            : 
     465                 :          6 :         CU_ASSERT_EQUAL(finish, 1);
     466                 :            : 
     467                 :          6 :         free_threads();
     468                 :          6 :         free_cores();
     469                 :          6 : }
     470                 :            : 
     471                 :            : static void
     472                 :          6 : iobuf_cache(void)
     473                 :            : {
     474                 :          6 :         struct spdk_iobuf_opts opts = {
     475                 :            :                 .small_pool_count = 4,
     476                 :            :                 .large_pool_count = 4,
     477                 :            :                 .small_bufsize = SMALL_BUFSIZE,
     478                 :            :                 .large_bufsize = LARGE_BUFSIZE,
     479                 :            :         };
     480                 :          5 :         struct spdk_iobuf_channel iobuf_ch[2];
     481                 :          1 :         struct ut_iobuf_entry *entry;
     482                 :          6 :         struct ut_iobuf_entry mod0_entries[] = {
     483                 :            :                 { .thread_id = 0, .module = "ut_module0", },
     484                 :            :                 { .thread_id = 0, .module = "ut_module0", },
     485                 :            :                 { .thread_id = 0, .module = "ut_module0", },
     486                 :            :                 { .thread_id = 0, .module = "ut_module0", },
     487                 :            :         };
     488                 :          6 :         struct ut_iobuf_entry mod1_entries[] = {
     489                 :            :                 { .thread_id = 0, .module = "ut_module1", },
     490                 :            :                 { .thread_id = 0, .module = "ut_module1", },
     491                 :            :         };
     492                 :          6 :         int rc, finish = 0;
     493                 :          1 :         uint32_t i, j, bufsize;
     494                 :            : 
     495                 :          6 :         allocate_cores(1);
     496                 :          6 :         allocate_threads(1);
     497                 :            : 
     498                 :          6 :         set_thread(0);
     499                 :            : 
     500                 :            :         /* We cannot use spdk_iobuf_set_opts(), as it won't allow us to use such small pools */
     501                 :          6 :         g_iobuf.opts = opts;
     502                 :          6 :         rc = spdk_iobuf_initialize();
     503                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     504                 :            : 
     505                 :          6 :         rc = spdk_iobuf_register_module("ut_module0");
     506                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     507                 :            : 
     508                 :          6 :         rc = spdk_iobuf_register_module("ut_module1");
     509                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     510                 :            : 
     511                 :            :         /* First check that channel initialization fails when it's not possible to fill in the cache
     512                 :            :          * from the pool.
     513                 :            :          */
     514   [ +  -  +  - ]:          6 :         rc = spdk_iobuf_channel_init(&iobuf_ch[0], "ut_module0", 5, 1);
     515                 :          6 :         CU_ASSERT_EQUAL(rc, -ENOMEM);
     516   [ +  -  +  - ]:          6 :         rc = spdk_iobuf_channel_init(&iobuf_ch[0], "ut_module0", 1, 5);
     517                 :          6 :         CU_ASSERT_EQUAL(rc, -ENOMEM);
     518                 :            : 
     519   [ +  -  +  - ]:          6 :         rc = spdk_iobuf_channel_init(&iobuf_ch[0], "ut_module0", 4, 4);
     520                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     521   [ +  -  +  - ]:          6 :         rc = spdk_iobuf_channel_init(&iobuf_ch[1], "ut_module1", 4, 4);
     522                 :          6 :         CU_ASSERT_EQUAL(rc, -ENOMEM);
     523                 :            : 
     524   [ +  -  +  - ]:          6 :         spdk_iobuf_channel_fini(&iobuf_ch[0]);
     525                 :          6 :         poll_threads();
     526                 :            : 
     527                 :            :         /* Initialize one channel with cache, acquire buffers, and check that a second one can be
     528                 :            :          * created once the buffers acquired from the first one are returned to the pool
     529                 :            :          */
     530   [ +  -  +  - ]:          6 :         rc = spdk_iobuf_channel_init(&iobuf_ch[0], "ut_module0", 2, 2);
     531                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     532                 :            : 
     533         [ +  + ]:         24 :         for (i = 0; i < 3; ++i) {
     534   [ +  -  +  -  :         18 :                 mod0_entries[i].buf = spdk_iobuf_get(&iobuf_ch[0], LARGE_BUFSIZE, &mod0_entries[i].iobuf,
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     535                 :            :                                                      ut_iobuf_get_buf_cb);
     536   [ +  -  +  -  :         18 :                 CU_ASSERT_PTR_NOT_NULL(mod0_entries[i].buf);
             +  -  +  - ]
     537                 :          3 :         }
     538                 :            : 
     539                 :            :         /* The channels can be temporarily greedy, holding more buffers than their configured cache
     540                 :            :          * size. We can only guarantee that we can create a channel if all outstanding buffers
     541                 :            :          * have been returned. */
     542         [ +  + ]:         24 :         for (i = 0; i < 3; ++i) {
     543   [ +  -  +  -  :         18 :                 spdk_iobuf_put(&iobuf_ch[0], mod0_entries[i].buf, LARGE_BUFSIZE);
          +  -  +  -  +  
                -  +  - ]
     544                 :          3 :         }
     545                 :            : 
     546                 :            :         /* The last buffer should be released back to the pool, so we should be able to create a new
     547                 :            :          * channel
     548                 :            :          */
     549   [ +  -  +  - ]:          6 :         rc = spdk_iobuf_channel_init(&iobuf_ch[1], "ut_module1", 2, 2);
     550                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     551                 :            : 
     552   [ +  -  +  - ]:          6 :         spdk_iobuf_channel_fini(&iobuf_ch[0]);
     553   [ +  -  +  - ]:          6 :         spdk_iobuf_channel_fini(&iobuf_ch[1]);
     554                 :          6 :         poll_threads();
     555                 :            : 
     556                 :            :         /* Check that the pool is only used when the cache is empty and that the cache guarantees a
     557                 :            :          * certain set of buffers
     558                 :            :          */
     559   [ +  -  +  - ]:          6 :         rc = spdk_iobuf_channel_init(&iobuf_ch[0], "ut_module0", 2, 2);
     560                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     561   [ +  -  +  - ]:          6 :         rc = spdk_iobuf_channel_init(&iobuf_ch[1], "ut_module1", 1, 1);
     562                 :          6 :         CU_ASSERT_EQUAL(rc, 0);
     563                 :            : 
     564                 :          6 :         uint32_t buffer_sizes[] = { SMALL_BUFSIZE, LARGE_BUFSIZE };
     565         [ +  + ]:         18 :         for (i = 0; i < SPDK_COUNTOF(buffer_sizes); ++i) {
     566   [ +  -  +  -  :         12 :                 bufsize = buffer_sizes[i];
                   +  - ]
     567                 :            : 
     568         [ +  + ]:         48 :                 for (j = 0; j < 3; ++j) {
     569   [ +  -  +  - ]:         36 :                         entry = &mod0_entries[j];
     570   [ +  -  +  -  :         36 :                         entry->buf = spdk_iobuf_get(&iobuf_ch[0], bufsize, &entry->iobuf,
          +  -  +  -  +  
                      - ]
     571                 :            :                                                     ut_iobuf_get_buf_cb);
     572   [ +  -  +  - ]:         36 :                         CU_ASSERT_PTR_NOT_NULL(entry->buf);
     573                 :          6 :                 }
     574                 :            : 
     575   [ +  -  +  -  :         12 :                 mod1_entries[0].buf = spdk_iobuf_get(&iobuf_ch[1], bufsize, &mod1_entries[0].iobuf,
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     576                 :            :                                                      ut_iobuf_get_buf_cb);
     577   [ +  -  +  -  :         12 :                 CU_ASSERT_PTR_NOT_NULL(mod1_entries[0].buf);
                   +  - ]
     578                 :            : 
     579                 :            :                 /* The whole pool is exhausted now */
     580   [ +  -  +  -  :         12 :                 mod1_entries[1].buf = spdk_iobuf_get(&iobuf_ch[1], bufsize, &mod1_entries[1].iobuf,
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     581                 :            :                                                      ut_iobuf_get_buf_cb);
     582   [ +  -  +  -  :         12 :                 CU_ASSERT_PTR_NULL(mod1_entries[1].buf);
             +  -  +  - ]
     583   [ +  -  +  -  :         12 :                 mod0_entries[3].buf = spdk_iobuf_get(&iobuf_ch[0], bufsize, &mod0_entries[3].iobuf,
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     584                 :            :                                                      ut_iobuf_get_buf_cb);
     585   [ +  -  +  -  :         12 :                 CU_ASSERT_PTR_NULL(mod0_entries[3].buf);
             +  -  +  - ]
     586                 :            : 
     587                 :            :                 /* If there are outstanding requests waiting for a buffer, they should have priority
     588                 :            :                  * over filling in the cache, even if they're from different modules.
     589                 :            :                  */
     590   [ +  -  +  -  :         12 :                 spdk_iobuf_put(&iobuf_ch[0], mod0_entries[2].buf, bufsize);
          +  -  +  -  +  
                -  +  - ]
     591                 :            :                 /* Also make sure the queue is FIFO and doesn't care about which module requested
     592                 :            :                  * and which module released the buffer.
     593                 :            :                  */
     594   [ +  -  +  -  :         12 :                 CU_ASSERT_PTR_NOT_NULL(mod1_entries[1].buf);
             +  -  +  - ]
     595   [ +  -  +  -  :         12 :                 CU_ASSERT_PTR_NULL(mod0_entries[3].buf);
             +  -  +  - ]
     596                 :            : 
     597                 :            :                 /* Return the buffers back */
     598   [ +  -  +  -  :         12 :                 spdk_iobuf_entry_abort(&iobuf_ch[0], &mod0_entries[3].iobuf, bufsize);
          +  -  +  -  +  
                      - ]
     599         [ +  + ]:         36 :                 for (j = 0; j < 2; ++j) {
     600   [ +  -  +  -  :         24 :                         spdk_iobuf_put(&iobuf_ch[0], mod0_entries[j].buf, bufsize);
          +  -  +  -  +  
                -  +  - ]
     601   [ +  -  +  -  :         24 :                         spdk_iobuf_put(&iobuf_ch[1], mod1_entries[j].buf, bufsize);
          +  -  +  -  +  
                -  +  - ]
     602                 :          4 :                 }
     603                 :          2 :         }
     604                 :            : 
     605   [ +  -  +  - ]:          6 :         spdk_iobuf_channel_fini(&iobuf_ch[0]);
     606   [ +  -  +  - ]:          6 :         spdk_iobuf_channel_fini(&iobuf_ch[1]);
     607                 :          6 :         poll_threads();
     608                 :            : 
     609                 :          6 :         spdk_iobuf_finish(ut_iobuf_finish_cb, &finish);
     610                 :          6 :         poll_threads();
     611                 :            : 
     612                 :          6 :         CU_ASSERT_EQUAL(finish, 1);
     613                 :            : 
     614                 :          6 :         free_threads();
     615                 :          6 :         free_cores();
     616                 :          6 : }
     617                 :            : 
     618                 :            : int
     619                 :          6 : main(int argc, char **argv)
     620                 :            : {
     621                 :          6 :         CU_pSuite       suite = NULL;
     622                 :          1 :         unsigned int    num_failures;
     623                 :            : 
     624                 :          6 :         CU_initialize_registry();
     625                 :            : 
     626                 :          6 :         suite = CU_add_suite("io_channel", NULL, NULL);
     627                 :          6 :         CU_ADD_TEST(suite, iobuf);
     628                 :          6 :         CU_ADD_TEST(suite, iobuf_cache);
     629                 :            : 
     630                 :          6 :         num_failures = spdk_ut_run_tests(argc, argv, NULL);
     631                 :          6 :         CU_cleanup_registry();
     632                 :          7 :         return num_failures;
     633                 :          1 : }

Generated by: LCOV version 1.14