libmemif: version 2 62/11362/9
authorJakub Grajciar <jgrajcia@cisco.com>
Mon, 26 Mar 2018 09:26:34 +0000 (11:26 +0200)
committerDamjan Marion <dmarion.lists@gmail.com>
Mon, 26 Mar 2018 12:01:49 +0000 (12:01 +0000)
Change-Id: Ia2532695aa9199d2a7b684aebef43df0b8235531
Signed-off-by: Jakub Grajciar <jgrajcia@cisco.com>
16 files changed:
extras/libmemif/configure.ac
extras/libmemif/dockerfile
extras/libmemif/docs/buildinstructions_doc.md
extras/libmemif/docs/gettingstarted_doc.md
extras/libmemif/examples/icmp_responder-epoll/main.c
extras/libmemif/examples/icmp_responder-mt/main.c
extras/libmemif/examples/icmp_responder/main.c
extras/libmemif/libmemif_doc.md
extras/libmemif/src/libmemif.h
extras/libmemif/src/main.c
extras/libmemif/src/memif.h
extras/libmemif/src/memif_private.h
extras/libmemif/src/socket.c
extras/libmemif/test/main_test.c
extras/libmemif/test/socket_test.c
extras/libmemif/test/unit_test.h

index dfe33cf..7895cff 100644 (file)
@@ -1,4 +1,4 @@
-AC_INIT(libmemif, 1.0)
+AC_INIT(libmemif, 2.0)
 LT_INIT
 AM_INIT_AUTOMAKE
 AM_SILENT_RULES([yes])
index 5475c6b..81012b0 100644 (file)
@@ -4,15 +4,16 @@ RUN apt-get update && \
        apt-get install -y git build-essential autoconf pkg-config libtool sudo check
 RUN rm -rf /var/lib/apt/lists/*
 
-RUN git clone https://github.com/JakubGrajciar/libmemif.git /libmemif
+RUN mkdir /libmemif
+ADD . /libmemif
 WORKDIR /libmemif
-RUN git checkout master
+
 RUN ./bootstrap
 RUN ./configure
 RUN make
 RUN make install
 
-RUN mkdir /var/vpp
+RUN mkdir /run/vpp
 
 RUN ulimit -c unlimited
 
index 838e835..a226856 100644 (file)
@@ -5,12 +5,10 @@ Install dependencies
 # sudo apt-get install -y git autoconf pkg_config libtool check
 ```
 
-Clone repository to your local machine. 
-```
-# git clone https://github.com/JakubGrajciar/libmemif.git
-```
+Libmemif is now part of VPP repository. Follow fd.io wiki to pull source code from VPP repository.
+[https://wiki.fd.io/view/VPP/Pulling,_Building,_Running,_Hacking_and_Pushing_VPP_Code#Pushing_Patches](https://wiki.fd.io/view/VPP/Pulling,_Building,_Running,_Hacking_and_Pushing_VPP_Code#Pushing_Patches)
 
-From root directory execute:
+Libmemif is located under extras/libmemif.
 For debug build:
 ```
 # ./bootstrap
@@ -33,21 +31,23 @@ Verify installation:
 > Make sure to run the binary file from ./.libs. File ./icmp\_responder in libmemif root directory is script that links the library, so it only verifies successful build. Default install path is /usr/lib.
 Use _help_ command to display build information and commands:
 ```
-ICMP_Responder:add_epoll_fd:204: fd 0 added to epoll
-MEMIF_DEBUG:src/main.c:memif_init:383: app name: ICMP_Responder
-ICMP_Responder:add_epoll_fd:204: fd 4 added to epoll
+ICMP_Responder:add_epoll_fd:233: fd 0 added to epoll
+ICMP_Responder:add_epoll_fd:233: fd 5 added to epoll
 LIBMEMIF EXAMPLE APP: ICMP_Responder (debug)
 ==============================
-libmemif version: 1.0 (debug)
-memif version: 256
+libmemif version: 2.0 (debug)
+memif version: 512
 commands:
        help - prints this help
        exit - exit app
-       conn <index> - create memif (slave-mode)
+       conn <index> <mode> [<interrupt-desc>] - create memif. index is also used as interface id, mode 0 = slave 1 = master, interrupt-desc none = default 0 = if ring is full wait 1 = handle only ARP requests
        del  <index> - delete memif
        show - show connection details
        ip-set <index> <ip-addr> - set interface ip address
        rx-mode <index> <qid> <polling|interrupt> - set queue rx mode
+       sh-count - print counters
+       cl-count - clear counters
+       send <index> <tx> <ip> <mac> - send icmp
 ```
 
 #### Examples
index e3ae6e5..dbe465c 100644 (file)
@@ -15,10 +15,10 @@ control_fd_update (int fd, uint8_t events)
 ```
    - Call memif initialization function. memif\_init
 ```C
-err = memif_init (control_fd_update, APP_NAME);
+err = memif_init (control_fd_update, APP_NAME, NULL, NULL);
 ```
    
-> If event occurres on any file descriptor returned by this callback, call memif\_control\_fd\_handler function.
+> If event occurres on any file descriptor returned by this callback, call memif\_control\_fd\_handler function. Since version 2.0, last two optional arguments are used to specify custom memory allocation.
 ```C
 memif_err = memif_control_fd_handler (evt.data.fd, events);
 ``` 
@@ -54,7 +54,6 @@ args.buffer_size = 2048;
 args.num_s2m_rings = 2;
 args.num_m2s_rings = 2;
 strncpy ((char *) args.interface_name, IF_NAME, strlen (IF_NAME));
-strncpy ((char *) args.instance_name, APP_NAME, strlen (APP_NAME));
 args.mode = 0;
 args.interface_id = 0;
 ```
@@ -102,40 +101,45 @@ on_interrupt (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
 ```
 
 6. Memif buffers
-    - Packet data are stored in memif\_buffer\_t. Pointer _data_ points to shared memory buffer, and unsigned integer *data\_len* contains packet data length.
+    - Packet data are stored in memif\_buffer\_t. Pointer _data_ points to shared memory buffer, and unsigned integer *_len* contains buffer length.
+    - flags: MEMIF\_BUFFER\_FLAG\_NEXT states that the buffer is not large enough to contain whole packet, so next buffer contains the rest of the packet. (chained buffers)
 ```C
 typedef struct
 {
     uint16_t desc_index;
-    uint32_t buffer_len;
-    uint32_t data_len;
+    uint32_t len;
+    uint8_t flags;
     void *data;
 } memif_buffer_t;
 ```
 
 5. Packet receive
-    - Api call memif\_rx\_burst will set all required fields in memif buffers provided by user application.
+    - Api call memif\_rx\_burst will set all required fields in memif buffers provided by user application and dequeue received buffers.
 ```C
-err = memif_rx_burst (c->conn, qid, c->rx_bufs, MAX_MEMIF_BUFS, &rx);
+err = memif_rx_burst (c->conn, qid, c->bufs, MAX_MEMIF_BUFS, &rx);
 ```
     - User application can then process packets.
-    - Api call memif\_buffer\_free will make supplied memif buffers ready for next receive and mark shared memory buffers as free.
+    - Api call memif\_refill\_queue will enqueue rx buffers.
 ```C
-err = memif_buffer_free (c->conn, qid, c->rx_bufs, rx, &fb);
+err = memif_refill_queue (c->conn, qid, rx);
 ```
 
 6. Packet transmit
-    - Api call memif\_buffer\_alloc will set all required fields in memif buffers provided by user application.
+    - Api call memif\_buffer\_alloc will find free tx buffers and set all required fields in memif buffers provided by user application.
 ```C
 err = memif_buffer_alloc (c->conn, qid, c->tx_bufs, n, &r);
 ```
     - User application can populate shared memory buffers with packets.
-    - Api call memif\_tx\_burst will inform peer interface (master memif on VPP) that there are packets ready to receive and mark memif buffers as free.
+    - Api call memif\_tx\_burst will enqueue tx buffers
 ```C
 err = memif_tx_burst (c->conn, qid, c->tx_bufs, c->tx_buf_num, &r);
 ```
 
 7. Helper functions
+    - Memif version
+```C
+uint16_t memif_ver = memif_get_version ();
+```
     - Memif details
       - Api call memif\_get\_details will return details about connection.
 ```C
@@ -172,7 +176,7 @@ ICMP Responder custom fd event polling.
 ICMP Responder multi-thread.
 - @ref extras/libmemif/examples/icmp_responder-mt
 
-> Simple example of libmemif multi-thread usage. Connection establishment is handled by main thread. There are two rx queues in this example. One in polling mode and second in interrupt mode.
+> Simple example of libmemif multi-thread usage. Connection establishment is handled by main thread. There are two rx/tx queues in this example. One in polling mode and second in interrupt mode.
 
 VPP config:
 ```
index 634e180..6b977a4 100644 (file)
@@ -319,7 +319,7 @@ icmpr_buffer_alloc (long index, long n, uint16_t * r, uint16_t i,
   memif_connection_t *c = &memif_connection[index];
   int err;
   /* set data pointer to shared memory and set buffer_len to shared mmeory buffer len */
-  err = memif_buffer_alloc (c->conn, qid, c->tx_bufs + i, n, r, 0);
+  err = memif_buffer_alloc (c->conn, qid, c->tx_bufs + i, n, r, 128);
   if ((err != MEMIF_ERR_SUCCESS) && (err != MEMIF_ERR_NOBUF_RING))
     {
       INFO ("memif_buffer_alloc: %s", memif_strerror (err));
@@ -361,10 +361,10 @@ on_interrupt (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
     }
 
   int err = MEMIF_ERR_SUCCESS, ret_val;
-  uint16_t rx, tx;
-  uint16_t fb;
-  int i;                       /* rx buffer iterator */
-  int j;                       /* tx bufferiterator */
+  uint16_t rx = 0, tx = 0;
+  uint16_t fb = 0;
+  int i = 0;                   /* rx buffer iterator */
+  int j = 0;                   /* tx bufferiterator */
 
   /* loop while there are packets in shm */
   do
@@ -380,54 +380,34 @@ on_interrupt (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
        }
 
       i = 0;
-
-      /* try to alloc required number of buffers buffers */
-      err = memif_buffer_alloc (c->conn, qid, c->tx_bufs, rx, &tx, 0);
+      err = memif_buffer_alloc (c->conn, qid, c->tx_bufs, rx, &tx, 128);
       if ((err != MEMIF_ERR_SUCCESS) && (err != MEMIF_ERR_NOBUF_RING))
        {
          INFO ("memif_buffer_alloc: %s", memif_strerror (err));
          goto error;
        }
       j = 0;
-      c->tx_err_counter = rx - tx;
+      c->tx_err_counter += rx - tx;
 
-      /* process bufers */
       while (tx)
        {
-         while (tx > 2)
-           {
-             resolve_packet ((void *) (c->rx_bufs + i)->data,
-                             (c->rx_bufs + i)->data_len,
-                             (void *) (c->tx_bufs + j)->data,
-                             &(c->tx_bufs + j)->data_len, c->ip_addr);
-             resolve_packet ((void *) (c->rx_bufs + i + 1)->data,
-                             (c->rx_bufs + i + 1)->data_len,
-                             (void *) (c->tx_bufs + j + 1)->data,
-                             &(c->tx_bufs + j + 1)->data_len, c->ip_addr);
-
-             i += 2;
-             j += 2;
-             tx -= 2;
-           }
          resolve_packet ((void *) (c->rx_bufs + i)->data,
-                         (c->rx_bufs + i)->data_len,
+                         (c->rx_bufs + i)->len,
                          (void *) (c->tx_bufs + j)->data,
-                         &(c->tx_bufs + j)->data_len, c->ip_addr);
+                         &(c->tx_bufs + j)->len, c->ip_addr);
          i++;
          j++;
          tx--;
        }
-      /* mark memif buffers and shared memory buffers as free */
-      /* free processed buffers */
-      err = memif_buffer_free (c->conn, qid, c->rx_bufs, rx, &fb);
+
+      err = memif_refill_queue (c->conn, qid, rx);
       if (err != MEMIF_ERR_SUCCESS)
        INFO ("memif_buffer_free: %s", memif_strerror (err));
-      rx -= fb;
+      rx -= rx;
 
       DBG ("freed %d buffers. %u/%u alloc/free buffers",
-          fb, rx, MAX_MEMIF_BUFS - rx);
+          rx, rx, MAX_MEMIF_BUFS - rx);
 
-      /* transmit allocated buffers */
       err = memif_tx_burst (c->conn, qid, c->tx_bufs, j, &tx);
       if (err != MEMIF_ERR_SUCCESS)
        {
@@ -442,10 +422,10 @@ on_interrupt (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
   return 0;
 
 error:
-  err = memif_buffer_free (c->conn, qid, c->rx_bufs, rx, &fb);
+  err = memif_refill_queue (c->conn, qid, rx);
   if (err != MEMIF_ERR_SUCCESS)
     INFO ("memif_buffer_free: %s", memif_strerror (err));
-  c->rx_buf_num -= fb;
+  c->rx_buf_num -= rx;
   DBG ("freed %d buffers. %u/%u alloc/free buffers",
        fb, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
   return 0;
@@ -466,7 +446,7 @@ on_interrupt0 (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
     }
 
   int err = MEMIF_ERR_SUCCESS, ret_val;
-  uint16_t rx, tx;
+  uint16_t rx = 0, tx = 0;
   uint16_t fb;
   int i;                       /* rx buffer iterator */
   int j;                       /* tx bufferiterator */
@@ -492,7 +472,7 @@ on_interrupt0 (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
        {
 
          /* try to alloc required number of buffers buffers */
-         err = memif_buffer_alloc (c->conn, qid, c->tx_bufs, rx, &tx, 0);
+         err = memif_buffer_alloc (c->conn, qid, c->tx_bufs, rx, &tx, 128);
          if ((err != MEMIF_ERR_SUCCESS) && (err != MEMIF_ERR_NOBUF_RING))
            {
              INFO ("memif_buffer_alloc: %s", memif_strerror (err));
@@ -506,33 +486,32 @@ on_interrupt0 (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
              while (tx > 2)
                {
                  resolve_packet ((void *) (c->rx_bufs + i)->data,
-                                 (c->rx_bufs + i)->data_len,
+                                 (c->rx_bufs + i)->len,
                                  (void *) (c->tx_bufs + j)->data,
-                                 &(c->tx_bufs + j)->data_len, c->ip_addr);
+                                 &(c->tx_bufs + j)->len, c->ip_addr);
                  resolve_packet ((void *) (c->rx_bufs + i + 1)->data,
-                                 (c->rx_bufs + i + 1)->data_len,
+                                 (c->rx_bufs + i + 1)->len,
                                  (void *) (c->tx_bufs + j + 1)->data,
-                                 &(c->tx_bufs + j + 1)->data_len,
-                                 c->ip_addr);
+                                 &(c->tx_bufs + j + 1)->len, c->ip_addr);
 
                  i += 2;
                  j += 2;
                  tx -= 2;
                }
              resolve_packet ((void *) (c->rx_bufs + i)->data,
-                             (c->rx_bufs + i)->data_len,
+                             (c->rx_bufs + i)->len,
                              (void *) (c->tx_bufs + j)->data,
-                             &(c->tx_bufs + j)->data_len, c->ip_addr);
+                             &(c->tx_bufs + j)->len, c->ip_addr);
              i++;
              j++;
              tx--;
            }
          /* mark memif buffers and shared memory buffers as free */
          /* free processed buffers */
-         err = memif_buffer_free (c->conn, qid, c->rx_bufs + prev_i, j, &fb);
+         err = memif_refill_queue (c->conn, qid, j);
          if (err != MEMIF_ERR_SUCCESS)
            INFO ("memif_buffer_free: %s", memif_strerror (err));
-         rx -= fb;
+         rx -= j;
          prev_i = i;
 
          DBG ("freed %d buffers. %u/%u alloc/free buffers",
@@ -555,10 +534,10 @@ on_interrupt0 (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
   return 0;
 
 error:
-  err = memif_buffer_free (c->conn, qid, c->rx_bufs, rx, &fb);
+  err = memif_refill_queue (c->conn, qid, rx);
   if (err != MEMIF_ERR_SUCCESS)
     INFO ("memif_buffer_free: %s", memif_strerror (err));
-  c->rx_buf_num -= fb;
+  c->rx_buf_num -= rx;
   DBG ("freed %d buffers. %u/%u alloc/free buffers",
        fb, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
   return 0;
@@ -605,17 +584,17 @@ on_interrupt1 (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
              if (icmpr_buffer_alloc (c->index, 1, &tx, i, qid) < 0)
                break;
              resolve_packet ((void *) (c->rx_bufs + i)->data,
-                             (c->rx_bufs + i)->data_len,
+                             (c->rx_bufs + i)->len,
                              (void *) (c->tx_bufs + i)->data,
-                             &(c->tx_bufs + i)->data_len, c->ip_addr);
+                             &(c->tx_bufs + i)->len, c->ip_addr);
              icmpr_tx_burst (c->index, qid);
            }
        }
 
-      err = memif_buffer_free (c->conn, qid, c->rx_bufs, rx, &fb);
+      err = memif_refill_queue (c->conn, qid, rx);
       if (err != MEMIF_ERR_SUCCESS)
        INFO ("memif_buffer_free: %s", memif_strerror (err));
-      c->rx_buf_num -= fb;
+      c->rx_buf_num -= rx;
 
 
     }
@@ -624,10 +603,10 @@ on_interrupt1 (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
   return 0;
 
 error:
-  err = memif_buffer_free (c->conn, qid, c->rx_bufs, rx, &fb);
+  err = memif_refill_queue (c->conn, qid, rx);
   if (err != MEMIF_ERR_SUCCESS)
     INFO ("memif_buffer_free: %s", memif_strerror (err));
-  c->rx_buf_num -= fb;
+  c->rx_buf_num -= rx;
   DBG ("freed %d buffers. %u/%u alloc/free buffers",
        fb, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
   return 0;
@@ -655,10 +634,9 @@ icmpr_memif_create (long index, long mode, char *s)
   args.is_master = mode;
   args.log2_ring_size = 11;
   args.buffer_size = 2048;
-  args.num_s2m_rings = 2;
-  args.num_m2s_rings = 2;
+  args.num_s2m_rings = 1;
+  args.num_m2s_rings = 1;
   strncpy ((char *) args.interface_name, IF_NAME, strlen (IF_NAME));
-  strncpy ((char *) args.instance_name, APP_NAME, strlen (APP_NAME));
   args.mode = 0;
   /* socket filename is not specified, because this app is supposed to
      connect to VPP over memif. so default socket filename will be used */
@@ -779,7 +757,7 @@ print_help ()
   printf (" (debug)");
 #endif
   printf ("\n");
-  printf ("memif version: %d\n", MEMIF_VERSION);
+  printf ("memif version: %d\n", memif_get_version ());
   printf ("commands:\n");
   printf ("\thelp - prints this help\n");
   printf ("\texit - exit app\n");
@@ -968,7 +946,7 @@ icmpr_send_proc (void *data)
       i = 0;
       err = memif_buffer_alloc (c->conn, 0, c->tx_bufs,
                                MAX_MEMIF_BUFS >
-                               count ? count : MAX_MEMIF_BUFS, &tx, 0);
+                               count ? count : MAX_MEMIF_BUFS, &tx, 128);
       if ((err != MEMIF_ERR_SUCCESS) && (err != MEMIF_ERR_NOBUF_RING))
        {
          INFO ("memif_buffer_alloc: %s Thread exiting...\n",
@@ -982,16 +960,16 @@ icmpr_send_proc (void *data)
          while (tx > 2)
            {
              generate_packet ((void *) c->tx_bufs[i].data,
-                              &c->tx_bufs[i].data_len, c->ip_addr,
+                              &c->tx_bufs[i].len, c->ip_addr,
                               d->ip_daddr, d->hw_daddr, seq++);
              generate_packet ((void *) c->tx_bufs[i + 1].data,
-                              &c->tx_bufs[i + 1].data_len, c->ip_addr,
+                              &c->tx_bufs[i + 1].len, c->ip_addr,
                               d->ip_daddr, d->hw_daddr, seq++);
              i += 2;
              tx -= 2;
            }
          generate_packet ((void *) c->tx_bufs[i].data,
-                          &c->tx_bufs[i].data_len, c->ip_addr,
+                          &c->tx_bufs[i].len, c->ip_addr,
                           d->ip_daddr, d->hw_daddr, seq++);
          i++;
          tx--;
@@ -1313,13 +1291,17 @@ main ()
   /* if valid callback is passed as argument, fd event polling will be done by user
      all file descriptors and events will be passed to user in this callback */
   /* if callback is set to NULL libmemif will handle fd event polling */
-  err = memif_init (control_fd_update, APP_NAME);
+  err = memif_init (control_fd_update, APP_NAME, NULL, NULL);
   if (err != MEMIF_ERR_SUCCESS)
-    INFO ("memif_init: %s", memif_strerror (err));
+    {
+      INFO ("memif_init: %s", memif_strerror (err));
+      icmpr_free ();
+      exit (-1);
+    }
 
   for (i = 0; i < MAX_CONNS; i++)
     {
-      memif_connection[i].conn = NULL;
+      memset (&memif_connection[i], 0, sizeof (memif_connection_t));
       ctx[i] = i;
     }
 
index c47fc53..4f7733b 100644 (file)
@@ -299,6 +299,10 @@ memif_rx_poll (void *ptr)
       data->rx_buf_num += rx;
       if (rx == 0)
        {
+         /* if queue is in polling mode, it's not refilled */
+         err = memif_refill_queue (c->conn, data->qid, -1);
+         if (err != MEMIF_ERR_SUCCESS)
+           INFO ("memif_buffer_free: %s", memif_strerror (err));
          continue;
        }
 
@@ -309,7 +313,7 @@ memif_rx_poll (void *ptr)
 
       err =
        memif_buffer_alloc (c->conn, data->qid, data->tx_bufs,
-                           data->rx_buf_num, &tx, 0);
+                           data->rx_buf_num, &tx, 128);
       if (err != MEMIF_ERR_SUCCESS)
        {
          INFO ("memif_buffer_alloc: %s", memif_strerror (err));
@@ -324,16 +328,16 @@ memif_rx_poll (void *ptr)
       for (i = 0; i < rx; i++)
        {
          resolve_packet ((void *) (data->rx_bufs + i)->data,
-                         (data->rx_bufs + i)->data_len,
+                         (data->rx_bufs + i)->len,
                          (void *) (data->tx_bufs + i)->data,
-                         &(data->tx_bufs + i)->data_len, c->ip_addr);
+                         &(data->tx_bufs + i)->len, c->ip_addr);
        }
 
       /* mark memif buffers and shared memory buffers as free */
-      err = memif_buffer_free (c->conn, data->qid, data->rx_bufs, rx, &fb);
+      err = memif_refill_queue (c->conn, data->qid, -1);
       if (err != MEMIF_ERR_SUCCESS)
        INFO ("memif_buffer_free: %s", memif_strerror (err));
-      data->rx_buf_num -= fb;
+      data->rx_buf_num -= rx;
 
       DBG ("freed %d buffers. %u/%u alloc/free buffers",
           fb, data->rx_buf_num, MAX_MEMIF_BUFS - data->rx_buf_num);
@@ -355,10 +359,10 @@ error:
   goto close;
 
 close:
-  err = memif_buffer_free (c->conn, data->qid, data->rx_bufs, rx, &fb);
+  err = memif_refill_queue (c->conn, data->qid, -1);
   if (err != MEMIF_ERR_SUCCESS)
     INFO ("memif_buffer_free: %s", memif_strerror (err));
-  data->rx_buf_num -= fb;
+  data->rx_buf_num -= rx;
   DBG ("freed %d buffers. %u/%u alloc/free buffers",
        fb, data->rx_buf_num, MAX_MEMIF_BUFS - data->rx_buf_num);
   free (data->rx_bufs);
@@ -439,7 +443,7 @@ memif_rx_interrupt (void *ptr)
 
          err =
            memif_buffer_alloc (c->conn, data->qid, data->tx_bufs,
-                               data->rx_buf_num, &tx, 0);
+                               data->rx_buf_num, &tx, 128);
          if (err != MEMIF_ERR_SUCCESS)
            {
              INFO ("memif_buffer_alloc: %s", memif_strerror (err));
@@ -454,17 +458,16 @@ memif_rx_interrupt (void *ptr)
          for (i = 0; i < rx; i++)
            {
              resolve_packet ((void *) (data->rx_bufs + i)->data,
-                             (data->rx_bufs + i)->data_len,
+                             (data->rx_bufs + i)->len,
                              (void *) (data->tx_bufs + i)->data,
-                             &(data->tx_bufs + i)->data_len, c->ip_addr);
+                             &(data->tx_bufs + i)->len, c->ip_addr);
            }
 
          /* mark memif buffers and shared memory buffers as free */
-         err =
-           memif_buffer_free (c->conn, data->qid, data->rx_bufs, rx, &fb);
+         err = memif_refill_queue (c->conn, data->qid, rx);
          if (err != MEMIF_ERR_SUCCESS)
            INFO ("memif_buffer_free: %s", memif_strerror (err));
-         data->rx_buf_num -= fb;
+         data->rx_buf_num -= rx;
 
          DBG ("freed %d buffers. %u/%u alloc/free buffers",
               fb, data->rx_buf_num, MAX_MEMIF_BUFS - data->rx_buf_num);
@@ -487,10 +490,10 @@ error:
   goto close;
 
 close:
-  err = memif_buffer_free (c->conn, data->qid, data->rx_bufs, rx, &fb);
+  err = memif_refill_queue (c->conn, data->qid, rx);
   if (err != MEMIF_ERR_SUCCESS)
     INFO ("memif_buffer_free: %s", memif_strerror (err));
-  data->rx_buf_num -= fb;
+  data->rx_buf_num -= rx;
   DBG ("freed %d buffers. %u/%u alloc/free buffers",
        fb, data->rx_buf_num, MAX_MEMIF_BUFS - data->rx_buf_num);
   free (data->rx_bufs);
@@ -611,7 +614,6 @@ icmpr_memif_create (long index)
   args.num_s2m_rings = 2;
   args.num_m2s_rings = 2;
   strncpy ((char *) args.interface_name, IF_NAME, strlen (IF_NAME));
-  strncpy ((char *) args.instance_name, APP_NAME, strlen (APP_NAME));
   args.mode = 0;
   /* socket filename is not specified, because this app is supposed to
      connect to VPP over memif. so default socket filename will be used */
@@ -675,7 +677,7 @@ print_help ()
   printf (" (debug)");
 #endif
   printf ("\n");
-  printf ("memif version: %d\n", MEMIF_VERSION);
+  printf ("memif version: %d\n", memif_get_version ());
   printf ("commands:\n");
   printf ("\thelp - prints this help\n");
   printf ("\texit - exit app\n");
@@ -896,7 +898,7 @@ main ()
   /* if valid callback is passed as argument, fd event polling will be done by user
      all file descriptors and events will be passed to user in this callback */
   /* if callback is set to NULL libmemif will handle fd event polling */
-  err = memif_init (control_fd_update, APP_NAME);
+  err = memif_init (control_fd_update, APP_NAME, NULL, NULL);
   if (err != MEMIF_ERR_SUCCESS)
     INFO ("memif_init: %s", memif_strerror (err));
 
index 9e49771..b820ad3 100644 (file)
@@ -214,7 +214,7 @@ print_help ()
   printf (" (debug)");
 #endif
   printf ("\n");
-  printf ("memif version: %d\n", MEMIF_VERSION);
+  printf ("memif version: %d\n", memif_get_version ());
   printf ("\tuse CTRL+C to exit\n");
 }
 
@@ -225,7 +225,7 @@ icmpr_buffer_alloc (long n, uint16_t qid)
   int err;
   uint16_t r;
   /* set data pointer to shared memory and set buffer_len to shared mmeory buffer len */
-  err = memif_buffer_alloc (c->conn, qid, c->tx_bufs, n, &r, 0);
+  err = memif_buffer_alloc (c->conn, qid, c->tx_bufs, n, &r, 128);
   if (err != MEMIF_ERR_SUCCESS)
     {
       INFO ("memif_buffer_alloc: %s", memif_strerror (err));
@@ -306,30 +306,29 @@ on_interrupt (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
   for (i = 0; i < rx; i++)
     {
       resolve_packet ((void *) (c->rx_bufs + i)->data,
-                     (c->rx_bufs + i)->data_len,
+                     (c->rx_bufs + i)->len,
                      (void *) (c->tx_bufs + i)->data,
-                     &(c->tx_bufs + i)->data_len, c->ip_addr);
+                     &(c->tx_bufs + i)->len, c->ip_addr);
     }
 
-  uint16_t fb;
   /* mark memif buffers and shared memory buffers as free */
-  err = memif_buffer_free (c->conn, qid, c->rx_bufs, rx, &fb);
-  c->rx_buf_num -= fb;
+  err = memif_refill_queue (c->conn, qid, rx);
+  c->rx_buf_num -= rx;
 
   DBG ("freed %d buffers. %u/%u alloc/free buffers",
-       fb, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
+       rx, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
 
   icmpr_tx_burst (c->tx_qid);
 
   return 0;
 
 error:
-  err = memif_buffer_free (c->conn, qid, c->rx_bufs, rx, &fb);
+  err = memif_refill_queue (c->conn, qid, rx);
   if (err != MEMIF_ERR_SUCCESS)
     INFO ("memif_buffer_free: %s", memif_strerror (err));
-  c->rx_buf_num -= fb;
+  c->rx_buf_num -= rx;
   DBG ("freed %d buffers. %u/%u alloc/free buffers",
-       fb, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
+       rx, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
   return 0;
 }
 
@@ -346,7 +345,6 @@ icmpr_memif_create (int is_master)
   args.num_s2m_rings = 2;
   args.num_m2s_rings = 2;
   strncpy ((char *) args.interface_name, IF_NAME, strlen (IF_NAME));
-  strncpy ((char *) args.instance_name, APP_NAME, strlen (APP_NAME));
   args.mode = 0;
   /* socket filename is not specified, because this app is supposed to
      connect to VPP over memif. so default socket filename will be used */
@@ -396,7 +394,7 @@ main (int argc, char *argv[])
   /* if valid callback is passed as argument, fd event polling will be done by user
      all file descriptors and events will be passed to user in this callback */
   /* if callback is set to NULL libmemif will handle fd event polling */
-  err = memif_init (NULL, APP_NAME);
+  err = memif_init (NULL, APP_NAME, NULL, NULL);
   if (err != MEMIF_ERR_SUCCESS)
     INFO ("memif_init: %s", memif_strerror (err));
 
index 0ecaea0..a6e1e75 100644 (file)
@@ -47,21 +47,23 @@ Run container:
 ```
 Example application will start in debug mode. Output should look like this:
 ```
-ICMP_Responder:add_epoll_fd:204: fd 0 added to epoll
-MEMIF_DEBUG:src/main.c:memif_init:383: app name: ICMP_Responder
-ICMP_Responder:add_epoll_fd:204: fd 4 added to epoll
+ICMP_Responder:add_epoll_fd:233: fd 0 added to epoll
+ICMP_Responder:add_epoll_fd:233: fd 5 added to epoll
 LIBMEMIF EXAMPLE APP: ICMP_Responder (debug)
 ==============================
-libmemif version: 1.0 (debug)
-memif version: 256
+libmemif version: 2.0 (debug)
+memif version: 512
 commands:
        help - prints this help
        exit - exit app
-       conn <index> - create memif (slave-mode)
+       conn <index> <mode> [<interrupt-desc>] - create memif. index is also used as interface id, mode 0 = slave 1 = master, interrupt-desc none = default 0 = if ring is full wait 1 = handle only ARP requests
        del  <index> - delete memif
        show - show connection details
        ip-set <index> <ip-addr> - set interface ip address
        rx-mode <index> <qid> <polling|interrupt> - set queue rx mode
+       sh-count - print counters
+       cl-count - clear counters
+       send <index> <tx> <ip> <mac> - send icmp
 ```
 
 Continue with @ref libmemif_example_setup which contains instructions on how to set up conenction between icmpr-epoll example app and VPP-memif.
index a14a102..14c4503 100644 (file)
 #define _LIBMEMIF_H_
 
 /** Libmemif version. */
-#define LIBMEMIF_VERSION "1.0"
+#define LIBMEMIF_VERSION "2.0"
 /** Default name of application using libmemif. */
 #define MEMIF_DEFAULT_APP_NAME "libmemif-app"
 
 #include <inttypes.h>
 
-#include <memif.h>
-
 /*! Error codes */
 typedef enum
 {
@@ -95,10 +93,25 @@ typedef enum
 #define MEMIF_FD_EVENT_MOD   (1 << 4)
 /** @} */
 
-/** *brief Memif connection handle
+/** \brief Memif connection handle
     pointer of type void, pointing to internal structure
 */
 typedef void *memif_conn_handle_t;
+
+/** \brief Memif allocator alloc
+    @param size - requested allocation size
+
+    custom memory allocator: alloc function template
+*/
+typedef void *(memif_alloc_t) (size_t size);
+
+/** \brief Memif allocator free
+    @param size - requested allocation size
+
+    custom memory allocator: free function template
+*/
+typedef void (memif_free_t) (void *ptr);
+
 /**
  * @defgroup CALLBACKS Callback functions definitions
  * @ingroup libmemif
@@ -143,6 +156,15 @@ typedef int (memif_interrupt_t) (memif_conn_handle_t conn, void *private_ctx,
  * @{
  */
 
+#ifndef _MEMIF_H_
+typedef enum
+{
+  MEMIF_INTERFACE_MODE_ETHERNET = 0,
+  MEMIF_INTERFACE_MODE_IP = 1,
+  MEMIF_INTERFACE_MODE_PUNT_INJECT = 2,
+} memif_interface_mode_t;
+#endif /* _MEMIF_H_ */
+
 /** \brief Memif connection arguments
     @param socket_filename - socket filename
     @param secret - otional parameter used as interface autenthication
@@ -153,7 +175,6 @@ typedef int (memif_interrupt_t) (memif_conn_handle_t conn, void *private_ctx,
     @param is_master - 0 == master, 1 == slave
     @param interface_id - id used to identify peer connection
     @param interface_name - interface name
-    @param instance_name - application name
     @param mode - 0 == ethernet, 1 == ip , 2 == punt/inject
 */
 typedef struct
@@ -164,12 +185,11 @@ typedef struct
   uint8_t num_s2m_rings;       /*!< default = 1 */
   uint8_t num_m2s_rings;       /*!< default = 1 */
   uint16_t buffer_size;                /*!< default = 2048 */
-  memif_log2_ring_size_t log2_ring_size;       /*!< default = 10 (1024) */
+  uint8_t log2_ring_size;      /*!< default = 10 (1024) */
   uint8_t is_master;
 
-  memif_interface_id_t interface_id;
+  uint32_t interface_id;
   uint8_t interface_name[32];
-  uint8_t instance_name[32];   /*!< deprecated, will be removed in 2.0 */
   memif_interface_mode_t mode:8;
 } memif_conn_args_t;
 
@@ -182,15 +202,16 @@ typedef enum
 
 /** \brief Memif buffer
     @param desc_index - ring descriptor index
-    @param buffer_len - shared meory buffer length
-    @param data_len - data length
+    @param len - buffer length
+    @param flags - memif buffer flags
     @param data - pointer to shared memory data
 */
 typedef struct
 {
   uint16_t desc_index;
-  uint32_t buffer_len;
-  uint32_t data_len;
+  uint32_t len;
+#define MEMIF_BUFFER_FLAG_NEXT (1 << 0)
+  uint8_t flags;
   void *data;
 } memif_buffer_t;
 /** @} */
@@ -266,6 +287,12 @@ typedef struct
  * @{
  */
 
+/** \brief Memif get version
+
+    \return ((MEMIF_VERSION_MAJOR << 8) | MEMIF_VERSION_MINOR)
+*/
+uint16_t memif_get_version ();
+
 /** \biref Memif get queue event file descriptor
     @param conn - memif connection handle
     @param qid - queue id
@@ -309,6 +336,8 @@ int memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
 /** \brief Memif initialization
     @param on_control_fd_update - if control fd updates inform user to watch new fd
     @param app_name - application name (will be truncated to 32 chars)
+    @param memif_alloc - cutom memory allocator, NULL = default
+    @param memif_free - custom memory free, NULL = default
 
     if param on_control_fd_update is set to NULL,
     libmemif will handle file descriptor event polling
@@ -323,7 +352,8 @@ int memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
     \return memif_err_t
 */
 int memif_init (memif_control_fd_update_t * on_control_fd_update,
-               char *app_name);
+               char *app_name, memif_alloc_t * memif_alloc,
+               memif_free_t * memif_free);
 
 /** \brief Memif cleanup
 
@@ -398,7 +428,7 @@ int memif_delete (memif_conn_handle_t * conn);
     @param bufs - memif buffers
     @param count - number of memif buffers to allocate
     @param count_out - returns number of allocated buffers
-    @param size - minimal buffer size, 0 = standard buffer size
+    @param size - buffer size, may return chained buffers if size > buffer_size
 
     \return memif_err_t
 */
@@ -406,18 +436,15 @@ int memif_buffer_alloc (memif_conn_handle_t conn, uint16_t qid,
                        memif_buffer_t * bufs, uint16_t count,
                        uint16_t * count_out, uint16_t size);
 
-/** \brief Memif buffer free
+/** \brief Memif refill ring
     @param conn - memif conenction handle
     @param qid - number indentifying queue
-    @param bufs - memif buffers
-    @param count - number of memif buffers to free
-    @param count_out - returns number of freed buffers
+    @param count - number of buffers to be placed on ring
 
     \return memif_err_t
 */
-int memif_buffer_free (memif_conn_handle_t conn, uint16_t qid,
-                      memif_buffer_t * bufs, uint16_t count,
-                      uint16_t * count_out);
+int memif_refill_queue (memif_conn_handle_t conn, uint16_t qid,
+                       uint16_t count);
 
 /** \brief Memif transmit buffer burst
     @param conn - memif conenction handle
index cb24083..f83f710 100644 (file)
@@ -166,6 +166,12 @@ memif_strerror (int err_code)
   return memif_buf;
 }
 
+uint16_t
+memif_get_version ()
+{
+  return MEMIF_VERSION;
+}
+
 #define DBG_TX_BUF (0)
 #define DBG_RX_BUF (1)
 
@@ -191,7 +197,7 @@ print_bytes (void *data, uint16_t len, uint8_t q)
 int
 memif_syscall_error_handler (int err_code)
 {
-  DBG_UNIX ("%s", strerror (err_code));
+  DBG ("%s", strerror (err_code));
 
   if (err_code == 0)
     return MEMIF_ERR_SUCCESS;
@@ -401,18 +407,45 @@ memif_control_fd_update_register (memif_control_fd_update_t * cb)
   lm->control_fd_update = cb;
 }
 
+static void
+memif_alloc_register (memif_alloc_t * ma)
+{
+  libmemif_main_t *lm = &libmemif_main;
+  lm->alloc = ma;
+}
+
+static void
+memif_free_register (memif_free_t * mf)
+{
+  libmemif_main_t *lm = &libmemif_main;
+  lm->free = mf;
+}
+
 int
-memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name)
+memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
+           memif_alloc_t * memif_alloc, memif_free_t * memif_free)
 {
   int err = MEMIF_ERR_SUCCESS; /* 0 */
   libmemif_main_t *lm = &libmemif_main;
   memset (lm, 0, sizeof (libmemif_main_t));
 
-  if (app_name)
+  if (memif_alloc != NULL)
     {
-      uint8_t len = (strlen (app_name) < MEMIF_NAME_LEN)
-       ? MEMIF_NAME_LEN : strlen (app_name);
-      strncpy ((char *) lm->app_name, app_name, strlen (app_name));
+      memif_alloc_register (memif_alloc);
+    }
+  else
+    memif_alloc_register (malloc);
+
+  if (memif_free != NULL)
+    memif_free_register (memif_free);
+  else
+    memif_free_register (free);
+
+  if (app_name != NULL)
+    {
+      uint8_t len = (strlen (app_name) > MEMIF_NAME_LEN)
+       ? strlen (app_name) : MEMIF_NAME_LEN;
+      strncpy ((char *) lm->app_name, app_name, len);
     }
   else
     {
@@ -443,13 +476,33 @@ memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name)
   lm->pending_list_len = 1;
 
   lm->control_list =
-    malloc (sizeof (memif_list_elt_t) * lm->control_list_len);
+    lm->alloc (sizeof (memif_list_elt_t) * lm->control_list_len);
+  if (lm->control_list == NULL)
+    {
+      err = MEMIF_ERR_NOMEM;
+      goto error;
+    }
   lm->interrupt_list =
-    malloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
+    lm->alloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
+  if (lm->interrupt_list == NULL)
+    {
+      err = MEMIF_ERR_NOMEM;
+      goto error;
+    }
   lm->listener_list =
-    malloc (sizeof (memif_list_elt_t) * lm->listener_list_len);
+    lm->alloc (sizeof (memif_list_elt_t) * lm->listener_list_len);
+  if (lm->listener_list == NULL)
+    {
+      err = MEMIF_ERR_NOMEM;
+      goto error;
+    }
   lm->pending_list =
-    malloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
+    lm->alloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
+  if (lm->pending_list == NULL)
+    {
+      err = MEMIF_ERR_NOMEM;
+      goto error;
+    }
 
   int i;
   for (i = 0; i < lm->control_list_len; i++)
@@ -478,9 +531,8 @@ memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name)
   lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
   if (lm->timerfd < 0)
     {
-      err = errno;
-      DBG ("timerfd: %s", strerror (err));
-      return memif_syscall_error_handler (err);
+      err = memif_syscall_error_handler (errno);
+      goto error;
     }
 
   lm->arm.it_value.tv_sec = 2;
@@ -491,10 +543,15 @@ memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name)
   if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ) < 0)
     {
       DBG ("callback type memif_control_fd_update_t error!");
-      return MEMIF_ERR_CB_FDUPDATE;
+      err = MEMIF_ERR_CB_FDUPDATE;
+      goto error;
     }
 
-  return 0;
+  return err;
+
+error:
+  memif_cleanup ();
+  return err;
 }
 
 static inline memif_ring_t *
@@ -520,8 +577,8 @@ memif_set_rx_mode (memif_conn_handle_t c, memif_rx_mode_t rx_mode,
   if (conn == NULL)
     return MEMIF_ERR_NOCONN;
   uint8_t num =
-    (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->
-    run_args.num_m2s_rings;
+    (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->run_args.
+    num_m2s_rings;
   if (qid >= num)
     return MEMIF_ERR_QID;
 
@@ -536,6 +593,7 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
              memif_connection_update_t * on_disconnect,
              memif_interrupt_t * on_interrupt, void *private_ctx)
 {
+  libmemif_main_t *lm = &libmemif_main;
   int err, i, index, sockfd = -1;
   memif_list_elt_t list_elt;
   memif_connection_t *conn = (memif_connection_t *) * c;
@@ -544,16 +602,14 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
       DBG ("This handle already points to existing memif.");
       return MEMIF_ERR_CONN;
     }
-  conn = (memif_connection_t *) malloc (sizeof (memif_connection_t));
+  conn = (memif_connection_t *) lm->alloc (sizeof (memif_connection_t));
   if (conn == NULL)
     {
-      err = memif_syscall_error_handler (errno);
+      err = MEMIF_ERR_NOMEM;
       goto error;
     }
   memset (conn, 0, sizeof (memif_connection_t));
 
-  libmemif_main_t *lm = &libmemif_main;
-
   conn->args.interface_id = args->interface_id;
 
   if (args->log2_ring_size == 0)
@@ -591,13 +647,14 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
   strncpy ((char *) conn->args.interface_name, (char *) args->interface_name,
           l);
 
-  l = strlen ((char *) args->instance_name);
-  strncpy ((char *) conn->args.instance_name, (char *) args->instance_name,
-          l);
-
   /* allocate and initialize socket_filename so it can be copyed to sun_path
      without memory leaks */
-  conn->args.socket_filename = malloc (sizeof (char *) * 108);
+  conn->args.socket_filename = lm->alloc (sizeof (char *) * 108);
+  if (conn->args.socket_filename == NULL)
+    {
+      err = MEMIF_ERR_NOMEM;
+      goto error;
+    }
   memset (conn->args.socket_filename, 0, 108 * sizeof (char *));
 
   if (args->socket_filename)
@@ -668,10 +725,20 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
                    return memif_syscall_error_handler (errno);
                }
              DBG ("creating socket file");
-             ms = malloc (sizeof (memif_socket_t));
+             ms = lm->alloc (sizeof (memif_socket_t));
+             if (ms == NULL)
+               {
+                 err = MEMIF_ERR_NOMEM;
+                 goto error;
+               }
              ms->filename =
-               malloc (strlen ((char *) conn->args.socket_filename) +
-                       sizeof (char));
+               lm->alloc (strlen ((char *) conn->args.socket_filename) +
+                          sizeof (char));
+             if (ms->filename == NULL)
+               {
+                 err = MEMIF_ERR_NOMEM;
+                 goto error;
+               }
              memset (ms->filename, 0,
                      strlen ((char *) conn->args.socket_filename) +
                      sizeof (char));
@@ -680,7 +747,13 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
                       strlen ((char *) conn->args.socket_filename));
              ms->interface_list_len = 1;
              ms->interface_list =
-               malloc (sizeof (memif_list_elt_t) * ms->interface_list_len);
+               lm->alloc (sizeof (memif_list_elt_t) *
+                          ms->interface_list_len);
+             if (ms->interface_list == NULL)
+               {
+                 err = MEMIF_ERR_NOMEM;
+                 goto error;
+               }
              ms->interface_list[0].key = -1;
              ms->interface_list[0].data_struct = NULL;
              struct sockaddr_un un = { 0 };
@@ -772,9 +845,9 @@ error:
     close (sockfd);
   sockfd = -1;
   if (conn->args.socket_filename)
-    free (conn->args.socket_filename);
+    lm->free (conn->args.socket_filename);
   if (conn != NULL)
-    free (conn);
+    lm->free (conn);
   *c = conn = NULL;
   return err;
 }
@@ -855,20 +928,21 @@ memif_control_fd_handler (int fd, uint8_t events)
          if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
            {
              num =
-               (((memif_connection_t *) e->data_struct)->
-                args.is_master) ? ((memif_connection_t *) e->
-                                   data_struct)->run_args.
-               num_s2m_rings : ((memif_connection_t *) e->data_struct)->
-               run_args.num_m2s_rings;
+               (((memif_connection_t *) e->data_struct)->args.
+                is_master) ? ((memif_connection_t *) e->data_struct)->
+               run_args.num_s2m_rings : ((memif_connection_t *) e->
+                                         data_struct)->run_args.
+               num_m2s_rings;
              for (i = 0; i < num; i++)
                {
-                 if (((memif_connection_t *) e->data_struct)->
-                     rx_queues[i].int_fd == fd)
+                 if (((memif_connection_t *) e->data_struct)->rx_queues[i].
+                     int_fd == fd)
                    {
-                     ((memif_connection_t *) e->data_struct)->
-                       on_interrupt ((void *) e->data_struct,
-                                     ((memif_connection_t *) e->
-                                      data_struct)->private_ctx, i);
+                     ((memif_connection_t *) e->
+                      data_struct)->on_interrupt ((void *) e->data_struct,
+                                                  ((memif_connection_t *)
+                                                   e->data_struct)->
+                                                  private_ctx, i);
                      return MEMIF_ERR_SUCCESS;
                    }
                }
@@ -895,24 +969,24 @@ memif_control_fd_handler (int fd, uint8_t events)
          if (events & MEMIF_FD_EVENT_READ)
            {
              err =
-               ((memif_connection_t *) e->data_struct)->
-               read_fn (e->data_struct);
+               ((memif_connection_t *) e->data_struct)->read_fn (e->
+                                                                 data_struct);
              if (err != MEMIF_ERR_SUCCESS)
                return err;
            }
          if (events & MEMIF_FD_EVENT_WRITE)
            {
              err =
-               ((memif_connection_t *) e->data_struct)->
-               write_fn (e->data_struct);
+               ((memif_connection_t *) e->data_struct)->write_fn (e->
+                                                                  data_struct);
              if (err != MEMIF_ERR_SUCCESS)
                return err;
            }
          if (events & MEMIF_FD_EVENT_ERROR)
            {
              err =
-               ((memif_connection_t *) e->data_struct)->
-               error_fn (e->data_struct);
+               ((memif_connection_t *) e->data_struct)->error_fn (e->
+                                                                  data_struct);
              if (err != MEMIF_ERR_SUCCESS)
                return err;
            }
@@ -985,12 +1059,12 @@ memif_cancel_poll_event ()
 }
 
 static void
-memif_msg_queue_free (memif_msg_queue_elt_t ** e)
+memif_msg_queue_free (libmemif_main_t * lm, memif_msg_queue_elt_t ** e)
 {
   if (*e == NULL)
     return;
-  memif_msg_queue_free (&(*e)->next);
-  free (*e);
+  memif_msg_queue_free (lm, &(*e)->next);
+  lm->free (*e);
   *e = NULL;
   return;
 }
@@ -1029,8 +1103,8 @@ memif_disconnect_internal (memif_connection_t * c)
   if (c->tx_queues != NULL)
     {
       num =
-       (c->args.is_master) ? c->run_args.num_m2s_rings : c->
-       run_args.num_s2m_rings;
+       (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
+       num_s2m_rings;
       for (i = 0; i < num; i++)
        {
          mq = &c->tx_queues[i];
@@ -1043,15 +1117,15 @@ memif_disconnect_internal (memif_connection_t * c)
              mq->int_fd = -1;
            }
        }
-      free (c->tx_queues);
+      lm->free (c->tx_queues);
       c->tx_queues = NULL;
     }
 
   if (c->rx_queues != NULL)
     {
       num =
-       (c->args.is_master) ? c->run_args.num_s2m_rings : c->
-       run_args.num_m2s_rings;
+       (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
+       num_m2s_rings;
       for (i = 0; i < num; i++)
        {
          mq = &c->rx_queues[i];
@@ -1068,7 +1142,7 @@ memif_disconnect_internal (memif_connection_t * c)
              mq->int_fd = -1;
            }
        }
-      free (c->rx_queues);
+      lm->free (c->rx_queues);
       c->rx_queues = NULL;
     }
 
@@ -1079,13 +1153,13 @@ memif_disconnect_internal (memif_connection_t * c)
       if (c->regions[0].fd > 0)
        close (c->regions[0].fd);
       c->regions[0].fd = -1;
-      free (c->regions);
+      lm->free (c->regions);
       c->regions = NULL;
     }
 
   memset (&c->run_args, 0, sizeof (memif_conn_run_args_t));
 
-  memif_msg_queue_free (&c->msg_queue);
+  memif_msg_queue_free (lm, &c->msg_queue);
 
   if (!(c->args.is_master))
     {
@@ -1094,7 +1168,7 @@ memif_disconnect_internal (memif_connection_t * c)
          if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
            {
              err = memif_syscall_error_handler (errno);
-             DBG_UNIX ("timerfd_settime: arm");
+             DBG ("timerfd_settime: arm");
            }
        }
       lm->disconn_slaves++;
@@ -1145,11 +1219,11 @@ memif_delete (memif_conn_handle_t * conn)
                             c->listener_fd);
              close (c->listener_fd);
              c->listener_fd = ms->fd = -1;
-             free (ms->interface_list);
+             lm->free (ms->interface_list);
              ms->interface_list = NULL;
-             free (ms->filename);
+             lm->free (ms->filename);
              ms->filename = NULL;
-             free (ms);
+             lm->free (ms);
              ms = NULL;
            }
        }
@@ -1168,10 +1242,10 @@ memif_delete (memif_conn_handle_t * conn)
     }
 
   if (c->args.socket_filename)
-    free (c->args.socket_filename);
+    lm->free (c->args.socket_filename);
   c->args.socket_filename = NULL;
 
-  free (c);
+  lm->free (c);
   c = NULL;
 
   *conn = c;
@@ -1203,8 +1277,8 @@ memif_connect1 (memif_connection_t * c)
     }
 
   num =
-    (c->args.is_master) ? c->run_args.num_m2s_rings : c->
-    run_args.num_s2m_rings;
+    (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
+    num_s2m_rings;
   for (i = 0; i < num; i++)
     {
       mq = &c->tx_queues[i];
@@ -1221,8 +1295,8 @@ memif_connect1 (memif_connection_t * c)
        }
     }
   num =
-    (c->args.is_master) ? c->run_args.num_s2m_rings : c->
-    run_args.num_m2s_rings;
+    (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
+    num_m2s_rings;
   for (i = 0; i < num; i++)
     {
       mq = &c->rx_queues[i];
@@ -1254,9 +1328,9 @@ memif_init_regions_and_queues (memif_connection_t * conn)
   libmemif_main_t *lm = &libmemif_main;
   memif_list_elt_t e;
 
-  conn->regions = (memif_region_t *) malloc (sizeof (memif_region_t));
+  conn->regions = (memif_region_t *) lm->alloc (sizeof (memif_region_t));
   if (conn->regions == NULL)
-    return memif_syscall_error_handler (errno);
+    return MEMIF_ERR_NOMEM;
   r = conn->regions;
 
   buffer_offset =
@@ -1269,12 +1343,13 @@ memif_init_regions_and_queues (memif_connection_t * conn)
     conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
     (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
 
-  if ((r->fd = memfd_create ("memif region 0", MFD_ALLOW_SEALING)) == -1)
+  if ((r->fd =
+       memif_memfd_create ("memif region 0", MFD_ALLOW_SEALING)) == -1)
     return memif_syscall_error_handler (errno);
-/*
-    if ((fcntl (r->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
-        return memif_syscall_error_handler (errno);
-*/
+
+  if ((fcntl (r->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
+    return memif_syscall_error_handler (errno);
+
   if ((ftruncate (r->fd, r->region_size)) == -1)
     return memif_syscall_error_handler (errno);
 
@@ -1295,7 +1370,7 @@ memif_init_regions_and_queues (memif_connection_t * conn)
          ring->desc[j].region = 0;
          ring->desc[j].offset = buffer_offset +
            (uint32_t) (slot * conn->run_args.buffer_size);
-         ring->desc[j].buffer_length = conn->run_args.buffer_size;
+         ring->desc[j].length = conn->run_args.buffer_size;
        }
     }
   for (i = 0; i < conn->run_args.num_m2s_rings; i++)
@@ -1314,15 +1389,15 @@ memif_init_regions_and_queues (memif_connection_t * conn)
          ring->desc[j].region = 0;
          ring->desc[j].offset = buffer_offset +
            (uint32_t) (slot * conn->run_args.buffer_size);
-         ring->desc[j].buffer_length = conn->run_args.buffer_size;
+         ring->desc[j].length = conn->run_args.buffer_size;
        }
     }
   memif_queue_t *mq;
   mq =
-    (memif_queue_t *) malloc (sizeof (memif_queue_t) *
-                             conn->run_args.num_s2m_rings);
+    (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
+                                conn->run_args.num_s2m_rings);
   if (mq == NULL)
-    return memif_syscall_error_handler (errno);
+    return MEMIF_ERR_NOMEM;
   int x;
   for (x = 0; x < conn->run_args.num_s2m_rings; x++)
     {
@@ -1340,15 +1415,16 @@ memif_init_regions_and_queues (memif_connection_t * conn)
       mq[x].offset =
        (void *) mq[x].ring - (void *) conn->regions[mq->region].shm;
       mq[x].last_head = 0;
+      mq[x].last_tail = 0;
       mq[x].alloc_bufs = 0;
     }
   conn->tx_queues = mq;
 
   mq =
-    (memif_queue_t *) malloc (sizeof (memif_queue_t) *
-                             conn->run_args.num_m2s_rings);
+    (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
+                                conn->run_args.num_m2s_rings);
   if (mq == NULL)
-    return memif_syscall_error_handler (errno);
+    return MEMIF_ERR_NOMEM;
   for (x = 0; x < conn->run_args.num_m2s_rings; x++)
     {
       if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
@@ -1365,6 +1441,7 @@ memif_init_regions_and_queues (memif_connection_t * conn)
       mq[x].offset =
        (void *) mq[x].ring - (void *) conn->regions[mq->region].shm;
       mq[x].last_head = 0;
+      mq[x].last_tail = 0;
       mq[x].alloc_bufs = 0;
     }
   conn->rx_queues = mq;
@@ -1378,101 +1455,102 @@ memif_buffer_alloc (memif_conn_handle_t conn, uint16_t qid,
                    uint16_t * count_out, uint16_t size)
 {
   memif_connection_t *c = (memif_connection_t *) conn;
-  if (c == NULL)
+  if (EXPECT_FALSE (c == NULL))
     return MEMIF_ERR_NOCONN;
-  if (c->fd < 0)
+  if (EXPECT_FALSE (c->fd < 0))
     return MEMIF_ERR_DISCONNECTED;
   uint8_t num =
-    (c->args.is_master) ? c->run_args.num_m2s_rings : c->
-    run_args.num_s2m_rings;
-  if (qid >= num)
+    (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
+    num_s2m_rings;
+  if (EXPECT_FALSE (qid >= num))
     return MEMIF_ERR_QID;
+  if (EXPECT_FALSE (!count_out))
+    return MEMIF_ERR_INVAL_ARG;
+
   memif_queue_t *mq = &c->tx_queues[qid];
   memif_ring_t *ring = mq->ring;
   memif_buffer_t *b0, *b1;
-  uint8_t chain_buf = 1;
   uint16_t mask = (1 << mq->log2_ring_size) - 1;
-  uint16_t head = ring->head;
-  uint16_t tail = ring->tail;
   uint16_t ring_size;
-  uint16_t s0, s1, ns;
-  *count_out = 0;
+  uint16_t slot, ns;
   int i, err = MEMIF_ERR_SUCCESS;      /* 0 */
+  uint16_t dst_left, src_left;
+  uint16_t saved_count;
+  memif_buffer_t *saved_b;
+  *count_out = 0;
 
   ring_size = (1 << mq->log2_ring_size);
-  ns = ring_size - head + tail;
+  ns = ring->tail - mq->last_tail;
+  mq->last_tail += ns;
+  slot = (c->args.is_master) ? ring->tail : ring->head;
+  slot += mq->alloc_bufs;
 
-  /* calculate number of chain buffers */
-  if (size > ring->desc[0].buffer_length)
-    {
-      chain_buf = size / ring->desc[0].buffer_length;
-      if (((size % ring->desc[0].buffer_length) != 0) || (size == 0))
-       chain_buf++;
-    }
+  if (c->args.is_master)
+    ns = ring->head + mq->alloc_bufs - ring->tail;
+  else
+    ns = ring_size - ring->head + mq->alloc_bufs + mq->last_tail;
 
   while (count && ns)
     {
-      while ((count > 2) && (ns > 2))
-       {
-         s0 = (ring->head + mq->alloc_bufs) & mask;
-         s1 = (ring->head + mq->alloc_bufs + chain_buf) & mask;
-
-         if ((2 * chain_buf) > ns)
-           break;
-
-         b0 = (bufs + *count_out);
-         b1 = (bufs + *count_out + 1);
-
-         b0->desc_index = head + mq->alloc_bufs;
-         b1->desc_index = head + mq->alloc_bufs + chain_buf;
-         ring->desc[s0].flags = 0;
-         ring->desc[s1].flags = 0;
-         b0->buffer_len = ring->desc[s0].buffer_length * chain_buf;
-         b1->buffer_len = ring->desc[s1].buffer_length * chain_buf;
-         /* TODO: support multiple regions -> ring descriptor contains region index */
-         b0->data = c->regions->shm + ring->desc[s0].offset;
-         b1->data = c->regions->shm + ring->desc[s1].offset;
-
-         for (i = 0; i < (chain_buf - 1); i++)
-           {
-             ring->desc[(s0 + i) & mask].flags |= MEMIF_DESC_FLAG_NEXT;
-             ring->desc[(s1 + i) & mask].flags |= MEMIF_DESC_FLAG_NEXT;
-             DBG ("allocating chained buffers");
-           }
-
-         mq->alloc_bufs += 2 * chain_buf;
-
-         DBG ("allocated ring slots %u, %u", s0, s1);
-         count -= 2;
-         ns -= (2 * chain_buf);
-         *count_out += 2;
-       }
-      s0 = (ring->head + mq->alloc_bufs) & mask;
-
       b0 = (bufs + *count_out);
 
-      if (chain_buf > ns)
-       break;
+      saved_b = b0;
+      saved_count = count;
+
+      b0->desc_index = slot;
+      ring->desc[slot & mask].flags = 0;
 
-      b0->desc_index = head + mq->alloc_bufs;
-      ring->desc[s0].flags = 0;
-      b0->buffer_len = ring->desc[s0].buffer_length * chain_buf;
-      b0->data = c->regions->shm + ring->desc[s0].offset;
+      /* slave can produce buffer with original length */
+      dst_left = (c->args.is_master) ? ring->desc[slot & mask].length : c->run_args.buffer_size;       /* - headroom */
+      src_left = size;
 
-      for (i = 0; i < (chain_buf - 1); i++)
+      while (src_left)
        {
-         ring->desc[(s0 + i) & mask].flags |= MEMIF_DESC_FLAG_NEXT;
-         DBG ("allocating chained buffers");
-       }
+         if (dst_left == 0)
+           {
+             if (count && ns)
+               {
+                 slot++;
+                 *count_out += 1;
+                 mq->alloc_bufs++;
+                 ns--;
+                 count--;
+
+                 ring->desc[b0->desc_index & mask].flags |=
+                   MEMIF_DESC_FLAG_NEXT;
+                 b0->flags |= MEMIF_BUFFER_FLAG_NEXT;
+
+                 b0 = (bufs + *count_out);
+                 b0->desc_index = slot;
+                 dst_left = (c->args.is_master) ? ring->desc[slot & mask].length : c->run_args.buffer_size;    /* - headroom */
+                 ring->desc[slot & mask].flags = 0;
+               }
+             else
+               {
+                 /* rollback allocated chain buffers */
+                 memset (saved_b, 0, sizeof (memif_buffer_t)
+                         * (saved_count - count + 1));
+                 *count_out -= saved_count - count;
+                 mq->alloc_bufs = saved_count - count;
+                 goto no_ns;
+               }
+           }
+         b0->len = memif_min (dst_left, src_left);
+         b0->data = memif_get_buffer (c, ring, slot & mask);
 
-      mq->alloc_bufs += chain_buf;
+         src_left -= b0->len;
+         dst_left -= b0->len;
+       }
 
-      DBG ("allocated ring slot %u", s0);
-      count--;
-      ns -= chain_buf;
+      slot++;
       *count_out += 1;
+      mq->alloc_bufs++;
+      ns--;
+      count--;
     }
 
+no_ns:
+
   DBG ("allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
        mq->alloc_bufs);
 
@@ -1486,72 +1564,37 @@ memif_buffer_alloc (memif_conn_handle_t conn, uint16_t qid,
 }
 
 int
-memif_buffer_free (memif_conn_handle_t conn, uint16_t qid,
-                  memif_buffer_t * bufs, uint16_t count,
-                  uint16_t * count_out)
+memif_refill_queue (memif_conn_handle_t conn, uint16_t qid, uint16_t count)
 {
   memif_connection_t *c = (memif_connection_t *) conn;
-  if (c == NULL)
+  if (EXPECT_FALSE (c == NULL))
     return MEMIF_ERR_NOCONN;
-  if (c->fd < 0)
+  if (EXPECT_FALSE (c->fd < 0))
     return MEMIF_ERR_DISCONNECTED;
   uint8_t num =
-    (c->args.is_master) ? c->run_args.num_s2m_rings : c->
-    run_args.num_m2s_rings;
-  if (qid >= num)
+    (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
+    num_m2s_rings;
+  if (EXPECT_FALSE (qid >= num))
     return MEMIF_ERR_QID;
   libmemif_main_t *lm = &libmemif_main;
   memif_queue_t *mq = &c->rx_queues[qid];
   memif_ring_t *ring = mq->ring;
-  uint16_t tail = ring->tail;
-  uint16_t mask = (1 << mq->log2_ring_size) - 1;
-  uint8_t chain_buf0, chain_buf1;
-  memif_buffer_t *b0, *b1;
-  *count_out = 0;
 
-  if (mq->alloc_bufs < count)
-    count = mq->alloc_bufs;
-
-  while (count)
+  if (c->args.is_master)
     {
-      while (count > 2)
-       {
-         b0 = (bufs + *count_out);
-         b1 = (bufs + *count_out + 1);
-         chain_buf0 =
-           b0->buffer_len / ring->desc[b0->desc_index & mask].buffer_length;
-         if ((b0->buffer_len %
-              ring->desc[b0->desc_index & mask].buffer_length) != 0)
-           chain_buf0++;
-         chain_buf1 =
-           b1->buffer_len / ring->desc[b1->desc_index & mask].buffer_length;
-         if ((b1->buffer_len %
-              ring->desc[b1->desc_index & mask].buffer_length) != 0)
-           chain_buf1++;
-         tail = b1->desc_index + chain_buf1;
-         b0->data = NULL;
-         b1->data = NULL;
-
-         count -= 2;
-         *count_out += 2;
-         mq->alloc_bufs -= chain_buf0 + chain_buf1;
-       }
-      b0 = (bufs + *count_out);
-      chain_buf0 =
-       b0->buffer_len / ring->desc[b0->desc_index & mask].buffer_length;
-      if ((b0->buffer_len %
-          ring->desc[b0->desc_index & mask].buffer_length) != 0)
-       chain_buf0++;
-      tail = b0->desc_index + chain_buf0;
-      b0->data = NULL;
-
-      count--;
-      *count_out += 1;
-      mq->alloc_bufs -= chain_buf0;
+      MEMIF_MEMORY_BARRIER ();
+      ring->tail =
+       (ring->tail + count <=
+        mq->last_head) ? ring->tail + count : mq->last_head;
+    }
+  else
+    {
+      uint16_t head = ring->head;
+      uint16_t ns = (1 << mq->log2_ring_size) - head + mq->last_tail;
+      head += ns;
+      MEMIF_MEMORY_BARRIER ();
+      ring->head = (ring->head + count <= head) ? ring->head + count : head;
     }
-  MEMIF_MEMORY_BARRIER ();
-  ring->tail = tail;
-  DBG ("tail: %u", ring->tail);
 
   return MEMIF_ERR_SUCCESS;    /* 0 */
 }
@@ -1561,212 +1604,48 @@ memif_tx_burst (memif_conn_handle_t conn, uint16_t qid,
                memif_buffer_t * bufs, uint16_t count, uint16_t * tx)
 {
   memif_connection_t *c = (memif_connection_t *) conn;
-  if (c == NULL)
+  if (EXPECT_FALSE (c == NULL))
     return MEMIF_ERR_NOCONN;
-  if (c->fd < 0)
+  if (EXPECT_FALSE (c->fd < 0))
     return MEMIF_ERR_DISCONNECTED;
   uint8_t num =
-    (c->args.is_master) ? c->run_args.num_m2s_rings : c->
-    run_args.num_s2m_rings;
-  if (qid >= num)
+    (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
+    num_s2m_rings;
+  if (EXPECT_FALSE (qid >= num))
     return MEMIF_ERR_QID;
+  if (EXPECT_FALSE (!tx))
+    return MEMIF_ERR_INVAL_ARG;
+
   memif_queue_t *mq = &c->tx_queues[qid];
   memif_ring_t *ring = mq->ring;
-  uint16_t head = ring->head;
-  uint16_t mask = (1 << mq->log2_ring_size) - 1;
-  uint8_t chain_buf0, chain_buf1;
-  *tx = 0;
-  uint16_t curr_buf = 0;
-  memif_buffer_t *b0, *b1;
-  int i;
+  uint16_t slot;
 
-  while (count)
-    {
-      while (count > 2)
-       {
-         b0 = (bufs + curr_buf);
-         b1 = (bufs + curr_buf + 1);
-         chain_buf0 =
-           b0->buffer_len / ring->desc[b0->desc_index & mask].buffer_length;
-         if ((b0->buffer_len %
-              ring->desc[b0->desc_index & mask].buffer_length) != 0)
-           chain_buf0++;
-
-         chain_buf1 =
-           b1->buffer_len / ring->desc[b1->desc_index & mask].buffer_length;
-         if ((b1->buffer_len %
-              ring->desc[b1->desc_index & mask].buffer_length) != 0)
-           chain_buf1++;
-
-         for (i = 0; i < memif_min (chain_buf0, chain_buf1); i++)
-           {
-             /* b0 */
-             if (b0->data_len >
-                 ring->desc[(b0->desc_index + i) & mask].buffer_length)
-               {
-                 b0->data_len -=
-                   ring->desc[(b0->desc_index + i) & mask].length =
-                   ring->desc[(b0->desc_index + i) & mask].buffer_length;
-               }
-             else
-               {
-                 ring->desc[(b0->desc_index + i) & mask].length =
-                   b0->data_len;
-                 b0->data_len = 0;
-               }
-             /* b1 */
-             if (b1->data_len >
-                 ring->desc[(b1->desc_index + i) & mask].buffer_length)
-               {
-                 b1->data_len -=
-                   ring->desc[(b1->desc_index + i) & mask].length =
-                   ring->desc[(b1->desc_index + i) & mask].buffer_length;
-               }
-             else
-               {
-                 ring->desc[(b1->desc_index + i) & mask].length =
-                   b1->data_len;
-                 b1->data_len = 0;
-               }
-#ifdef MEMIF_DBG_SHM
-             print_bytes (b0->data +
-                          ring->desc[(b0->desc_index +
-                                      i) & mask].buffer_length *
-                          (chain_buf0 - 1),
-                          ring->desc[(b0->desc_index +
-                                      i) & mask].buffer_length, DBG_TX_BUF);
-             print_bytes (b1->data +
-                          ring->desc[(b1->desc_index +
-                                      i) & mask].buffer_length *
-                          (chain_buf1 - 1),
-                          ring->desc[(b1->desc_index +
-                                      i) & mask].buffer_length, DBG_TX_BUF);
-#endif /* MEMIF_DBG_SHM */
-           }
+  slot = (c->args.is_master) ? ring->tail : ring->head;
+  *tx = (count <= mq->alloc_bufs) ? count : mq->alloc_bufs;
 
-         if (chain_buf0 > chain_buf1)
-           {
-             for (; i < chain_buf0; i++)
-               {
-                 if (b0->data_len >
-                     ring->desc[(b0->desc_index + i) & mask].buffer_length)
-                   {
-                     b0->data_len -=
-                       ring->desc[(b0->desc_index + i) & mask].length =
-                       ring->desc[(b0->desc_index + i) & mask].buffer_length;
-                   }
-                 else
-                   {
-                     ring->desc[(b0->desc_index + i) & mask].length =
-                       b0->data_len;
-                     b0->data_len = 0;
-                   }
-#ifdef MEMIF_DBG_SHM
-                 print_bytes (b0->data +
-                              ring->desc[(b0->desc_index +
-                                          i) & mask].buffer_length *
-                              (chain_buf0 - 1),
-                              ring->desc[(b0->desc_index +
-                                          i) & mask].buffer_length,
-                              DBG_TX_BUF);
-#endif /* MEMIF_DBG_SHM */
-               }
-           }
-         else
-           {
-             for (; i < chain_buf1; i++)
-               {
-                 if (b1->data_len >
-                     ring->desc[(b1->desc_index + i) & mask].buffer_length)
-                   {
-                     b1->data_len -=
-                       ring->desc[(b1->desc_index + i) & mask].length =
-                       ring->desc[(b1->desc_index + i) & mask].buffer_length;
-                   }
-                 else
-                   {
-                     ring->desc[(b1->desc_index + i) & mask].length =
-                       b1->data_len;
-                     b1->data_len = 0;
-                   }
 #ifdef MEMIF_DBG_SHM
-                 print_bytes (b1->data +
-                              ring->desc[(b1->desc_index +
-                                          i) & mask].buffer_length *
-                              (chain_buf1 - 1),
-                              ring->desc[(b1->desc_index +
-                                          i) & mask].buffer_length,
-                              DBG_TX_BUF);
-#endif /* MEMIF_DBG_SHM */
-               }
-           }
-
-         head = b1->desc_index + chain_buf1;
-
-         b0->data = NULL;
-#ifdef MEMIF_DBG
-         if (b0->data_len != 0)
-           DBG ("invalid b0 data length!");
-#endif /* MEMIF_DBG */
-         b1->data = NULL;
-#ifdef MEMIF_DBG
-         if (b1->data_len != 0)
-           DBG ("invalid b1 data length!");
-#endif /* MEMIF_DBG */
-
-         count -= 2;
-         *tx += chain_buf0 + chain_buf1;
-         curr_buf += 2;
-       }
-
+  uint16_t curr_buf = 0;
+  uint16_t mask = (1 << mq->log2_ring_size) - 1;
+  memif_buffer_t *b0;
+  for (curr_buf = 0; curr_buf < count; curr_buf++)
+    {
       b0 = (bufs + curr_buf);
-      chain_buf0 =
-       b0->buffer_len / ring->desc[b0->desc_index & mask].buffer_length;
-      if ((b0->buffer_len %
-          ring->desc[b0->desc_index & mask].buffer_length) != 0)
-       chain_buf0++;
+      print_bytes (memif_get_buffer (c, ring, b0->desc_index & mask),
+                  ring->desc[b0->desc_index & mask].length, DBG_TX_BUF);
 
-      for (i = 0; i < chain_buf0; i++)
-       {
-         if (b0->data_len >
-             ring->desc[(b0->desc_index + i) & mask].buffer_length)
-           {
-             b0->data_len -= ring->desc[(b0->desc_index + i) & mask].length =
-               ring->desc[(b0->desc_index + i) & mask].buffer_length;
-           }
-         else
-           {
-             ring->desc[(b0->desc_index + i) & mask].length = b0->data_len;
-             b0->data_len = 0;
-           }
-#ifdef MEMIF_DBG_SHM
-         print_bytes (b0->data +
-                      ring->desc[(b0->desc_index + i) & mask].buffer_length *
-                      (chain_buf0 - 1),
-                      ring->desc[(b0->desc_index + i) & mask].buffer_length,
-                      DBG_TX_BUF);
+    }
 #endif /* MEMIF_DBG_SHM */
-       }
-
-      head = b0->desc_index + chain_buf0;
 
-      b0->data = NULL;
-#ifdef MEMIF_DBG
-      if (b0->data_len != 0)
-       DBG ("invalid b0 data length!");
-#endif /* MEMIF_DBG */
-
-      count--;
-      *tx += chain_buf0;
-      curr_buf++;
-    }
   MEMIF_MEMORY_BARRIER ();
-  ring->head = head;
+  if (c->args.is_master)
+    ring->tail = slot + *tx;
+  else
+    ring->head = slot + *tx;
 
-  mq->alloc_bufs -= *tx;
+  /* zero out buffer fields so the client cant modify transmitted data */
+  memset (bufs, 0, sizeof (memif_buffer_t) * *tx);
 
-  /* TODO: return num of buffers and packets */
-  *tx = curr_buf;
+  mq->alloc_bufs -= *tx;
 
   if ((ring->flags & MEMIF_RING_FLAG_MASK_INT) == 0)
     {
@@ -1784,154 +1663,70 @@ memif_rx_burst (memif_conn_handle_t conn, uint16_t qid,
                memif_buffer_t * bufs, uint16_t count, uint16_t * rx)
 {
   memif_connection_t *c = (memif_connection_t *) conn;
-  if (c == NULL)
+  if (EXPECT_FALSE (c == NULL))
     return MEMIF_ERR_NOCONN;
-  if (c->fd < 0)
+  if (EXPECT_FALSE (c->fd < 0))
     return MEMIF_ERR_DISCONNECTED;
   uint8_t num =
-    (c->args.is_master) ? c->run_args.num_s2m_rings : c->
-    run_args.num_m2s_rings;
-  if (qid >= num)
+    (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
+    num_m2s_rings;
+  if (EXPECT_FALSE (qid >= num))
     return MEMIF_ERR_QID;
+  if (EXPECT_FALSE (!rx))
+    return MEMIF_ERR_INVAL_ARG;
+
   memif_queue_t *mq = &c->rx_queues[qid];
   memif_ring_t *ring = mq->ring;
-  uint16_t head = ring->head;
+  uint16_t cur_slot, last_slot;
   uint16_t ns;
   uint16_t mask = (1 << mq->log2_ring_size) - 1;
   memif_buffer_t *b0, *b1;
-  uint16_t curr_buf = 0;
   *rx = 0;
-#ifdef MEMIF_DBG_SHM
-  int i;
-#endif /* MEMIF_DBG_SHM */
 
   uint64_t b;
   ssize_t r = read (mq->int_fd, &b, sizeof (b));
   if ((r == -1) && (errno != EAGAIN))
     return memif_syscall_error_handler (errno);
 
-  if (head == mq->last_head)
-    return 0;
+  cur_slot = (c->args.is_master) ? mq->last_head : mq->last_tail;
+  last_slot = (c->args.is_master) ? ring->head : ring->tail;
+  if (cur_slot == last_slot)
+    return MEMIF_ERR_SUCCESS;
 
-  ns = head - mq->last_head;
+  ns = last_slot - cur_slot;
 
   while (ns && count)
     {
-      while ((ns > 2) && (count > 2))
-       {
-         b0 = (bufs + curr_buf);
-         b1 = (bufs + curr_buf + 1);
-
-         b0->desc_index = mq->last_head;
-         b0->data = memif_get_buffer (conn, ring, mq->last_head & mask);
-         b0->data_len = ring->desc[mq->last_head & mask].length;
-         b0->buffer_len = ring->desc[mq->last_head & mask].buffer_length;
-#ifdef MEMIF_DBG_SHM
-         i = 0;
-         print_bytes (b0->data +
-                      ring->desc[b0->desc_index & mask].buffer_length * i++,
-                      ring->desc[b0->desc_index & mask].buffer_length,
-                      DBG_TX_BUF);
-#endif /* MEMIF_DBG_SHM */
-         ns--;
-         *rx += 1;
-         while (ring->desc[mq->last_head & mask].
-                flags & MEMIF_DESC_FLAG_NEXT)
-           {
-             ring->desc[mq->last_head & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
-             mq->last_head++;
-             b0->data_len += ring->desc[mq->last_head & mask].length;
-             b0->buffer_len +=
-               ring->desc[mq->last_head & mask].buffer_length;
-#ifdef MEMIF_DBG_SHM
-             print_bytes (b0->data +
-                          ring->desc[b0->desc_index & mask].buffer_length *
-                          i++,
-                          ring->desc[b0->desc_index & mask].buffer_length,
-                          DBG_TX_BUF);
-#endif /* MEMIF_DBG_SHM */
-             ns--;
-             *rx += 1;
-           }
-         mq->last_head++;
-
-         b1->desc_index = mq->last_head;
-         b1->data = memif_get_buffer (conn, ring, mq->last_head & mask);
-         b1->data_len = ring->desc[mq->last_head & mask].length;
-         b1->buffer_len = ring->desc[mq->last_head & mask].buffer_length;
-#ifdef MEMIF_DBG_SHM
-         i = 0;
-         print_bytes (b1->data +
-                      ring->desc[b1->desc_index & mask].buffer_length * i++,
-                      ring->desc[b1->desc_index & mask].buffer_length,
-                      DBG_TX_BUF);
-#endif /* MEMIF_DBG_SHM */
-         ns--;
-         *rx += 1;
-         while (ring->desc[mq->last_head & mask].
-                flags & MEMIF_DESC_FLAG_NEXT)
-           {
-             ring->desc[mq->last_head & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
-             mq->last_head++;
-             b1->data_len += ring->desc[mq->last_head & mask].length;
-             b1->buffer_len +=
-               ring->desc[mq->last_head & mask].buffer_length;
-#ifdef MEMIF_DBG_SHM
-             print_bytes (b1->data +
-                          ring->desc[b1->desc_index & mask].buffer_length *
-                          i++,
-                          ring->desc[b1->desc_index & mask].buffer_length,
-                          DBG_TX_BUF);
-#endif /* MEMIF_DBG_SHM */
-             ns--;
-             *rx += 1;
-           }
-         mq->last_head++;
+      b0 = (bufs + *rx);
 
-         count -= 2;
-         curr_buf += 2;
+      b0->desc_index = cur_slot;
+      b0->data = memif_get_buffer (c, ring, cur_slot & mask);
+      b0->len = ring->desc[cur_slot & mask].length;
+      /* slave resets buffer length */
+      if (c->args.is_master == 0)
+       {
+         ring->desc[cur_slot & mask].length = c->run_args.buffer_size;
+       }
+      if (ring->desc[cur_slot & mask].flags & MEMIF_DESC_FLAG_NEXT)
+       {
+         b0->flags = MEMIF_BUFFER_FLAG_NEXT;
+         ring->desc[cur_slot & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
        }
-      b0 = (bufs + curr_buf);
 
-      b0->desc_index = mq->last_head;
-      b0->data = memif_get_buffer (conn, ring, mq->last_head & mask);
-      b0->data_len = ring->desc[mq->last_head & mask].length;
-      b0->buffer_len = ring->desc[mq->last_head & mask].buffer_length;
 #ifdef MEMIF_DBG_SHM
-      i = 0;
-      print_bytes (b0->data +
-                  ring->desc[b0->desc_index & mask].buffer_length * i++,
-                  ring->desc[b0->desc_index & mask].buffer_length,
-                  DBG_TX_BUF);
+      print_bytes (b0->data, b0->len, DBG_RX_BUF);
 #endif /* MEMIF_DBG_SHM */
       ns--;
       *rx += 1;
 
-      while (ring->desc[mq->last_head & mask].flags & MEMIF_DESC_FLAG_NEXT)
-       {
-         ring->desc[mq->last_head & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
-         mq->last_head++;
-         b0->data_len += ring->desc[mq->last_head & mask].length;
-         b0->buffer_len += ring->desc[mq->last_head & mask].buffer_length;
-#ifdef MEMIF_DBG_SHM
-         print_bytes (b0->data +
-                      ring->desc[b0->desc_index & mask].buffer_length * i++,
-                      ring->desc[b0->desc_index & mask].buffer_length,
-                      DBG_TX_BUF);
-#endif /* MEMIF_DBG_SHM */
-         ns--;
-         *rx += 1;
-       }
-      mq->last_head++;
-
       count--;
-      curr_buf++;
+      cur_slot++;
     }
 
-  mq->alloc_bufs += *rx;
-
-  /* TODO: return num of buffers and packets */
-  *rx = curr_buf;
+  if (c->args.is_master)
+    mq->last_head = cur_slot;
+  else
+    mq->last_tail = cur_slot;
 
   if (ns)
     {
@@ -1946,6 +1741,7 @@ int
 memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
                   char *buf, ssize_t buflen)
 {
+  libmemif_main_t *lm = &libmemif_main;
   memif_connection_t *c = (memif_connection_t *) conn;
   if (c == NULL)
     return MEMIF_ERR_NOCONN;
@@ -1963,10 +1759,10 @@ memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
   else
     err = MEMIF_ERR_NOBUF_DET;
 
-  l1 = strlen ((char *) c->args.instance_name);
+  l1 = strlen ((char *) lm->app_name);
   if (l0 + l1 < buflen)
     {
-      md->inst_name = strcpy (buf + l0, (char *) c->args.instance_name);
+      md->inst_name = strcpy (buf + l0, (char *) lm->app_name);
       l0 += l1 + 1;
     }
   else
@@ -2018,8 +1814,8 @@ memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
     err = MEMIF_ERR_NOBUF_DET;
 
   md->rx_queues_num =
-    (c->args.is_master) ? c->run_args.num_s2m_rings : c->
-    run_args.num_m2s_rings;
+    (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
+    num_m2s_rings;
 
   l1 = sizeof (memif_queue_details_t) * md->rx_queues_num;
   if (l0 + l1 <= buflen)
@@ -2041,8 +1837,8 @@ memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
     }
 
   md->tx_queues_num =
-    (c->args.is_master) ? c->run_args.num_m2s_rings : c->
-    run_args.num_s2m_rings;
+    (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
+    num_s2m_rings;
 
   l1 = sizeof (memif_queue_details_t) * md->tx_queues_num;
   if (l0 + l1 <= buflen)
@@ -2078,8 +1874,8 @@ memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *efd)
   if (c->fd < 0)
     return MEMIF_ERR_DISCONNECTED;
   uint8_t num =
-    (c->args.is_master) ? c->run_args.num_s2m_rings : c->
-    run_args.num_m2s_rings;
+    (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
+    num_m2s_rings;
   if (qid >= num)
     return MEMIF_ERR_QID;
 
@@ -2093,16 +1889,16 @@ memif_cleanup ()
 {
   libmemif_main_t *lm = &libmemif_main;
   if (lm->control_list)
-    free (lm->control_list);
+    lm->free (lm->control_list);
   lm->control_list = NULL;
   if (lm->interrupt_list)
-    free (lm->interrupt_list);
+    lm->free (lm->interrupt_list);
   lm->interrupt_list = NULL;
   if (lm->listener_list)
-    free (lm->listener_list);
+    lm->free (lm->listener_list);
   lm->listener_list = NULL;
   if (lm->pending_list)
-    free (lm->pending_list);
+    lm->free (lm->pending_list);
   lm->pending_list = NULL;
   if (poll_cancel_fd != -1)
     close (poll_cancel_fd);
index 11918ea..38b5402 100644 (file)
@@ -22,8 +22,8 @@
 #define MEMIF_CACHELINE_SIZE 64
 #endif
 
-#define MEMIF_COOKIE           0x3E31F10
-#define MEMIF_VERSION_MAJOR    1
+#define MEMIF_COOKIE           0x3E31F20
+#define MEMIF_VERSION_MAJOR    2
 #define MEMIF_VERSION_MINOR    0
 #define MEMIF_VERSION          ((MEMIF_VERSION_MAJOR << 8) | MEMIF_VERSION_MINOR)
 
@@ -58,7 +58,7 @@ typedef enum
 } memif_interface_mode_t;
 
 typedef uint16_t memif_region_index_t;
-typedef uint64_t memif_region_offset_t;
+typedef uint32_t memif_region_offset_t;
 typedef uint64_t memif_region_size_t;
 typedef uint16_t memif_ring_index_t;
 typedef uint32_t memif_interface_id_t;
@@ -148,15 +148,13 @@ typedef struct __attribute__ ((packed))
   uint16_t flags;
 #define MEMIF_DESC_FLAG_NEXT (1 << 0)
   memif_region_index_t region;
-  uint32_t buffer_length;
   uint32_t length;
-  uint8_t reserved[4];
   memif_region_offset_t offset;
-  uint64_t metadata;
+  uint32_t metadata;
 } memif_desc_t;
 
-_Static_assert (sizeof (memif_desc_t) == 32,
-               "Size of memif_dsct_t must be 32");
+_Static_assert (sizeof (memif_desc_t) == 16,
+               "Size of memif_dsct_t must be 16 bytes");
 
 #define MEMIF_CACHELINE_ALIGN_MARK(mark) \
   uint8_t mark[0] __attribute__((aligned(MEMIF_CACHELINE_SIZE)))
index a512ed4..b1039f9 100644 (file)
@@ -28,6 +28,7 @@
 #include <sys/timerfd.h>
 #include <string.h>
 
+#include <memif.h>
 #include <libmemif.h>
 
 #define MEMIF_NAME_LEN 32
@@ -45,43 +46,23 @@ _Static_assert (strlen (MEMIF_DEFAULT_APP_NAME) <= MEMIF_NAME_LEN,
 #define MEMIF_MAX_M2S_RING             255
 #define MEMIF_MAX_S2M_RING             255
 #define MEMIF_MAX_REGION               255
-#define MEMIF_MAX_LOG2_RING_SIZE       15
+#define MEMIF_MAX_LOG2_RING_SIZE       14
 
 #define MEMIF_MAX_FDS 512
 
 #define memif_min(a,b) (((a) < (b)) ? (a) : (b))
 
+#define EXPECT_TRUE(x) __builtin_expect((x),1)
+#define EXPECT_FALSE(x) __builtin_expect((x),0)
+
 #ifdef MEMIF_DBG
 #define DBG(...) do {                                                             \
                         printf("MEMIF_DEBUG:%s:%s:%d: ", __FILE__, __func__, __LINE__);  \
                         printf(__VA_ARGS__);                                            \
                         printf("\n");                                                   \
                         } while (0)
-
-#define DBG_UNIX(...) do {                                                        \
-                      printf("MEMIF_DEBUG_UNIX:%s:%s:%d: ", __FILE__, __func__, __LINE__);  \
-                      printf(__VA_ARGS__);                                    \
-                      printf("\n");                                           \
-                      } while (0)
-
-#define error_return_unix(...) do {                                             \
-                                DBG_UNIX(__VA_ARGS__);                          \
-                                return -1;                                      \
-                                } while (0)
-#define error_return(...) do {                                                  \
-                            DBG(__VA_ARGS__);                                   \
-                            return -1;                                          \
-                            } while (0)
 #else
 #define DBG(...)
-#define DBG_UNIX(...)
-#define error_return_unix(...) do {                                             \
-                                return -1;                                      \
-                                } while (0)
-#define error_return(...) do {                                                  \
-                            return -1;                                          \
-                            } while (0)
-
 #endif /* MEMIF_DBG */
 
 typedef struct
@@ -160,18 +141,12 @@ typedef struct memif_connection
 #define MEMIF_CONNECTION_FLAG_WRITE (1 << 0)
 } memif_connection_t;
 
-/*
- * WIP
- */
 typedef struct
 {
-  int key;                     /* fd or id */
+  int key;
   void *data_struct;
 } memif_list_elt_t;
 
-/*
- * WIP
- */
 typedef struct
 {
   int fd;
@@ -181,10 +156,6 @@ typedef struct
   memif_list_elt_t *interface_list;    /* memif master interfaces listening on this socket */
 } memif_socket_t;
 
-/*
- * WIP
- */
-/* probably function like memif_cleanup () will need to be called to close timerfd */
 typedef struct
 {
   memif_control_fd_update_t *control_fd_update;
@@ -193,8 +164,8 @@ typedef struct
   uint16_t disconn_slaves;
   uint8_t app_name[MEMIF_NAME_LEN];
 
-  /* master implementation... */
-  memif_socket_t ms;
+  memif_alloc_t *alloc;
+  memif_free_t *free;
 
   uint16_t control_list_len;
   uint16_t interrupt_list_len;
@@ -244,7 +215,7 @@ int free_list_elt (memif_list_elt_t * list, uint16_t len, int key);
 
 #ifndef HAVE_MEMFD_CREATE
 static inline int
-memfd_create (const char *name, unsigned int flags)
+memif_memfd_create (const char *name, unsigned int flags)
 {
   return syscall (__NR_memfd_create, name, flags);
 }
index 2be40f8..8f18d89 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <socket.h>
 #include <memif.h>
+#include <memif_private.h>
 
 /* sends msg to socket */
 static_fn int
@@ -70,8 +71,9 @@ memif_msg_send (int fd, memif_msg_t * msg, int afd)
 static_fn int
 memif_msg_enq_ack (memif_connection_t * c)
 {
+  libmemif_main_t *lm = &libmemif_main;
   memif_msg_queue_elt_t *e =
-    (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
+    (memif_msg_queue_elt_t *) lm->alloc (sizeof (memif_msg_queue_elt_t));
   if (e == NULL)
     return memif_syscall_error_handler (errno);
 
@@ -121,8 +123,9 @@ memif_msg_send_hello (int fd)
 static_fn int
 memif_msg_enq_init (memif_connection_t * c)
 {
+  libmemif_main_t *lm = &libmemif_main;
   memif_msg_queue_elt_t *e =
-    (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
+    (memif_msg_queue_elt_t *) lm->alloc (sizeof (memif_msg_queue_elt_t));
   if (e == NULL)
     return memif_syscall_error_handler (errno);
   memset (e, 0, sizeof (memif_msg_queue_elt_t));
@@ -136,8 +139,8 @@ memif_msg_enq_init (memif_connection_t * c)
   i->id = c->args.interface_id;
   i->mode = c->args.mode;
 
-  strncpy ((char *) i->name, (char *) c->args.instance_name,
-          strlen ((char *) c->args.instance_name));
+  strncpy ((char *) i->name, (char *) lm->app_name,
+          strlen ((char *) lm->app_name));
   if (c->args.secret)
     strncpy ((char *) i->secret, (char *) c->args.secret, sizeof (i->secret));
 
@@ -162,11 +165,12 @@ memif_msg_enq_init (memif_connection_t * c)
 static_fn int
 memif_msg_enq_add_region (memif_connection_t * c, uint8_t region_index)
 {
+  libmemif_main_t *lm = &libmemif_main;
   /* maybe check if region is valid? */
   memif_region_t *mr = &c->regions[region_index];
 
   memif_msg_queue_elt_t *e =
-    (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
+    (memif_msg_queue_elt_t *) lm->alloc (sizeof (memif_msg_queue_elt_t));
   if (e == NULL)
     return memif_syscall_error_handler (errno);
 
@@ -199,8 +203,9 @@ memif_msg_enq_add_region (memif_connection_t * c, uint8_t region_index)
 static_fn int
 memif_msg_enq_add_ring (memif_connection_t * c, uint8_t index, uint8_t dir)
 {
+  libmemif_main_t *lm = &libmemif_main;
   memif_msg_queue_elt_t *e =
-    (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
+    (memif_msg_queue_elt_t *) lm->alloc (sizeof (memif_msg_queue_elt_t));
   if (e == NULL)
     return memif_syscall_error_handler (errno);
 
@@ -244,8 +249,9 @@ memif_msg_enq_add_ring (memif_connection_t * c, uint8_t index, uint8_t dir)
 static_fn int
 memif_msg_enq_connect (memif_connection_t * c)
 {
+  libmemif_main_t *lm = &libmemif_main;
   memif_msg_queue_elt_t *e =
-    (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
+    (memif_msg_queue_elt_t *) lm->alloc (sizeof (memif_msg_queue_elt_t));
   if (e == NULL)
     return memif_syscall_error_handler (errno);
 
@@ -278,8 +284,9 @@ memif_msg_enq_connect (memif_connection_t * c)
 static_fn int
 memif_msg_enq_connected (memif_connection_t * c)
 {
+  libmemif_main_t *lm = &libmemif_main;
   memif_msg_queue_elt_t *e =
-    (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
+    (memif_msg_queue_elt_t *) lm->alloc (sizeof (memif_msg_queue_elt_t));
   if (e == NULL)
     return memif_syscall_error_handler (errno);
 
@@ -519,7 +526,7 @@ memif_msg_receive_add_ring (memif_connection_t * c, memif_msg_t * msg, int fd)
       mq =
        (memif_queue_t *) realloc (c->rx_queues,
                                   sizeof (memif_queue_t) * (ar->index + 1));
-       memset(mq, 0, sizeof (memif_queue_t) * (ar->index + 1));
+      memset (mq, 0, sizeof (memif_queue_t) * (ar->index + 1));
       if (mq == NULL)
        return memif_syscall_error_handler (errno);
       c->rx_queues = mq;
@@ -539,7 +546,7 @@ memif_msg_receive_add_ring (memif_connection_t * c, memif_msg_t * msg, int fd)
       mq =
        (memif_queue_t *) realloc (c->tx_queues,
                                   sizeof (memif_queue_t) * (ar->index + 1));
-       memset(mq, 0, sizeof (memif_queue_t) * (ar->index + 1));
+      memset (mq, 0, sizeof (memif_queue_t) * (ar->index + 1));
       if (mq == NULL)
        return memif_syscall_error_handler (errno);
       c->tx_queues = mq;
@@ -579,6 +586,9 @@ memif_msg_receive_connect (memif_connection_t * c, memif_msg_t * msg)
          add_list_elt (&elt, &lm->interrupt_list, &lm->interrupt_list_len);
 
          lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ);
+
+         /* refill ring buffers */
+         memif_refill_queue ((void *) c, i, -1);
        }
 
     }
@@ -607,7 +617,12 @@ memif_msg_receive_connected (memif_connection_t * c, memif_msg_t * msg)
   if (c->on_interrupt != NULL)
     {
       for (i = 0; i < c->run_args.num_s2m_rings; i++)
-       lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ);
+       {
+         lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ);
+
+         /* refill ring buffers */
+         memif_refill_queue ((void *) c, i, -1);
+       }
     }
 
   c->on_connect ((void *) c, c->private_ctx);
@@ -814,6 +829,7 @@ memif_conn_fd_read_ready (memif_connection_t * c)
 int
 memif_conn_fd_write_ready (memif_connection_t * c)
 {
+  libmemif_main_t *lm = &libmemif_main;
   int err = MEMIF_ERR_SUCCESS; /* 0 */
 
 
@@ -834,7 +850,7 @@ memif_conn_fd_write_ready (memif_connection_t * c)
         MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_WRITE | MEMIF_FD_EVENT_MOD);
 */
   err = memif_msg_send (c->fd, &e->msg, e->fd);
-  free (e);
+  lm->free (e);
   goto done;
 
 done:
index b7705c4..a5e0e3d 100644 (file)
@@ -65,7 +65,8 @@ START_TEST (test_init)
   int err;
 
   if ((err =
-       memif_init (control_fd_update, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   libmemif_main_t *lm = &libmemif_main;
@@ -84,7 +85,8 @@ START_TEST (test_init_epoll)
 {
   int err;
 
-  if ((err = memif_init (NULL, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
+  if ((err =
+       memif_init (NULL, TEST_APP_NAME, NULL, NULL)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   libmemif_main_t *lm = &libmemif_main;
@@ -110,12 +112,11 @@ START_TEST (test_create)
   libmemif_main_t *lm = &libmemif_main;
 
   if ((err =
-       memif_init (control_fd_update, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   strncpy ((char *) args.interface_name, TEST_IF_NAME, strlen (TEST_IF_NAME));
-  strncpy ((char *) args.instance_name, TEST_APP_NAME,
-          strlen (TEST_APP_NAME));
 
   if ((err = memif_create (&conn, &args, on_connect,
                           on_disconnect, on_interrupt,
@@ -147,7 +148,6 @@ START_TEST (test_create)
   ck_assert_ptr_ne (c->on_interrupt, NULL);
 
   ck_assert_str_eq (c->args.interface_name, args.interface_name);
-  ck_assert_str_eq (c->args.instance_name, args.instance_name);
   ck_assert_str_eq (c->args.socket_filename, SOCKET_FILENAME);
 
   struct itimerspec timer;
@@ -176,12 +176,11 @@ START_TEST (test_create_master)
   libmemif_main_t *lm = &libmemif_main;
 
   if ((err =
-       memif_init (control_fd_update, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   strncpy ((char *) args.interface_name, TEST_IF_NAME, strlen (TEST_IF_NAME));
-  strncpy ((char *) args.instance_name, TEST_APP_NAME,
-          strlen (TEST_APP_NAME));
 
   if ((err = memif_create (&conn, &args, on_connect,
                           on_disconnect, on_interrupt,
@@ -213,7 +212,6 @@ START_TEST (test_create_master)
   ck_assert_ptr_ne (c->on_interrupt, NULL);
 
   ck_assert_str_eq (c->args.interface_name, args.interface_name);
-  ck_assert_str_eq (c->args.instance_name, args.instance_name);
   ck_assert_str_eq (c->args.socket_filename, SOCKET_FILENAME);
 
   struct stat file_stat;
@@ -239,12 +237,11 @@ START_TEST (test_create_mult)
   libmemif_main_t *lm = &libmemif_main;
 
   if ((err =
-       memif_init (control_fd_update, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   strncpy ((char *) args.interface_name, TEST_IF_NAME, strlen (TEST_IF_NAME));
-  strncpy ((char *) args.instance_name, TEST_APP_NAME,
-          strlen (TEST_APP_NAME));
 
   if ((err = memif_create (&conn, &args, on_connect,
                           on_disconnect, on_interrupt,
@@ -300,10 +297,8 @@ START_TEST (test_create_mult)
   ck_assert_ptr_ne (c1->on_interrupt, NULL);
 
   ck_assert_str_eq (c->args.interface_name, args.interface_name);
-  ck_assert_str_eq (c->args.instance_name, args.instance_name);
   ck_assert_str_eq (c->args.socket_filename, SOCKET_FILENAME);
   ck_assert_str_eq (c1->args.interface_name, args.interface_name);
-  ck_assert_str_eq (c1->args.instance_name, args.instance_name);
   ck_assert_str_eq (c1->args.socket_filename, SOCKET_FILENAME);
 
   struct itimerspec timer;
@@ -334,12 +329,11 @@ START_TEST (test_control_fd_handler)
   libmemif_main_t *lm = &libmemif_main;
 
   if ((err =
-       memif_init (control_fd_update, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   strncpy ((char *) args.interface_name, TEST_IF_NAME, strlen (TEST_IF_NAME));
-  strncpy ((char *) args.instance_name, TEST_APP_NAME,
-          strlen (TEST_APP_NAME));
 
   if ((err = memif_create (&conn, &args, on_connect,
                           on_disconnect, on_interrupt,
@@ -406,12 +400,11 @@ START_TEST (test_buffer_alloc)
   libmemif_main_t *lm = &libmemif_main;
 
   if ((err =
-       memif_init (control_fd_update, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   strncpy ((char *) args.interface_name, TEST_IF_NAME, strlen (TEST_IF_NAME));
-  strncpy ((char *) args.instance_name, TEST_APP_NAME,
-          strlen (TEST_APP_NAME));
 
   if ((err = memif_create (&conn, &args, on_connect,
                           on_disconnect, on_interrupt,
@@ -437,12 +430,13 @@ START_TEST (test_buffer_alloc)
   qid = 0;
   if ((err =
        memif_buffer_alloc (conn, qid, bufs, max_buf,
-                          &buf, 0)) != MEMIF_ERR_SUCCESS)
+                          &buf,
+                          MEMIF_DEFAULT_BUFFER_SIZE)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   ck_assert_uint_eq (buf, max_buf);
   for (i = 0; i < max_buf; i++)
-    ck_assert_uint_eq (bufs[i].buffer_len, MEMIF_DEFAULT_BUFFER_SIZE);
+    ck_assert_uint_eq (bufs[i].len, MEMIF_DEFAULT_BUFFER_SIZE);
 
   /* test buffer allocation qid 1 (positive) */
   free (bufs);
@@ -451,12 +445,13 @@ START_TEST (test_buffer_alloc)
   qid = 1;
   if ((err =
        memif_buffer_alloc (conn, qid, bufs, max_buf,
-                          &buf, 0)) != MEMIF_ERR_SUCCESS)
+                          &buf,
+                          MEMIF_DEFAULT_BUFFER_SIZE)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   ck_assert_uint_eq (buf, max_buf);
   for (i = 0; i < max_buf; i++)
-    ck_assert_uint_eq (bufs[i].buffer_len, MEMIF_DEFAULT_BUFFER_SIZE);
+    ck_assert_uint_eq (bufs[i].len, MEMIF_DEFAULT_BUFFER_SIZE);
 
   /* test buffer allocation qid 2 (negative) */
 
@@ -466,7 +461,8 @@ START_TEST (test_buffer_alloc)
   qid = 2;
   if ((err =
        memif_buffer_alloc (conn, qid, bufs, max_buf,
-                          &buf, 0)) != MEMIF_ERR_SUCCESS)
+                          &buf,
+                          MEMIF_DEFAULT_BUFFER_SIZE)) != MEMIF_ERR_SUCCESS)
     ck_assert_msg (err == MEMIF_ERR_QID, "err code: %u, err msg: %s", err,
                   memif_strerror (err));
 
@@ -498,12 +494,11 @@ START_TEST (test_tx_burst)
   libmemif_main_t *lm = &libmemif_main;
 
   if ((err =
-       memif_init (control_fd_update, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   strncpy ((char *) args.interface_name, TEST_IF_NAME, strlen (TEST_IF_NAME));
-  strncpy ((char *) args.instance_name, TEST_APP_NAME,
-          strlen (TEST_APP_NAME));
 
   if ((err = memif_create (&conn, &args, on_connect,
                           on_disconnect, on_interrupt,
@@ -528,12 +523,13 @@ START_TEST (test_tx_burst)
   qid = 0;
   if ((err =
        memif_buffer_alloc (conn, qid, bufs, max_buf,
-                          &buf, 0)) != MEMIF_ERR_SUCCESS)
+                          &buf,
+                          MEMIF_DEFAULT_BUFFER_SIZE)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   ck_assert_uint_eq (buf, max_buf);
   for (i = 0; i < max_buf; i++)
-    ck_assert_uint_eq (bufs[i].buffer_len, MEMIF_DEFAULT_BUFFER_SIZE);
+    ck_assert_uint_eq (bufs[i].len, MEMIF_DEFAULT_BUFFER_SIZE);
 
   if ((err =
        memif_tx_burst (conn, qid, bufs, max_buf, &tx)) != MEMIF_ERR_SUCCESS)
@@ -549,12 +545,13 @@ START_TEST (test_tx_burst)
   qid = 1;
   if ((err =
        memif_buffer_alloc (conn, qid, bufs, max_buf,
-                          &buf, 0)) != MEMIF_ERR_SUCCESS)
+                          &buf,
+                          MEMIF_DEFAULT_BUFFER_SIZE)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   ck_assert_uint_eq (buf, max_buf);
   for (i = 0; i < max_buf; i++)
-    ck_assert_uint_eq (bufs[i].buffer_len, MEMIF_DEFAULT_BUFFER_SIZE);
+    ck_assert_uint_eq (bufs[i].len, MEMIF_DEFAULT_BUFFER_SIZE);
 
   if ((err =
        memif_tx_burst (conn, qid, bufs, max_buf, &tx)) != MEMIF_ERR_SUCCESS)
@@ -602,12 +599,11 @@ START_TEST (test_rx_burst)
   libmemif_main_t *lm = &libmemif_main;
 
   if ((err =
-       memif_init (control_fd_update, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   strncpy ((char *) args.interface_name, TEST_IF_NAME, strlen (TEST_IF_NAME));
-  strncpy ((char *) args.instance_name, TEST_APP_NAME,
-          strlen (TEST_APP_NAME));
 
   if ((err = memif_create (&conn, &args, on_connect,
                           on_disconnect, on_interrupt,
@@ -630,7 +626,7 @@ START_TEST (test_rx_burst)
   qid = 0;
   mq = &c->rx_queues[qid];
   ring = mq->ring;
-  ring->head += max_buf;
+  ring->tail += max_buf;
 
   bufs = malloc (sizeof (memif_buffer_t) * max_buf);
 
@@ -646,7 +642,7 @@ START_TEST (test_rx_burst)
   qid = 1;
   mq = &c->rx_queues[qid];
   ring = mq->ring;
-  ring->head += max_buf;
+  ring->tail += max_buf;
 
   free (bufs);
   bufs = malloc (sizeof (memif_buffer_t) * max_buf);
@@ -678,124 +674,6 @@ START_TEST (test_rx_burst)
   ck_assert_ptr_eq (conn, NULL);
 }
 
-END_TEST
-START_TEST (test_buffer_free)
-{
-  int err, i;
-  uint16_t max_buf = 10, buf, rx;
-  uint8_t qid;
-  memif_buffer_t *bufs;
-  memif_queue_t *mq;
-  memif_ring_t *ring;
-  ready_called = 0;
-  memif_conn_handle_t conn = NULL;
-  memif_conn_args_t args;
-  memset (&args, 0, sizeof (args));
-  args.num_s2m_rings = 2;
-  args.num_m2s_rings = 2;
-
-  libmemif_main_t *lm = &libmemif_main;
-
-  if ((err =
-       memif_init (control_fd_update, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
-    ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
-
-  strncpy ((char *) args.interface_name, TEST_IF_NAME, strlen (TEST_IF_NAME));
-  strncpy ((char *) args.instance_name, TEST_APP_NAME,
-          strlen (TEST_APP_NAME));
-
-  if ((err = memif_create (&conn, &args, on_connect,
-                          on_disconnect, on_interrupt,
-                          NULL)) != MEMIF_ERR_SUCCESS)
-    ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
-
-  memif_connection_t *c = (memif_connection_t *) conn;
-
-  c->run_args.num_s2m_rings = 2;
-  c->run_args.num_m2s_rings = 2;
-  c->run_args.log2_ring_size = 10;
-  c->run_args.buffer_size = 2048;
-
-  if ((err = memif_init_regions_and_queues (c)) != MEMIF_ERR_SUCCESS)
-    ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
-
-  c->fd = 69;
-
-  /* test buffer free qid 0 (positive) */
-  qid = 0;
-  mq = &c->rx_queues[qid];
-  ring = mq->ring;
-  ring->head += 10;
-
-  bufs = malloc (sizeof (memif_buffer_t) * max_buf);
-
-  if ((err =
-       memif_rx_burst (conn, qid, bufs, max_buf, &rx)) != MEMIF_ERR_SUCCESS)
-    ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
-
-  ck_assert_uint_eq (rx, max_buf);
-  for (i = 0; i < max_buf; i++)
-    ck_assert_ptr_ne (bufs[i].data, NULL);
-
-  if ((err =
-       memif_buffer_free (conn, qid, bufs, max_buf,
-                         &buf)) != MEMIF_ERR_SUCCESS)
-    ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
-
-  ck_assert_uint_eq (buf, max_buf);
-  for (i = 0; i < max_buf; i++)
-    ck_assert_ptr_eq (bufs[i].data, NULL);
-  ck_assert_uint_eq (ring->head, ring->tail);
-
-  /* test buffer free qid 1 (positive) */
-  qid = 1;
-  mq = &c->rx_queues[qid];
-  ring = mq->ring;
-  ring->head += 10;
-
-  free (bufs);
-  bufs = malloc (sizeof (memif_buffer_t) * max_buf);
-
-  if ((err =
-       memif_rx_burst (conn, qid, bufs, max_buf, &rx)) != MEMIF_ERR_SUCCESS)
-    ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
-
-  ck_assert_uint_eq (rx, max_buf);
-  for (i = 0; i < max_buf; i++)
-    ck_assert_ptr_ne (bufs[i].data, NULL);
-
-  if ((err =
-       memif_buffer_free (conn, qid, bufs, max_buf,
-                         &buf)) != MEMIF_ERR_SUCCESS)
-    ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
-
-  ck_assert_uint_eq (buf, max_buf);
-  for (i = 0; i < max_buf; i++)
-    ck_assert_ptr_eq (bufs[i].data, NULL);
-  ck_assert_uint_eq (ring->head, ring->tail);
-
-
-  /* test buffer free qid 2 (negative) */
-  qid = 2;
-  free (bufs);
-  bufs = malloc (sizeof (memif_buffer_t) * max_buf);
-
-  if ((err =
-       memif_buffer_free (conn, qid, bufs, max_buf,
-                         &buf)) != MEMIF_ERR_SUCCESS)
-    ck_assert_msg (err == MEMIF_ERR_QID, "err code: %u, err msg: %s", err,
-                  memif_strerror (err));
-
-  if (lm->timerfd > 0)
-    close (lm->timerfd);
-  lm->timerfd = -1;
-  free (bufs);
-  bufs = NULL;
-
-  memif_delete (&conn);
-  ck_assert_ptr_eq (conn, NULL);
-}
-
 END_TEST
 START_TEST (test_get_details)
 {
@@ -810,12 +688,11 @@ START_TEST (test_get_details)
   libmemif_main_t *lm = &libmemif_main;
 
   if ((err =
-       memif_init (control_fd_update, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   strncpy ((char *) args.interface_name, TEST_IF_NAME, strlen (TEST_IF_NAME));
-  strncpy ((char *) args.instance_name, TEST_APP_NAME,
-          strlen (TEST_APP_NAME));
 
   if ((err = memif_create (&conn, &args, on_connect,
                           on_disconnect, on_interrupt,
@@ -842,7 +719,6 @@ START_TEST (test_get_details)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   ck_assert_str_eq (md.if_name, c->args.interface_name);
-  ck_assert_str_eq (md.inst_name, c->args.instance_name);
   ck_assert_str_eq (md.remote_if_name, c->remote_if_name);
   ck_assert_str_eq (md.remote_inst_name, c->remote_name);
   ck_assert_str_eq (md.secret, c->args.secret);
@@ -889,12 +765,11 @@ START_TEST (test_init_regions_and_queues)
   libmemif_main_t *lm = &libmemif_main;
 
   if ((err =
-       memif_init (control_fd_update, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   strncpy ((char *) args.interface_name, TEST_IF_NAME, strlen (TEST_IF_NAME));
-  strncpy ((char *) args.instance_name, TEST_APP_NAME,
-          strlen (TEST_APP_NAME));
 
   if ((err = memif_create (&conn, &args, on_connect,
                           on_disconnect, on_interrupt,
@@ -945,12 +820,11 @@ START_TEST (test_connect1)
   libmemif_main_t *lm = &libmemif_main;
 
   if ((err =
-       memif_init (control_fd_update, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   strncpy ((char *) args.interface_name, TEST_IF_NAME, strlen (TEST_IF_NAME));
-  strncpy ((char *) args.instance_name, TEST_APP_NAME,
-          strlen (TEST_APP_NAME));
 
   if ((err = memif_create (&conn, &args, on_connect,
                           on_disconnect, on_interrupt,
@@ -992,12 +866,11 @@ START_TEST (test_disconnect_internal)
   libmemif_main_t *lm = &libmemif_main;
 
   if ((err =
-       memif_init (control_fd_update, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   strncpy ((char *) args.interface_name, TEST_IF_NAME, strlen (TEST_IF_NAME));
-  strncpy ((char *) args.instance_name, TEST_APP_NAME,
-          strlen (TEST_APP_NAME));
 
   if ((err = memif_create (&conn, &args, on_connect,
                           on_disconnect, on_interrupt,
@@ -1038,7 +911,8 @@ START_TEST (test_disconnect_internal)
   ck_assert_ptr_eq (conn, NULL);
 }
 
-END_TEST Suite * main_suite ()
+END_TEST Suite *
+main_suite ()
 {
   Suite *s;
 
@@ -1060,7 +934,6 @@ END_TEST Suite * main_suite ()
   tcase_add_test (tc_api, test_buffer_alloc);
   tcase_add_test (tc_api, test_tx_burst);
   tcase_add_test (tc_api, test_rx_burst);
-  tcase_add_test (tc_api, test_buffer_free);
   tcase_add_test (tc_api, test_get_details);
 
   /* create internal test case */
index f148495..720d686 100644 (file)
@@ -46,10 +46,17 @@ queue_free (memif_msg_queue_elt_t ** e)
 
 START_TEST (test_msg_queue)
 {
+  int err;
+  if ((err =
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
+    ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
+
   memif_connection_t conn;
   conn.msg_queue = NULL;
   conn.fd = -1;
 
+
   int i, len = 10;
 
   for (i = 0; i < len; i++)
@@ -88,6 +95,10 @@ END_TEST
 START_TEST (test_enq_ack)
 {
   int err;
+  if ((err =
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
+    ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
   memif_connection_t conn;
   conn.msg_queue = NULL;
 
@@ -104,14 +115,16 @@ END_TEST
 START_TEST (test_enq_init)
 {
   int err;
+  if ((err =
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
+    ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
   memif_connection_t conn;
   conn.msg_queue = NULL;
 
   conn.args.interface_id = 69;
   conn.args.mode = 0;
 
-  strncpy ((char *) conn.args.instance_name, TEST_APP_NAME,
-          strlen (TEST_APP_NAME));
   strncpy ((char *) conn.args.secret, TEST_SECRET, strlen (TEST_SECRET));
 
   if ((err = memif_msg_enq_init (&conn)) != MEMIF_ERR_SUCCESS)
@@ -127,7 +140,6 @@ START_TEST (test_enq_init)
   ck_assert_uint_eq (i->version, MEMIF_VERSION);
   ck_assert_uint_eq (i->id, conn.args.interface_id);
   ck_assert_uint_eq (i->mode, conn.args.mode);
-  ck_assert_str_eq (i->name, conn.args.instance_name);
   ck_assert_str_eq (i->secret, conn.args.secret);
   queue_free (&conn.msg_queue);
 }
@@ -136,6 +148,10 @@ END_TEST
 START_TEST (test_enq_add_region)
 {
   int err;
+  if ((err =
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
+    ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
   memif_connection_t conn;
   conn.msg_queue = NULL;
   conn.regions = (memif_region_t *) malloc (sizeof (memif_region_t));
@@ -168,6 +184,11 @@ END_TEST
 START_TEST (test_enq_add_ring)
 {
   int err;
+  if ((err =
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
+    ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
+
   memif_connection_t conn;
   conn.msg_queue = NULL;
   conn.rx_queues = (memif_queue_t *) malloc (sizeof (memif_queue_t));
@@ -204,6 +225,10 @@ END_TEST
 START_TEST (test_enq_connect)
 {
   int err;
+  if ((err =
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
+    ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
   memif_connection_t conn;
   conn.msg_queue = NULL;
   memset (conn.args.interface_name, 0, sizeof (conn.args.interface_name));
@@ -225,6 +250,10 @@ END_TEST
 START_TEST (test_enq_connected)
 {
   int err;
+  if ((err =
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
+    ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
   memif_connection_t conn;
   conn.msg_queue = NULL;
   memset (conn.args.interface_name, 0, sizeof (conn.args.interface_name));
@@ -261,12 +290,10 @@ START_TEST (test_send_hello)
   int err;
   memif_connection_t conn;
   conn.fd = -1;
-  memset (conn.args.instance_name, 0, sizeof (conn.args.instance_name));
-  strncpy ((char *) conn.args.instance_name, TEST_APP_NAME,
-          strlen (TEST_APP_NAME));
 
   if ((err =
-       memif_init (control_fd_update, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   if ((err = memif_msg_send_hello (conn.fd)) != MEMIF_ERR_SUCCESS)
@@ -363,7 +390,8 @@ START_TEST (test_recv_init)
   add_list_elt (&elt, &ms.interface_list, &ms.interface_list_len);
 
   if ((err =
-       memif_init (control_fd_update, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   if ((err = memif_msg_receive_init (&ms, -1, &msg)) != MEMIF_ERR_SUCCESS)
@@ -478,7 +506,8 @@ START_TEST (test_recv_connect)
   args.mode = 0;
 
   if ((err =
-       memif_init (control_fd_update, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   if ((err = memif_create (&c, &args, on_connect,
@@ -522,7 +551,8 @@ START_TEST (test_recv_connected)
   args.mode = 0;
 
   if ((err =
-       memif_init (control_fd_update, TEST_APP_NAME)) != MEMIF_ERR_SUCCESS)
+       memif_init (control_fd_update, TEST_APP_NAME, NULL,
+                  NULL)) != MEMIF_ERR_SUCCESS)
     ck_abort_msg ("err code: %u, err msg: %s", err, memif_strerror (err));
 
   if ((err = memif_create (&c, &args, on_connect,
@@ -570,7 +600,8 @@ START_TEST (test_recv_disconnect)
   ck_assert_str_eq (conn.remote_disconnect_string, "unit_test_dc");
 }
 
-END_TEST Suite * socket_suite ()
+END_TEST Suite *
+socket_suite ()
 {
   Suite *s;
   TCase *tc_msg_queue;
index fae3cba..a24887d 100644 (file)
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include <check.h>
 
+#include <memif.h>
 #include <libmemif.h>
 
 #define TEST_APP_NAME "unit_test_app"