2 * Copyright (c) 2017 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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include <vppinfra/maplog.h>
19 clib_maplog_init (clib_maplog_main_t * mm, char *file_basename,
20 u64 file_size_in_bytes, u32 record_size_in_bytes)
25 u32 record_size_in_cache_lines;
26 u64 file_size_in_records;
28 /* Already initialized? */
29 if (mm->flags & CLIB_MAPLOG_FLAG_INIT)
32 memset (mm, 0, sizeof (*mm));
34 record_size_in_cache_lines =
35 (record_size_in_bytes + CLIB_CACHE_LINE_BYTES -
36 1) / CLIB_CACHE_LINE_BYTES;
38 file_size_in_records = file_size_in_bytes
39 / (record_size_in_cache_lines * CLIB_CACHE_LINE_BYTES);
41 /* Round up file size in records to a power of 2, for speed... */
42 mm->log2_file_size_in_records = max_log2 (file_size_in_records);
43 file_size_in_records = 1ULL << (mm->log2_file_size_in_records);
45 file_size_in_bytes = file_size_in_records * record_size_in_cache_lines
46 * CLIB_CACHE_LINE_BYTES;
48 mm->file_basename = format (0, "%s", file_basename);
49 mm->file_size_in_records = file_size_in_records;
50 mm->flags |= CLIB_MAPLOG_FLAG_INIT;
51 mm->record_size_in_cachelines = record_size_in_cache_lines;
54 for (i = 0; i < 2; i++)
56 mm->filenames[i] = format (0, "%v_%d", mm->file_basename,
57 mm->current_file_index++);
59 fd = open ((char *) mm->filenames[i], O_CREAT | O_RDWR | O_TRUNC, 0600);
66 if (lseek (fd, file_size_in_bytes - 1, SEEK_SET) == (off_t) - 1)
71 if (write (fd, &zero, 1) != 1)
77 mm->file_baseva[i] = mmap (0, file_size_in_bytes,
78 PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
79 if (mm->file_baseva[i] == (u8 *) MAP_FAILED)
81 clib_unix_warning ("mmap");
92 for (i = 0; i < 2; i++)
94 if (mm->file_baseva[i])
95 (void) munmap ((u8 *) mm->file_baseva[i], file_size_in_bytes);
101 _clib_maplog_get_entry_slowpath (clib_maplog_main_t * mm, u64 my_record_index)
106 u32 unmap_index = (mm->current_file_index) & 1;
107 u64 file_size_in_bytes = mm->file_size_in_records
108 * mm->record_size_in_cachelines * CLIB_CACHE_LINE_BYTES;
110 (void) munmap ((u8 *) mm->file_baseva[unmap_index], file_size_in_bytes);
111 vec_reset_length (mm->filenames[unmap_index]);
113 mm->filenames[unmap_index] = format (mm->filenames[unmap_index],
114 "%v_%d", mm->file_basename,
115 mm->current_file_index++);
117 fd = open ((char *) mm->filenames[unmap_index],
118 O_CREAT | O_RDWR | O_TRUNC, 0600);
119 /* $$$ this is not real error recovery... */
122 clib_unix_warning ("creat");
126 if (lseek (fd, file_size_in_bytes - 1, SEEK_SET) == (off_t) - 1)
128 clib_unix_warning ("lseek");
131 if (write (fd, &zero, 1) != 1)
133 clib_unix_warning ("set-size write");
137 mm->file_baseva[unmap_index] =
138 mmap (0, file_size_in_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
139 if (mm->file_baseva[unmap_index] == (u8 *) MAP_FAILED)
141 clib_unix_warning ("mmap");
147 mm->file_baseva[(my_record_index >> mm->log2_file_size_in_records) & 1] +
148 (my_record_index & (mm->file_size_in_records - 1))
149 * mm->record_size_in_cachelines * CLIB_CACHE_LINE_BYTES;
155 clib_maplog_close (clib_maplog_main_t * mm)
158 u64 file_size_in_bytes;
160 if (!(mm->flags & CLIB_MAPLOG_FLAG_INIT))
164 mm->file_size_in_records * mm->record_size_in_cachelines *
165 CLIB_CACHE_LINE_BYTES;
167 for (i = 0; i < 2; i++)
169 (void) munmap ((u8 *) mm->file_baseva[i], file_size_in_bytes);
170 vec_free (mm->filenames[i]);
173 vec_free (mm->file_basename);
174 memset (mm, 0, sizeof (*mm));
178 * fd.io coding-style-patch-verification: ON
181 * eval: (c-set-style "gnu")