VPP-598: tcp stack initial commit
[vpp.git] / src / svm / svm_fifo_segment.c
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <svm/svm_fifo_segment.h>
17
18 svm_fifo_segment_main_t svm_fifo_segment_main;
19
20 /** (master) create an svm fifo segment */
21 int
22 svm_fifo_segment_create (svm_fifo_segment_create_args_t * a)
23 {
24   int rv;
25   svm_fifo_segment_private_t *s;
26   svm_fifo_segment_main_t *sm = &svm_fifo_segment_main;
27   ssvm_shared_header_t *sh;
28   svm_fifo_segment_header_t *fsh;
29   void *oldheap;
30
31   /* Allocate a fresh segment */
32   pool_get (sm->segments, s);
33   memset (s, 0, sizeof (*s));
34
35   s->ssvm.ssvm_size = a->segment_size;
36   s->ssvm.i_am_master = 1;
37   s->ssvm.my_pid = getpid ();
38   s->ssvm.name = (u8 *) a->segment_name;
39   s->ssvm.requested_va = sm->next_baseva;
40
41   rv = ssvm_master_init (&s->ssvm, s - sm->segments);
42
43   if (rv)
44     {
45       _vec_len (s) = vec_len (s) - 1;
46       return (rv);
47     }
48
49   /* Note; requested_va updated due to seg base addr randomization */
50   sm->next_baseva = s->ssvm.requested_va + a->segment_size;
51
52   sh = s->ssvm.sh;
53   oldheap = ssvm_push_heap (sh);
54
55   /* Set up svm_fifo_segment shared header */
56   fsh = clib_mem_alloc (sizeof (*fsh));
57   memset (fsh, 0, sizeof (*fsh));
58   sh->opaque[0] = fsh;
59   s->h = fsh;
60   fsh->segment_name = format (0, "%s%c", a->segment_name, 0);
61
62   /* Avoid vec_add1(...) failure when adding a fifo, etc. */
63   vec_validate (fsh->fifos, 64);
64   _vec_len (fsh->fifos) = 0;
65
66   ssvm_pop_heap (oldheap);
67
68   sh->ready = 1;
69   a->new_segment_index = s - sm->segments;
70   return (0);
71 }
72
73 /** (slave) attach to an svm fifo segment */
74 int
75 svm_fifo_segment_attach (svm_fifo_segment_create_args_t * a)
76 {
77   int rv;
78   svm_fifo_segment_private_t *s;
79   svm_fifo_segment_main_t *sm = &svm_fifo_segment_main;
80   ssvm_shared_header_t *sh;
81   svm_fifo_segment_header_t *fsh;
82
83   /* Allocate a fresh segment */
84   pool_get (sm->segments, s);
85
86   memset (s, 0, sizeof (*s));
87
88   s->ssvm.ssvm_size = a->segment_size;
89   s->ssvm.my_pid = getpid ();
90   s->ssvm.name = (u8 *) a->segment_name;
91   s->ssvm.requested_va = sm->next_baseva;
92
93   rv = ssvm_slave_init (&s->ssvm, sm->timeout_in_seconds);
94
95   if (rv)
96     {
97       _vec_len (s) = vec_len (s) - 1;
98       return (rv);
99     }
100
101   /* Fish the segment header */
102   sh = s->ssvm.sh;
103   fsh = (svm_fifo_segment_header_t *) sh->opaque[0];
104   s->h = fsh;
105
106   a->new_segment_index = s - sm->segments;
107   return (0);
108 }
109
110 void
111 svm_fifo_segment_delete (svm_fifo_segment_private_t * s)
112 {
113   svm_fifo_segment_main_t *sm = &svm_fifo_segment_main;
114   ssvm_delete (&s->ssvm);
115   pool_put (sm->segments, s);
116 }
117
118 svm_fifo_t *
119 svm_fifo_segment_alloc_fifo (svm_fifo_segment_private_t * s,
120                              u32 data_size_in_bytes)
121 {
122   ssvm_shared_header_t *sh;
123   svm_fifo_segment_header_t *fsh;
124   svm_fifo_t *f;
125   void *oldheap;
126
127   sh = s->ssvm.sh;
128   fsh = (svm_fifo_segment_header_t *) sh->opaque[0];
129   oldheap = ssvm_push_heap (sh);
130
131   /* Note: this can fail, in which case: create another segment */
132   f = svm_fifo_create (data_size_in_bytes);
133   if (f == 0)
134     {
135       ssvm_pop_heap (oldheap);
136       return (0);
137     }
138
139   vec_add1 (fsh->fifos, f);
140
141   ssvm_pop_heap (oldheap);
142   return (f);
143 }
144
145 void
146 svm_fifo_segment_free_fifo (svm_fifo_segment_private_t * s, svm_fifo_t * f)
147 {
148   ssvm_shared_header_t *sh;
149   svm_fifo_segment_header_t *fsh;
150   void *oldheap;
151   int i;
152
153   sh = s->ssvm.sh;
154   fsh = (svm_fifo_segment_header_t *) sh->opaque[0];
155   oldheap = ssvm_push_heap (sh);
156
157   for (i = 0; i < vec_len (fsh->fifos); i++)
158     {
159       if (fsh->fifos[i] == f)
160         {
161           vec_delete (fsh->fifos, 1, i);
162           goto found;
163         }
164     }
165   clib_warning ("fifo 0x%llx not found in fifo table...", f);
166
167 found:
168   clib_mem_free (f);
169   ssvm_pop_heap (oldheap);
170 }
171
172 void
173 svm_fifo_segment_init (u64 baseva, u32 timeout_in_seconds)
174 {
175   svm_fifo_segment_main_t *sm = &svm_fifo_segment_main;
176
177   sm->next_baseva = baseva;
178   sm->timeout_in_seconds = timeout_in_seconds;
179 }
180
181 u32
182 svm_fifo_segment_index (svm_fifo_segment_private_t * s)
183 {
184   return s - svm_fifo_segment_main.segments;
185 }
186
187 /*
188  * fd.io coding-style-patch-verification: ON
189  *
190  * Local Variables:
191  * eval: (c-set-style "gnu")
192  * End:
193  */