65 lines
2.0 KiB
C
65 lines
2.0 KiB
C
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <stdint.h>
|
|
#include <pthread.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
/* 校准探针:正常释放、失败 realloc、零大小释放和已知的 37 字节残留。 */
|
|
static void *volatile retained;
|
|
static pthread_barrier_t start;
|
|
|
|
static void exercise(void) {
|
|
for (int index = 0; index < 1000; index++) {
|
|
void *first = malloc(10);
|
|
assert(first);
|
|
first = realloc(first, 20);
|
|
assert(first);
|
|
void *second = calloc(2, 16);
|
|
assert(second);
|
|
volatile size_t impossible = SIZE_MAX;
|
|
assert(realloc(first, impossible) == NULL);
|
|
free(second);
|
|
assert(realloc(first, 0) == NULL);
|
|
void *aligned = NULL;
|
|
assert(posix_memalign(&aligned, 64, 96) == 0);
|
|
assert((uintptr_t)aligned % 64 == 0);
|
|
void *original = aligned;
|
|
errno = E2BIG;
|
|
assert(posix_memalign(&aligned, 3, 96) == EINVAL);
|
|
assert(aligned == original && errno == E2BIG);
|
|
assert(posix_memalign(&aligned, 64, impossible) == ENOMEM);
|
|
assert(aligned == original && errno == E2BIG);
|
|
free(aligned);
|
|
}
|
|
}
|
|
|
|
static void *worker(void *input) {
|
|
pthread_barrier_wait(&start);
|
|
free(input);
|
|
exercise();
|
|
return NULL;
|
|
}
|
|
|
|
int main(int count, char **arguments) {
|
|
int concurrent = count > 1 && strcmp(arguments[1], "threads") == 0;
|
|
if (concurrent) {
|
|
pthread_t workers[4];
|
|
assert(pthread_barrier_init(&start, NULL, 5) == 0);
|
|
for (size_t index = 0; index < 4; index++) {
|
|
void *input = malloc(16);
|
|
assert(input);
|
|
assert(pthread_create(&workers[index], NULL, worker, input) == 0);
|
|
}
|
|
pthread_barrier_wait(&start);
|
|
for (size_t index = 0; index < 4; index++) {
|
|
assert(pthread_join(workers[index], NULL) == 0);
|
|
}
|
|
assert(pthread_barrier_destroy(&start) == 0);
|
|
} else {
|
|
exercise();
|
|
}
|
|
if (count > (concurrent ? 2 : 1)) retained = malloc(37);
|
|
return 0;
|
|
}
|