xref: /unit/src/nxt_port_queue.h (revision 1555)
1*1555Smax.romanov@nginx.com 
2*1555Smax.romanov@nginx.com /*
3*1555Smax.romanov@nginx.com  * Copyright (C) NGINX, Inc.
4*1555Smax.romanov@nginx.com  */
5*1555Smax.romanov@nginx.com 
6*1555Smax.romanov@nginx.com #ifndef _NXT_PORT_QUEUE_H_INCLUDED_
7*1555Smax.romanov@nginx.com #define _NXT_PORT_QUEUE_H_INCLUDED_
8*1555Smax.romanov@nginx.com 
9*1555Smax.romanov@nginx.com 
10*1555Smax.romanov@nginx.com #include <nxt_nncq.h>
11*1555Smax.romanov@nginx.com 
12*1555Smax.romanov@nginx.com 
13*1555Smax.romanov@nginx.com /* Using Numeric Naive Circular Queue as a backend. */
14*1555Smax.romanov@nginx.com 
15*1555Smax.romanov@nginx.com #define NXT_PORT_QUEUE_SIZE      NXT_NNCQ_SIZE
16*1555Smax.romanov@nginx.com #define NXT_PORT_QUEUE_MSG_SIZE  31
17*1555Smax.romanov@nginx.com 
18*1555Smax.romanov@nginx.com 
19*1555Smax.romanov@nginx.com typedef struct {
20*1555Smax.romanov@nginx.com     uint8_t   size;
21*1555Smax.romanov@nginx.com     uint8_t   data[NXT_PORT_QUEUE_MSG_SIZE];
22*1555Smax.romanov@nginx.com } nxt_port_queue_item_t;
23*1555Smax.romanov@nginx.com 
24*1555Smax.romanov@nginx.com 
25*1555Smax.romanov@nginx.com typedef struct {
26*1555Smax.romanov@nginx.com     nxt_nncq_atomic_t      nitems;
27*1555Smax.romanov@nginx.com     nxt_nncq_t             free_items;
28*1555Smax.romanov@nginx.com     nxt_nncq_t             queue;
29*1555Smax.romanov@nginx.com     nxt_port_queue_item_t  items[NXT_PORT_QUEUE_SIZE];
30*1555Smax.romanov@nginx.com } nxt_port_queue_t;
31*1555Smax.romanov@nginx.com 
32*1555Smax.romanov@nginx.com 
33*1555Smax.romanov@nginx.com nxt_inline void
34*1555Smax.romanov@nginx.com nxt_port_queue_init(nxt_port_queue_t volatile *q)
35*1555Smax.romanov@nginx.com {
36*1555Smax.romanov@nginx.com     nxt_nncq_atomic_t  i;
37*1555Smax.romanov@nginx.com 
38*1555Smax.romanov@nginx.com     nxt_nncq_init(&q->free_items);
39*1555Smax.romanov@nginx.com     nxt_nncq_init(&q->queue);
40*1555Smax.romanov@nginx.com 
41*1555Smax.romanov@nginx.com     for (i = 0; i < NXT_PORT_QUEUE_SIZE; i++) {
42*1555Smax.romanov@nginx.com         nxt_nncq_enqueue(&q->free_items, i);
43*1555Smax.romanov@nginx.com     }
44*1555Smax.romanov@nginx.com 
45*1555Smax.romanov@nginx.com     q->nitems = 0;
46*1555Smax.romanov@nginx.com }
47*1555Smax.romanov@nginx.com 
48*1555Smax.romanov@nginx.com 
49*1555Smax.romanov@nginx.com nxt_inline nxt_int_t
50*1555Smax.romanov@nginx.com nxt_port_queue_send(nxt_port_queue_t volatile *q, const void *p, uint8_t size,
51*1555Smax.romanov@nginx.com     int *notify)
52*1555Smax.romanov@nginx.com {
53*1555Smax.romanov@nginx.com     nxt_nncq_atomic_t      i;
54*1555Smax.romanov@nginx.com     nxt_port_queue_item_t  *qi;
55*1555Smax.romanov@nginx.com 
56*1555Smax.romanov@nginx.com     i = nxt_nncq_dequeue(&q->free_items);
57*1555Smax.romanov@nginx.com     if (i == nxt_nncq_empty(&q->free_items)) {
58*1555Smax.romanov@nginx.com         *notify = 0;
59*1555Smax.romanov@nginx.com         return NXT_AGAIN;
60*1555Smax.romanov@nginx.com     }
61*1555Smax.romanov@nginx.com 
62*1555Smax.romanov@nginx.com     qi = (nxt_port_queue_item_t *) &q->items[i];
63*1555Smax.romanov@nginx.com 
64*1555Smax.romanov@nginx.com     qi->size = size;
65*1555Smax.romanov@nginx.com     nxt_memcpy(qi->data, p, size);
66*1555Smax.romanov@nginx.com 
67*1555Smax.romanov@nginx.com     nxt_nncq_enqueue(&q->queue, i);
68*1555Smax.romanov@nginx.com 
69*1555Smax.romanov@nginx.com     i = nxt_atomic_fetch_add(&q->nitems, 1);
70*1555Smax.romanov@nginx.com 
71*1555Smax.romanov@nginx.com     *notify = (i == 0);
72*1555Smax.romanov@nginx.com 
73*1555Smax.romanov@nginx.com     return NXT_OK;
74*1555Smax.romanov@nginx.com }
75*1555Smax.romanov@nginx.com 
76*1555Smax.romanov@nginx.com 
77*1555Smax.romanov@nginx.com nxt_inline ssize_t
78*1555Smax.romanov@nginx.com nxt_port_queue_recv(nxt_port_queue_t volatile *q, void *p)
79*1555Smax.romanov@nginx.com {
80*1555Smax.romanov@nginx.com     ssize_t                res;
81*1555Smax.romanov@nginx.com     nxt_nncq_atomic_t      i;
82*1555Smax.romanov@nginx.com     nxt_port_queue_item_t  *qi;
83*1555Smax.romanov@nginx.com 
84*1555Smax.romanov@nginx.com     i = nxt_nncq_dequeue(&q->queue);
85*1555Smax.romanov@nginx.com     if (i == nxt_nncq_empty(&q->queue)) {
86*1555Smax.romanov@nginx.com         return -1;
87*1555Smax.romanov@nginx.com     }
88*1555Smax.romanov@nginx.com 
89*1555Smax.romanov@nginx.com     qi = (nxt_port_queue_item_t *) &q->items[i];
90*1555Smax.romanov@nginx.com 
91*1555Smax.romanov@nginx.com     res = qi->size;
92*1555Smax.romanov@nginx.com     nxt_memcpy(p, qi->data, qi->size);
93*1555Smax.romanov@nginx.com 
94*1555Smax.romanov@nginx.com     nxt_nncq_enqueue(&q->free_items, i);
95*1555Smax.romanov@nginx.com 
96*1555Smax.romanov@nginx.com     nxt_atomic_fetch_add(&q->nitems, -1);
97*1555Smax.romanov@nginx.com 
98*1555Smax.romanov@nginx.com     return res;
99*1555Smax.romanov@nginx.com }
100*1555Smax.romanov@nginx.com 
101*1555Smax.romanov@nginx.com 
102*1555Smax.romanov@nginx.com #endif /* _NXT_PORT_QUEUE_H_INCLUDED_ */
103