mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-08-10 17:50:59 +03:00
feat: Introduce stable Bazel build
The initial migration to a Bazel based build. All attempts have been made to maintain configuration parity with the upstream build.
This commit is contained in:
parent
54eaed1d8b
commit
7f192e9919
29 changed files with 6564 additions and 1 deletions
156
examples/test_api.c
Normal file
156
examples/test_api.c
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <jemalloc/jemalloc.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
|
||||
void print_usage(const char* prog_name) {
|
||||
printf("Usage: %s [options]\n", prog_name);
|
||||
printf("Options:\n");
|
||||
printf(" -h, --help Show this help message\n");
|
||||
printf(" -v, --verbose Enable verbose output\n");
|
||||
printf(" --expect-stats-unavailable Expect stats to be unavailable (exit 0 if unavailable, 1 if not)\n");
|
||||
printf(" By default, test expects stats to be available\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* This function explicitly tests stats functionality and optionally prints available stats
|
||||
* which can be disabled with --disable-stats
|
||||
* Returns 0 if stats are available, 1 if stats are disabled
|
||||
*/
|
||||
int test_stats_functionality(int verbose) {
|
||||
size_t allocated, active, resident, metadata, mapped, retained;
|
||||
size_t sz = sizeof(size_t);
|
||||
int ret;
|
||||
|
||||
// Try to access stats.allocated - will fail if stats are disabled
|
||||
ret = mallctl("stats.allocated", &allocated, &sz, NULL, 0);
|
||||
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Stats error: Failed to get stats.allocated: %s (error code: %d)\n",
|
||||
strerror(ret), ret);
|
||||
if (ret == ENOENT) {
|
||||
fprintf(stderr, "This indicates jemalloc was compiled with --disable-stats\n");
|
||||
}
|
||||
return 1; // Stats are unavailable
|
||||
}
|
||||
|
||||
// Stats are available, print them if verbose mode
|
||||
if (verbose) {
|
||||
printf("\nJemalloc Memory Stats:\n");
|
||||
printf(" Allocated: %zu bytes (%.2f MB)\n", allocated, (double)allocated / (1024 * 1024));
|
||||
|
||||
// Get additional stats and print them when available
|
||||
if (mallctl("stats.active", &active, &sz, NULL, 0) == 0) {
|
||||
printf(" Active: %zu bytes (%.2f MB)\n", active, (double)active / (1024 * 1024));
|
||||
}
|
||||
|
||||
if (mallctl("stats.resident", &resident, &sz, NULL, 0) == 0) {
|
||||
printf(" Resident: %zu bytes (%.2f MB)\n", resident, (double)resident / (1024 * 1024));
|
||||
}
|
||||
|
||||
if (mallctl("stats.metadata", &metadata, &sz, NULL, 0) == 0) {
|
||||
printf(" Metadata: %zu bytes (%.2f MB)\n", metadata, (double)metadata / (1024 * 1024));
|
||||
}
|
||||
|
||||
if (mallctl("stats.mapped", &mapped, &sz, NULL, 0) == 0) {
|
||||
printf(" Mapped: %zu bytes (%.2f MB)\n", mapped, (double)mapped / (1024 * 1024));
|
||||
}
|
||||
|
||||
if (mallctl("stats.retained", &retained, &sz, NULL, 0) == 0) {
|
||||
printf(" Retained: %zu bytes (%.2f MB)\n", retained, (double)retained / (1024 * 1024));
|
||||
}
|
||||
}
|
||||
|
||||
return 0; // Stats are available
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int expect_stats_available = 1; // Default: expect stats to be available
|
||||
int verbose = 0; // Default: non-verbose output
|
||||
|
||||
// Define long options
|
||||
static struct option long_options[] = {
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"expect-stats-unavailable", no_argument, 0, 'u'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
// Parse command line options
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "hv", long_options, &option_index)) != -1) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
print_usage(argv[0]);
|
||||
return 0;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
case 'u':
|
||||
expect_stats_available = 0; // Expect stats to be unavailable
|
||||
break;
|
||||
default:
|
||||
print_usage(argv[0]);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Basic check to ensure jemalloc is loaded
|
||||
const char *version;
|
||||
size_t version_size = sizeof(version);
|
||||
if (mallctl("version", (void*)&version, &version_size, NULL, 0) != 0) {
|
||||
fprintf(stderr, "Error: mallctl 'version' failed. Jemalloc not loaded?\n");
|
||||
return 1; // Always fail if jemalloc isn't loaded
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
printf("Using jemalloc version: %s\n", version);
|
||||
}
|
||||
|
||||
// Perform some allocations to have something to measure
|
||||
const int num_allocs = 10;
|
||||
void* ptrs[num_allocs];
|
||||
for (int i = 0; i < num_allocs; i++) {
|
||||
// Allocate blocks of increasing size
|
||||
size_t size = 1024 * (i + 1);
|
||||
ptrs[i] = malloc(size);
|
||||
if (!ptrs[i]) {
|
||||
fprintf(stderr, "malloc failed for size %zu\n", size);
|
||||
return 1;
|
||||
}
|
||||
// Write some data to ensure pages are committed
|
||||
memset(ptrs[i], i, size);
|
||||
}
|
||||
|
||||
// Test stats functionality
|
||||
int stats_unavailable = test_stats_functionality(verbose);
|
||||
|
||||
// Clean up allocations
|
||||
for (int i = 0; i < num_allocs; i++) {
|
||||
free(ptrs[i]);
|
||||
}
|
||||
|
||||
// Determine exit code based on stats availability and expectation
|
||||
int exit_code;
|
||||
|
||||
if (expect_stats_available) {
|
||||
// Expecting stats to be available
|
||||
exit_code = stats_unavailable ? 1 : 0;
|
||||
} else {
|
||||
// Expecting stats to be unavailable
|
||||
exit_code = stats_unavailable ? 0 : 1;
|
||||
}
|
||||
|
||||
// Only print this if verbose mode is enabled
|
||||
if (verbose) {
|
||||
printf("\nStats %s - Test %s\n",
|
||||
stats_unavailable ? "UNAVAILABLE" : "AVAILABLE",
|
||||
exit_code == 0 ? "PASSED" : "FAILED");
|
||||
}
|
||||
|
||||
return exit_code;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue