Line data Source code
1 : #ifndef HEADER_fd_src_util_shmem_fd_shmem_h
2 : #define HEADER_fd_src_util_shmem_fd_shmem_h
3 :
4 : /* APIs for NUMA aware and page size aware manipulation of complex
5 : interprocess shared memory topologies. This API is designed to
6 : interoperate with the fd_shmem_cfg command and control script for
7 : host configuration. fd must be booted to use the APIs in this
8 : module. */
9 :
10 : #include "../log/fd_log.h"
11 :
12 : /* FD_SHMEM_JOIN_MAX gives the maximum number of unique fd shmem regions
13 : that can be in mapped concurrently into the thread group's local
14 : address space. Should be positive. Powers of two minus 1 have good
15 : Feng Shui but this is not strictly required. */
16 :
17 : #define FD_SHMEM_JOIN_MAX (255UL)
18 :
19 : /* FD_SHMEM_JOIN_MODE_* are used to specify how a memory region should
20 : be initially mapped into the thread group's local address space by
21 : fd_shmem_join. */
22 :
23 18 : #define FD_SHMEM_JOIN_MODE_READ_ONLY (0)
24 4437 : #define FD_SHMEM_JOIN_MODE_READ_WRITE (1)
25 :
26 : /* FD_SHMEM_{NUMA,CPU}_MAX give the maximum number of numa nodes and
27 : logical cpus supported by fd_shmem.
28 : FD_SHMEM_CPU_MAX>=FD_SHMEM_NUMA_MAX>0. */
29 :
30 444 : #define FD_SHMEM_NUMA_MAX (1024UL)
31 1385 : #define FD_SHMEM_CPU_MAX (1024UL)
32 :
33 : /* FD_SHMEM_{UNKNOWN,NORMAL,HUGE,GIGANTIC}_{PAGE_LG_SZ,PAGE_SZ} give the
34 : log2 page size / page size on a hosted x86 target. These are
35 : explicit to workaround various compiler limitations in common use
36 : cases. */
37 :
38 0 : #define FD_SHMEM_UNKNOWN_LG_PAGE_SZ (-1)
39 6 : #define FD_SHMEM_NORMAL_LG_PAGE_SZ (12)
40 0 : #define FD_SHMEM_HUGE_LG_PAGE_SZ (21)
41 0 : #define FD_SHMEM_GIGANTIC_LG_PAGE_SZ (30)
42 :
43 27 : #define FD_SHMEM_UNKNOWN_PAGE_SZ (0UL)
44 4290 : #define FD_SHMEM_NORMAL_PAGE_SZ (4096UL)
45 4473 : #define FD_SHMEM_HUGE_PAGE_SZ (2097152UL)
46 10281 : #define FD_SHMEM_GIGANTIC_PAGE_SZ (1073741824UL)
47 :
48 : /* FD_SHMEM_NAME_MAX gives the maximum number of bytes needed to hold
49 : the cstr with the name fd_shmem region. That is, a valid fd_shmem
50 : region name will have a strlen in [1,FD_SHMEM_NAME_MAX). (Harmonized
51 : with FD_LOG_NAME_MAX but this is not strictly required.) */
52 :
53 8835 : #define FD_SHMEM_NAME_MAX FD_LOG_NAME_MAX
54 :
55 : /* FD_SHMEM_PAGE_SZ_CSTR_MAX is the size of a buffer large enough to
56 : hold an shmem page sz cstr (==strlen("gigantic")+1). */
57 :
58 : #define FD_SHMEM_PAGE_SZ_CSTR_MAX (9UL)
59 :
60 : /* fd_shmem_private_key_t is for internal use (tmpl/fd_map
61 : interoperability). */
62 :
63 : struct fd_shmem_private_key {
64 : char cstr[ FD_SHMEM_NAME_MAX ];
65 : };
66 :
67 : typedef struct fd_shmem_private_key fd_shmem_private_key_t;
68 :
69 : /* A fd_shmem_join_info_t used by various APIs to provide low level
70 : details about a join. */
71 :
72 : struct fd_shmem_join_info {
73 : long ref_cnt; /* Number of joins, -1L indicates a join/leave is in progress.
74 : Will be -1 the join is in join/leave func and positive otherwise. */
75 : void * join; /* Local join handle (i.e. what join_func returned). Will be NULL in a call join func. */
76 : void * shmem; /* Location in the thread group local address space of name. Will be non-NULL and page_sz aligned. */
77 : ulong page_sz; /* Page size used for the region. Will be a supported page size (e.g. non-zero integer power-of-two) */
78 : ulong page_cnt; /* Number of pages in the region. Will be non-zero, page_sz*page_cnt will not overflow */
79 : int mode; /* Will be in FD_SHMEM_JOIN_MODE_{READ_ONLY,READ_WRITE}. Attempting to execute and (if read-only) write in the
80 : shmem region will fault the thread group. */
81 : uint hash; /* Will be (uint)fd_hash( 0UL, name, FD_SHMEM_NAME_MAX ) */
82 : union {
83 : char name[ FD_SHMEM_NAME_MAX ]; /* cstr with the region name at join time (guaranteed '\0' terminated) */
84 : fd_shmem_private_key_t key; /* For easy interoperability tmpl/fd_map.h */
85 : };
86 : };
87 :
88 : typedef struct fd_shmem_join_info fd_shmem_join_info_t;
89 :
90 : /* A fd_shmem_joinleave_func_t is optionally used by fd_shmem_join /
91 : fd_shmem_leave to wrap / unwrap a shared memory region with
92 : additional thread group local context when it is mapped / unmapped. */
93 :
94 : typedef void *
95 : (*fd_shmem_joinleave_func_t)( void * context,
96 : fd_shmem_join_info_t const * join_info );
97 :
98 : /* A fd_shmem_info_t used by various APIs to provide low level details
99 : of a shared memory region. */
100 :
101 : struct fd_shmem_info {
102 : ulong page_sz; /* page size of the region, will be a supported page size (e.g. non-zero, integer power of two) */
103 : ulong page_cnt; /* number of pages in the region, will be positive, page_sz*page_cnt will not overflow */
104 : };
105 :
106 : typedef struct fd_shmem_info fd_shmem_info_t;
107 :
108 : FD_PROTOTYPES_BEGIN
109 :
110 : /* User APIs **********************************************************/
111 :
112 : /* fd_shmem_{join,leave} joins/leaves the caller to/from a named fd
113 : shared memory region.
114 :
115 : It is very convenient to be able to join the same region multiple
116 : times within a thread group. And it is safe and reasonably efficient
117 : to do so (O(1) but neither lockfree nor ultra HPC). To facilitate
118 : this, when a join requires mapping the region into the thread group's
119 : local address space (e.g. the first join to the region in the thread
120 : group), this will try to discover the page size that is backing the
121 : region (if there multiple regions with same name, this will try to
122 : join the one backed by the largest page size). Then the region is
123 : mapped into the address appropriately for the given access mode
124 : (FD_SHMEM_JOIN_MODE_{READ_ONLY,READ_WRITE}). Then the region is
125 : marked as MADVISE_DONTDUMP if the dump flag is 0. Lastly, any user
126 : provided fd_shmem_join_func_t is called on the mapping.
127 :
128 : A fd_shmem_join_func_t is meant to do any additional local address
129 : translations and what not as a one-time upfront cost on behalf of all
130 : subsequent joins. It is called if the underlying shared memory needs
131 : to be mapped into the thread group's address space and ignored
132 : otherwise. The input to a join_func is a pointer to any user context
133 : (i.e. the context passed to fd_shmem_join) and a pointer to
134 : information about the region (lifetime is the duration of the call
135 : and should not be assumed to be longer).
136 :
137 : On success, a join_func returns the join that wraps the shmem (often
138 : just a shmem); it should be one-to-one with shmem (i.e. while a
139 : thread group is joined, name cstr / shmem / join uniquely identify
140 : the name cstr / shmem / join). On failure, a join_func returns NULL
141 : (ideally without impacting thread group state while logging details
142 : about the failure).
143 :
144 : Pass NULL for join_func if no special handling is needed. The join
145 : handle will be just a pointer to the first byte of the region's local
146 : mapping.
147 :
148 : All joins should be paired with a leave.
149 :
150 : On success, if opt_info is non-NULL, *opt_info will also provide
151 : additional details about the join (i.e. the same details one would
152 : get if querying the join atomically with respect to join operations
153 : immediately afterward). On failure, *opt_info is ignored.
154 :
155 : fd_shmem_leave is just the inverse of this. It can fail for a few
156 : reasons, including if the mmap cannot be close()'d for any reason.
157 : IT will log extensive details if there is any wonkiness under the
158 : hood. The caller may wish to proceed even if it fails.
159 :
160 : IMPORTANT! It is safe to have join/leave functions themselves call
161 : fd_shmem_join/fd_shmem_leave to join additional regions as necessary.
162 : This allows very complex interdependent shared memory topologies to
163 : be constructed in a natural way. The only restriction (beyond the
164 : total number of regions that can be joined) is that there can't be
165 : join/leave cycles (e.g. fd_shmem_join("region1") calls join_func
166 : region1_join("region1") which calls fd_shmem_join("region2") which
167 : calls join_func region2_join("region2") which calls
168 : shmem_join("region1")). Such cycles will be detected, logged and
169 : failed. */
170 :
171 : void *
172 : fd_shmem_join( char const * name,
173 : int mode,
174 : int dump,
175 : fd_shmem_joinleave_func_t join_func,
176 : void * context,
177 : fd_shmem_join_info_t * opt_info );
178 :
179 : int
180 : fd_shmem_leave( void * join,
181 : fd_shmem_joinleave_func_t leave_func,
182 : void * context );
183 :
184 : /* FIXME: CONSIDER OPTION FOR SLIGHTLY MORE ALGO EFFICIENT LEAVE BY NAME
185 : VARIANT? */
186 :
187 : /* fd_shmem_join_query_by_{name,join,addr} queries if the cstr pointed
188 : by name is already joined by the caller's thread group / the join
189 : handle is a valid current join handle / [addr,addr+sz-1] overlaps (at
190 : least partially) with a shared memory region of a current join.
191 :
192 : On success, returns 0 and, if opt_info non-NULL, *opt_info will hold
193 : details about the join (as observed at a point between when the call
194 : was made and when it returned). On failure, returns a non-zero
195 : strerror friendly error code (these do not log anything so they can
196 : be use in situations where the query might fail in normal operation
197 : without being excessively chatty in the log). Reasons for failure
198 : include name is not valid (EINVAL) and there is no join currently
199 : (ENOENT).
200 :
201 : For query_by_addr, returns ENOENT if sz is 0 (no overlap with an
202 : empty set) and EINVAL if the address range wraps around the end of
203 : address space. If there are multiple joins overlapped by the range,
204 : returns 0 and, if opt_info is non-NULL, *opt_info will have details
205 : about one of the joins (it is undefined which join). Note it is
206 : impossible for a range to overlap multiple joins when sz==1.
207 :
208 : query by name is a reasonably fast O(1). query by join and by addr
209 : are theoretically O(FD_SHMEM_JOIN_MAX) but still quite fast
210 : practically. */
211 :
212 : int
213 : fd_shmem_join_query_by_name( char const * name,
214 : fd_shmem_join_info_t * opt_info );
215 :
216 : int
217 : fd_shmem_join_query_by_join( void const * join,
218 : fd_shmem_join_info_t * opt_info );
219 :
220 : int
221 : fd_shmem_join_query_by_addr( void const * addr,
222 : ulong sz,
223 : fd_shmem_join_info_t * opt_info );
224 :
225 : /* fd_shmem_join_anonymous treats with region pointed to by mem (which
226 : must be non-NULL with page_sz alignment and page_sz*page_cnt
227 : footprint) as a shmem join with the local join handle join, cstr name
228 : and mode.
229 :
230 : Other code in the thread group can fd_shmem_join( name, ... ) as
231 : though the fd_shmem_join_anonymous was done for the mapping join for
232 : name in the thread group. This is useful to allow memory regions
233 : procured out-of-band (e.g. a private anonymous mmap, interfacing with
234 : custom hardware that provides its own functions for getting access to
235 : its memory, etc) as a normal join.
236 :
237 : Returns 0 on success and a strerror friendly error code on failure
238 : (logs details). Reasons for failure include EINVAL: bad name (NULL /
239 : too short / too long / bad characters / already joined), bad join
240 : (NULL join / already joined), bad mem (NULL mem / unaligned mem /
241 : already joined), unsupported page_sz, zero page cnt, unsupported mode
242 : (not FD_SHMEM_JOIN_MODE_{READ_ONLY,READ_WRITE}.
243 :
244 : This will shadow any named shared memory region in the calling thread
245 : group (but not other thread groups).
246 :
247 : fd_shmem_leave_anonymous is just the inverse of this. Returns 0 on
248 : success and a non-zero strerror friendly error code on failure (logs
249 : details on failure). On success, if opt_info is non-NULL, *opt_info
250 : will contain details about the former join (e.g. determine details
251 : like the original name, mode, mem, page_sz and page_cnt of the join,
252 : ... opt_info->ref_cnt will be zero). It is untouched otherwise.
253 : Reasons for failure include EINVAL: join is obviously not an
254 : anonymous join with a reference count of 1.
255 :
256 : IMPORTANT! The join will have a ref cnt of 1 on return from
257 : join_anonymous. The final leave of something joined by
258 : fd_shmem_join_anonymous should done only by fd_shmem_leave_anonymous.
259 : Conversely, fd_shmem_leave_anonymous should only be used for the
260 : final leave of any anonymous join. */
261 :
262 : int
263 : fd_shmem_join_anonymous( char const * name,
264 : int mode,
265 : void * join,
266 : void * mem,
267 : ulong page_sz,
268 : ulong page_cnt );
269 :
270 : int
271 : fd_shmem_leave_anonymous( void * join,
272 : fd_shmem_join_info_t * opt_info );
273 :
274 : /* Administrative APIs ************************************************/
275 :
276 : /* Numa topology API */
277 :
278 : /* fd_shmem_{numa,cpu}_cnt returns the number of numa nodes / logical
279 : cpus configured in system. numa nodes are indexed in
280 : [0,fd_shmem_numa_cnt()) where fd_shmem_numa_cnt() is in
281 : [1,FD_SHMEM_NUMA_MAX] and similarly for logical cpus. This value is
282 : determined at thread group boot. cpu_cnt>=numa_cnt. */
283 :
284 : FD_FN_PURE ulong fd_shmem_numa_cnt( void );
285 : FD_FN_PURE ulong fd_shmem_cpu_cnt ( void );
286 :
287 : /* fd_shmem_numa_idx returns the closest numa node to the given logical
288 : cpu_idx. Given a cpu_idx in [0,fd_shmem_cpu_cnt()), returns a value
289 : in [0,fd_shmem_numa_cnt()). Returns ULONG_MAX otherwise. The cpu ->
290 : numa mapping is determined at thread group boot. */
291 :
292 : FD_FN_PURE ulong fd_shmem_numa_idx( ulong cpu_idx );
293 :
294 : /* fd_shmem_cpu_idx returns the smallest cpu_idx of a cpu close to
295 : numa_idx. Given a numa_idx in [0,fd_shmem_numa_cnt()), returns a
296 : value in [0,fd_shmem_cpu_cnt()). Returns ULONG_MAX otherwise. The
297 : numa -> cpu mapping is determined at thread group boot. */
298 :
299 : FD_FN_PURE ulong fd_shmem_cpu_idx( ulong numa_idx );
300 :
301 : /* fd_shmem_numa_validate returns 0 if all the pages in the page_cnt
302 : page_sz pages pointed to by mem are on a numa node near cpu_idx and a
303 : strerror friendly non-zero error code otherwise (logs details).
304 : Pages in mem will be queried (potentially non-atomically) over some
305 : point in time between when the call was made and when the call
306 : returns. */
307 :
308 : int
309 : fd_shmem_numa_validate( void const * mem,
310 : ulong page_sz,
311 : ulong page_cnt,
312 : ulong cpu_idx );
313 :
314 : /* Creation/destruction APIs */
315 :
316 : /* fd_shmem_create_multi creates a shared memory region whose name is
317 : given by the cstr pointed to by name backed by page_sz pages. The
318 : region will consist of sub_cnt subregions, indexed [0,sub_cnt). Each
319 : subregion will have page_cnt pages near cpu_idx and the region will
320 : be the concatenation of these subregions in the order specified.
321 : mode specifies the permissions for this region (the usual POSIX open
322 : umask caveats apply).
323 :
324 : Returns 0 on success and an strerror friendly error code on failure
325 : (also logs extensive details on error). Reasons for failure include
326 : name is invalid (EINVAL), page_sz is invalid (EINVAL), page_cnt is
327 : zero (EINVAL), cnt*page_sz overflows an off_t (EINVAL), open fails
328 : (errno of the open, e.g. region with the same name and page_sz in the
329 : thread domain already exists), ftruncate fails (errno of ftruncate,
330 : e.g. no suitable memory available near cpu_idx), etc.
331 :
332 : Note that each page_sz has its own namespace. As such, names are
333 : unique over caller's shared memory domain for a given page_sz. Names
334 : can be reused between two different page_sz (and such will correspond
335 : to two unrelated mappings). Generally, it is a good idea to have
336 : unique names over all page_sz but this is not strictly required (the
337 : APIs may not work particularly well in this case though).
338 :
339 : fd_shmem_create is a simple wrapper around fd_shmem_create_multi for
340 : applications that just want to create a shared memory region that
341 : contains only 1 subregion. */
342 :
343 : int /* 0 on success, strerror compatible error code on failure */
344 : fd_shmem_create_multi( char const * name, /* Should point to cstr with a valid name for a shared memory region */
345 : ulong page_sz, /* Should be a FD_SHMEM_{NORMAL,HUGE,GIGANTIC}_PAGE_SZ */
346 : ulong sub_cnt, /* Should be positive */
347 : ulong const * sub_page_cnt, /* Indexed [0,sub_cnt), 0 < sum(page_cnt)*page_sz <= ULONG_MAX */
348 : ulong const * sub_cpu_idx, /* Indexed [0,sub_cnt), each should be in [0,fd_shmem_cpu_cnt()) */
349 : ulong mode ); /* E.g. 0660 for user rw, group rw, world none */
350 :
351 : /* fd_shmem_update_multi updates a shared memory region created by
352 : fd_shmem_create_multi in place, to be as-if it was created with
353 : the provided parameters instead.
354 :
355 : This can be preferable to deleting and recreating the shmem region
356 : because it prevents needing to zero all of the underlying memory.
357 :
358 : WARNING: The memory returned will not be zeroed and the user will
359 : be able to read any contents that were in the previous workspace. */
360 :
361 : int
362 : fd_shmem_update_multi( char const * name,
363 : ulong page_sz,
364 : ulong sub_cnt,
365 : ulong const * sub_page_cnt,
366 : ulong const * sub_cpu_idx,
367 : ulong mode );
368 :
369 : static inline int
370 : fd_shmem_create( char const * name,
371 : ulong page_sz,
372 : ulong page_cnt,
373 : ulong cpu_idx,
374 0 : ulong mode ) {
375 0 : return fd_shmem_create_multi( name, page_sz, 1UL, &page_cnt, &cpu_idx, mode );
376 0 : }
377 :
378 : /* fd_shmem_unlink removes the name of the page_sz backed shared memory
379 : region in the thread group's shared memory domain such that it can no
380 : longer be mapped into a thread group's address space. The pages used
381 : for that region will be freed once there are no longer in use by any
382 : existing thread group.
383 :
384 : Return 0 on success and strerror friendly error code on failure (also
385 : logs extensive details on error). Reasons for failure include name
386 : is invalid (EINVAL), page_sz is invalid (EINVAL), unlink failed
387 : (error of the unlink, e.g. there is no region backed by page_sz pages
388 : in the thread group's shared memory domain currently with that name),
389 : etc. */
390 :
391 : int
392 : fd_shmem_unlink( char const * name,
393 : ulong page_sz );
394 :
395 : /* fd_shmem_info returns info about the given page_sz backed shared
396 : memory region in the thread groups' shared memory domain. If the
397 : page_sz is zero, the page size will be discovered. If there are
398 : multiple regions with different page sizes but the same name, the
399 : region backed by the largest (non-atomic) page size will be queried.
400 :
401 : Returns 0 on success and a strerror friendly error code on failure
402 : (logs extensive details on error with the exception of ENOENT / there
403 : is no region with that name so that existence checks can be done
404 : without generating excessive log chatter). Reasons for failure
405 : include name is invalid (EINVAL), page_sz is invalid (EINVAL), open
406 : failed (error of the open, e.g. there is no region), stat failed
407 : (error of the stat) or the mounts have been corrupted (EFAULT).
408 :
409 : On success, if opt_buf is non-NULL, *opt_buf will contain additional
410 : metadata about the region as observed at some point between when the
411 : call was made and when it returned. On failure, *opt_buf not be
412 : touched. */
413 :
414 : int
415 : fd_shmem_info( char const * name,
416 : ulong page_sz,
417 : fd_shmem_info_t * opt_info );
418 :
419 : /* Raw page allocation */
420 :
421 : /* fd_shmem_acquire_multi acquires the page_sz pages to create a memory
422 : region for the private use of the caller's thread group. The region
423 : will consist of sub_cnt subregions, indexed [0,sub_cnt). Each
424 : subregion will have page_cnt pages near cpu_idx and the region will
425 : be the concatenation of these subregions in the order specified.
426 : The lifetime of a page in the allocation is until the thread group
427 : terminates or the page is explicitly released. Returns a pointer to
428 : the location in the local address space of the mapped pages on
429 : success and NULL on failure (logs details). Reasons for failure
430 : include page_sz is invalid, page_cnt is zero, cnt*page_sz overflows
431 : an off_t, etc.
432 :
433 : fd_shmem_acquire is a simple wrapper around fd_shmem_acquire_multi
434 : for applications that just want to a create a shared memory region
435 : that contains only 1 subregion. */
436 :
437 : void *
438 : fd_shmem_acquire_multi( ulong page_sz, /* Should be a FD_SHMEM_{NORMAL,HUGE,GIGANTIC}_PAGE_SZ */
439 : ulong sub_cnt, /* Should be positive */
440 : ulong const * sub_page_cnt, /* Indexed [0,sub_cnt), 0 < sum(page_cnt)*page_sz <= ULONG_MAX */
441 : ulong const * sub_cpu_idx ); /* Indexed [0,sub_cnt), each should be in [0,fd_shmem_cpu_cnt()) */
442 :
443 : static inline void *
444 : fd_shmem_acquire( ulong page_sz,
445 : ulong page_cnt,
446 36 : ulong cpu_idx ) {
447 36 : return fd_shmem_acquire_multi( page_sz, 1UL, &page_cnt, &cpu_idx );
448 36 : }
449 :
450 : /* fd_shmem_release releases page_cnt page_sz pages of memory allocated
451 : by fd_shmem_acquire. This always succeeds from the caller's POV but
452 : logs details if there is any wonkiness under the hood. It is fine to
453 : release subregions of individual previous acquisitions.
454 :
455 : Returns 0 if successful, -1 for any errors. */
456 :
457 : int
458 : fd_shmem_release( void * mem,
459 : ulong page_sz,
460 : ulong page_cnt );
461 :
462 : /* Parsing APIs */
463 :
464 : /* fd_shmem_name_len: If name points at a cstr holding a valid name,
465 : returns strlen( name ) (which is guaranteed to be in
466 : [1,FD_SHMEM_NAME_MAX)). Returns 0 otherwise (e.g. name is NULL, name
467 : is too short, name is too long, name contains characters other than
468 : [0-9,A-Z,a-z,'_','-','.'], name doesn't start with a [0-9,A-Z,a-z],
469 : etc). */
470 :
471 : FD_FN_PURE ulong fd_shmem_name_len( char const * name );
472 :
473 : /* fd_shmem_page_sz_valid: Returns 1 if page_sz is a valid page size
474 : or 0 otherwise. */
475 :
476 : FD_FN_CONST static inline int
477 3633 : fd_shmem_is_page_sz( ulong page_sz ) {
478 3633 : return (page_sz==FD_SHMEM_NORMAL_PAGE_SZ) | (page_sz==FD_SHMEM_HUGE_PAGE_SZ) | (page_sz==FD_SHMEM_GIGANTIC_PAGE_SZ);
479 3633 : }
480 :
481 : /* fd_cstr_to_shmem_lg_page_sz: Convert a cstr pointed to by cstr to
482 : a shmem log2 page size (guaranteed to be one of
483 : FD_SHMEM_*_LG_PAGE_SZ) via case insensitive comparison with various
484 : tokens and (if none match) fd_cstr_to_int. Returns
485 : FD_SHMEM_UNKNOWN_LG_PAGE_SZ (-1 ... the only negative return
486 : possible) if it can't figure this out. */
487 :
488 : FD_FN_PURE int
489 : fd_cstr_to_shmem_lg_page_sz( char const * cstr );
490 :
491 : /* fd_shmem_lg_page_sz_to_cstr: Return a pointer to a cstr
492 : corresponding to a shmem log2 page sz. The pointer is guaranteed to
493 : be non-NULL with an infinite lifetime. If lg_page_sz is not a valid
494 : shmem log2 page size, the cstr will be "unknown". Otherwise, the
495 : returned cstr is guaranteed to be compatible with
496 : fd_cstr_to_shmem_lg_page_sz / fd_cstr_to_shmem_page_sz. strlen of
497 : the returned result will be in in [1,FD_SHMEM_PAGE_SZ_CSTR_MAX]. */
498 :
499 : FD_FN_CONST char const *
500 : fd_shmem_lg_page_sz_to_cstr( int lg_page_sz );
501 :
502 : /* fd_cstr_to_shmem_page_sz: Convert a cstr pointed to by cstr to a
503 : shmem page size (guaranteed to be one of the FD_SHMEM_*_PAGE_SZ
504 : values) via case insensitive comparison with various token and (if
505 : non match) via fd_cstr_to_ulong. Returns FD_SHMEM_UNKNOWN_PAGE_SZ
506 : (0UL, the only non-integral power of 2 return possible) if it can't
507 : figure this out. */
508 :
509 : FD_FN_PURE ulong
510 : fd_cstr_to_shmem_page_sz( char const * cstr );
511 :
512 : /* fd_shmem_page_sz_to_cstr: Return a pointer to a cstr corresponding
513 : to a shmem page sz. The pointer is guaranteed to be non-NULL with an
514 : infinite lifetime. If page_sz is not a valid shmem page size, the
515 : cstr will be "unknown". Otherwise, the returned cstr is guaranteed
516 : to be compatible with fd_cstr_to_shmem_lg_page_sz /
517 : fd_cstr_to_shmem_page_sz. strlen of the returned result in
518 : [1,FD_SHMEM_PAGE_SZ_CSTR_MAX]. */
519 :
520 : FD_FN_CONST char const *
521 : fd_shmem_page_sz_to_cstr( ulong page_sz );
522 :
523 : /* fd_shmem_iter_begin returns a pointer to the first join info in the
524 : process. Returns NULL if there are no more joins. */
525 :
526 : fd_shmem_join_info_t const * fd_shmem_iter_begin( void );
527 :
528 : /* fd_shmem_iter_next returns the next join info in the process.
529 : Returns NULL if there are no more joins */
530 :
531 : fd_shmem_join_info_t const * fd_shmem_iter_next( fd_shmem_join_info_t const * iter );
532 :
533 0 : static inline int fd_shmem_iter_done( fd_shmem_join_info_t const * iter ) {
534 0 : return (iter == NULL);
535 0 : }
536 :
537 : /* These functions are for fd_shmem internal use only. */
538 :
539 : void
540 : fd_shmem_private_boot( int * pargc,
541 : char *** pargv );
542 :
543 : void
544 : fd_shmem_private_halt( void );
545 :
546 : FD_PROTOTYPES_END
547 :
548 : #endif /* HEADER_fd_src_util_shmem_fd_shmem_h */
|