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
nxt_port_queue_init(nxt_port_queue_t volatile * q)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
nxt_port_queue_send(nxt_port_queue_t volatile * q,const void * p,uint8_t size,int * notify)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
nxt_port_queue_recv(nxt_port_queue_t volatile * q,void * p)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