Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // build it as gcc -std=c99 aio_race.c -o aio_race -lpthread -laio
- #define _GNU_SOURCE
- #include <pthread.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <assert.h>
- #include <unistd.h>
- #include <string.h>
- #include <libaio.h>
- #include <stdbool.h>
- #define PAGE_SIZE 4096
- #define FILENAME "tempfile"
- #define FILEPATTERN '1'
- #define DESTROY_PATTERN '2'
- #define THREADS_NUM 100
- void remove_tempfile(void) {
- assert(!unlink(FILENAME));
- }
- void aio_worker(void *ptr) {
- int fd = open(FILENAME, O_DIRECT | O_RDONLY);
- char buffer[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
- while(true) {
- io_context_t ctx;
- struct iocb cb;
- struct iocb *cbs[1];
- assert(!io_queue_init(1, &ctx));
- io_prep_pread(&cb, fd, buffer, PAGE_SIZE, 0);
- cbs[0] = &cb;
- memset(buffer, '0', PAGE_SIZE);
- assert(io_submit(ctx, 1, &cbs[0]) == 1);
- // wait random time (0-500ms) ?
- io_destroy(ctx);
- memset(buffer, DESTROY_PATTERN, PAGE_SIZE);
- // wait random for (0-500ms) ?
- // check it is still DESTROY_PATTERN
- for (int i = 0; i < PAGE_SIZE; i++) {
- if (buffer[i] != DESTROY_PATTERN) {
- fprintf(stderr, "Buffer has unexpected character: %c\n", buffer[i]);
- exit(EXIT_FAILURE);
- }
- }
- }
- close(fd);
- }
- int main(void) {
- int fd = open(FILENAME, O_CREAT | O_TRUNC | O_APPEND | O_RDWR, S_IRUSR | S_IWUSR);
- assert(fd != -1);
- //atexit(remove_tempfile);
- char buffer[PAGE_SIZE];
- memset(buffer, FILEPATTERN, PAGE_SIZE);
- write(fd, buffer, PAGE_SIZE);
- close(fd);
- pthread_t threads[THREADS_NUM];
- for (int i = 0; i < THREADS_NUM; i++) {
- assert(!pthread_create(&threads[i], NULL, (void *)&aio_worker, NULL));
- }
- for (int i = 0; i < THREADS_NUM; i++) {
- assert(!pthread_join(threads[i], NULL));
- }
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement