2 *------------------------------------------------------------------
3 * persist.c - persistent data structure storage test / demo code
5 * Copyright (c) 2013 Cisco and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
22 #include <sys/types.h>
25 #include <netinet/in.h>
32 #include <vppinfra/clib.h>
33 #include <vppinfra/vec.h>
34 #include <vppinfra/hash.h>
35 #include <vppinfra/bitmap.h>
36 #include <vppinfra/fifo.h>
37 #include <vppinfra/time.h>
38 #include <vppinfra/heap.h>
39 #include <vppinfra/pool.h>
40 #include <vppinfra/format.h>
41 #include <vppinfra/serialize.h>
49 persist_main_t persist_main;
59 demo_struct2_t *demo2;
64 * Data structures in persistent shared memory, all the time
67 persist_malloc (persist_main_t * pm)
69 demo_struct2_t *demo2;
70 demo_struct1_t *demo1;
71 time_t starttime = time (0);
72 char *datestring = ctime (&starttime);
75 /* Get back the root pointer */
76 demo1 = svmdb_local_get_variable_reference
77 (pm->c, SVMDB_NAMESPACE_VEC, "demo1_location");
79 /* It doesnt exist create our data structures */
82 /* If you want MP / thread safety, lock the region... */
83 pthread_mutex_lock (&pm->c->db_rp->mutex);
85 /* Switch to the shared memory region heap */
86 oldheap = svm_push_data_heap (pm->c->db_rp);
88 /* Allocate the top-level structure as a single element vector */
89 vec_validate (demo1, 0);
91 /* Allocate the next-level structure as a plain old memory obj */
92 demo2 = clib_mem_alloc (sizeof (*demo2));
95 demo1->name = format (0, "My name is Ishmael%c", 0);
96 demo2->string1 = format (0, "Here is string1%c", 0);
97 demo2->string2 = format (0, "Born at %s%c", datestring, 0);
99 /* Back to the process-private heap */
100 svm_pop_heap (oldheap);
101 pthread_mutex_unlock (&pm->c->db_rp->mutex);
104 * Set the root pointer. Note: this guy switches heaps, locks, etc.
105 * We allocated demo1 as a vector to make this "just work..."
107 svmdb_local_set_vec_variable (pm->c, "demo1_location",
108 demo1, sizeof (demo1));
113 /* retrieve and print data from shared memory */
114 demo2 = demo1->demo2;
115 fformat (stdout, "name: %s\n", demo1->name);
116 fformat (stdout, "demo2 location: %llx\n", demo2);
117 fformat (stdout, "string1: %s\n", demo2->string1);
118 fformat (stdout, "string2: %s\n", demo2->string2);
124 unserialize_demo1 (serialize_main_t * sm, va_list * args)
126 demo_struct1_t **result = va_arg (*args, demo_struct1_t **);
127 demo_struct1_t *demo1;
128 demo_struct2_t *demo2;
130 /* Allocate data structures in process private memory */
131 demo1 = clib_mem_alloc (sizeof (*demo1));
132 demo2 = clib_mem_alloc (sizeof (*demo2));
133 demo1->demo2 = demo2;
135 /* retrieve data from shared memory checkpoint */
136 unserialize_cstring (sm, (char **) &demo1->name);
137 unserialize_cstring (sm, (char **) &demo2->string1);
138 unserialize_cstring (sm, (char **) &demo2->string2);
143 serialize_demo1 (serialize_main_t * sm, va_list * args)
145 demo_struct1_t *demo1 = va_arg (*args, demo_struct1_t *);
146 demo_struct2_t *demo2 = demo1->demo2;
148 serialize_cstring (sm, (char *) demo1->name);
149 serialize_cstring (sm, (char *) demo2->string1);
150 serialize_cstring (sm, (char *) demo2->string2);
153 /* Serialize / unserialize variant */
155 persist_serialize (persist_main_t * pm)
160 demo_struct2_t *demo2;
161 demo_struct1_t *demo1;
162 time_t starttime = time (0);
163 char *datestring = ctime (&starttime);
165 /* Get back the root pointer */
166 checkpoint = svmdb_local_get_vec_variable (pm->c, "demo1_checkpoint",
169 /* It doesnt exist create our data structures */
172 /* Allocate data structures in process-private memory */
173 demo1 = clib_mem_alloc (sizeof (*demo2));
174 vec_validate (demo1, 0);
175 demo2 = clib_mem_alloc (sizeof (*demo2));
177 demo1->demo2 = demo2;
178 demo1->name = format (0, "My name is Ishmael%c", 0);
179 demo2->string1 = format (0, "Here is string1%c", 0);
180 demo2->string2 = format (0, "Born at %s%c", datestring, 0);
182 /* Create checkpoint */
183 serialize_open_vector (&sm, checkpoint);
184 serialize (&sm, serialize_demo1, demo1);
185 checkpoint = serialize_close_vector (&sm);
187 /* Copy checkpoint into shared memory */
188 svmdb_local_set_vec_variable (pm->c, "demo1_checkpoint",
189 checkpoint, sizeof (u8));
190 /* Toss the process-private-memory original.. */
191 vec_free (checkpoint);
195 /* Open the checkpoint */
196 unserialize_open_data (&sm, checkpoint, vec_len (checkpoint));
197 unserialize (&sm, unserialize_demo1, &demo1);
199 /* Toss the process-private-memory checkpoint copy */
200 vec_free (checkpoint);
203 demo2 = demo1->demo2;
204 fformat (stdout, "name: %s\n", demo1->name);
205 fformat (stdout, "demo2 location: %llx\n", demo2);
206 fformat (stdout, "string1: %s\n", demo2->string1);
207 fformat (stdout, "string2: %s\n", demo2->string2);
214 main (int argc, char **argv)
216 unformat_input_t _input, *input = &_input;
217 persist_main_t *pm = &persist_main;
218 clib_error_t *error = 0;
220 /* Make a 4mb database arena, chroot so it's truly private */
221 pm->c = svmdb_map_chroot_size ("/ptest", 4 << 20);
225 unformat_init_command_line (input, argv);
227 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
229 if (unformat (input, "malloc"))
230 error = persist_malloc (pm);
231 else if (unformat (input, "serialize"))
232 error = persist_serialize (pm);
235 error = clib_error_return (0, "Unknown flavor '%U'",
236 format_unformat_error, input);
245 clib_error_report (error);
252 * fd.io coding-style-patch-verification: ON
255 * eval: (c-set-style "gnu")