tools/testing/selftests/vDSO/vdso_test_getrandom.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/vDSO/vdso_test_getrandom.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/vDSO/vdso_test_getrandom.c- Extension
.c- Size
- 8946 bytes
- Lines
- 323
- Domain
- Support Tooling And Documentation
- Bucket
- tools
- Inferred role
- Support Tooling And Documentation: implementation source
- Status
- source implementation candidate
Why This File Exists
Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
assert.hpthread.hstdint.hstdio.hstdlib.hstring.htime.hunistd.hsched.hsignal.hsys/auxv.hsys/mman.hsys/random.hsys/syscall.hsys/ptrace.hsys/wait.hsys/types.hlinux/random.hlinux/ptrace.hkselftest.hparse_vdso.hvdso_config.hvdso_call.h
Detected Declarations
function vgetrandom_put_statefunction vgetrandom_initfunction vgetrandomfunction bench_singlefunction bench_multifunction fillfunction kselftestfunction usagefunction main
Annotated Snippet
if ((vsp)->tv_nsec < 0) { \
(vsp)->tv_sec--; \
(vsp)->tv_nsec += 1000000000L; \
} \
} while (0)
#endif
#define ksft_assert(condition) \
do { if (!(condition)) ksft_exit_fail_msg("Assertion failed: %s\n", #condition); } while (0)
static struct {
pthread_mutex_t lock;
void **states;
size_t len, cap;
ssize_t(*fn)(void *, size_t, unsigned long, void *, size_t);
struct vgetrandom_opaque_params params;
} vgrnd = {
.lock = PTHREAD_MUTEX_INITIALIZER
};
static void *vgetrandom_get_state(void)
{
void *state = NULL;
pthread_mutex_lock(&vgrnd.lock);
if (!vgrnd.len) {
size_t page_size = getpagesize();
size_t new_cap;
size_t alloc_size, num = sysconf(_SC_NPROCESSORS_ONLN); /* Just a decent heuristic. */
size_t state_size_aligned, cache_line_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE) ?: 1;
void *new_block, *new_states;
state_size_aligned = (vgrnd.params.size_of_opaque_state + cache_line_size - 1) & (~(cache_line_size - 1));
alloc_size = (num * state_size_aligned + page_size - 1) & (~(page_size - 1));
num = (page_size / state_size_aligned) * (alloc_size / page_size);
new_block = mmap(0, alloc_size, vgrnd.params.mmap_prot, vgrnd.params.mmap_flags, -1, 0);
if (new_block == MAP_FAILED)
goto out;
new_cap = vgrnd.cap + num;
new_states = reallocarray(vgrnd.states, new_cap, sizeof(*vgrnd.states));
if (!new_states)
goto unmap;
vgrnd.cap = new_cap;
vgrnd.states = new_states;
for (size_t i = 0; i < num; ++i) {
if (((uintptr_t)new_block & (page_size - 1)) + vgrnd.params.size_of_opaque_state > page_size)
new_block = (void *)(((uintptr_t)new_block + page_size - 1) & (~(page_size - 1)));
vgrnd.states[i] = new_block;
new_block += state_size_aligned;
}
vgrnd.len = num;
goto success;
unmap:
munmap(new_block, alloc_size);
goto out;
}
success:
state = vgrnd.states[--vgrnd.len];
out:
pthread_mutex_unlock(&vgrnd.lock);
return state;
}
__attribute__((unused)) /* Example for libc implementors */
static void vgetrandom_put_state(void *state)
{
if (!state)
return;
pthread_mutex_lock(&vgrnd.lock);
vgrnd.states[vgrnd.len++] = state;
pthread_mutex_unlock(&vgrnd.lock);
}
static void vgetrandom_init(void)
{
const char *version = versions[VDSO_VERSION];
const char *name = names[VDSO_NAMES][6];
unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
ssize_t ret;
if (!sysinfo_ehdr)
ksft_exit_skip("AT_SYSINFO_EHDR is not present\n");
vdso_init_from_sysinfo_ehdr(sysinfo_ehdr);
vgrnd.fn = (__typeof__(vgrnd.fn))vdso_sym(version, name);
if (!vgrnd.fn)
ksft_exit_skip("%s@%s symbol is missing from vDSO\n", name, version);
Annotation
- Immediate include surface: `assert.h`, `pthread.h`, `stdint.h`, `stdio.h`, `stdlib.h`, `string.h`, `time.h`, `unistd.h`.
- Detected declarations: `function vgetrandom_put_state`, `function vgetrandom_init`, `function vgetrandom`, `function bench_single`, `function bench_multi`, `function fill`, `function kselftest`, `function usage`, `function main`.
- Atlas domain: Support Tooling And Documentation / tools.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.