⬢ DragonFlyBSD Kernel Audit
DF-3014 / df3013stress.c
← back to finding ↓ download raw
/* DF-3013/3014 hammer stress - merged-iteration reseek EDEADLK + reblock
 * retry path. usage: df3013stress <dir> <seconds>
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <dirent.h>
static const char *dirp; static volatile int stop=0; static volatile long ops=0;
static void *writer2(void*x){
    long id=(long)x; char p[512],b[1024];
    memset(b,'w',sizeof b);
    while(!stop){
        snprintf(p,sizeof p,"%s/f%ld",dirp,id);
        int fd=open(p,O_RDWR|O_CREAT|O_TRUNC,0644);
        if(fd>=0){ for(int i=0;i<64;i++) write(fd,b,sizeof b); close(fd);}
        unlink(p);
        __sync_add_and_fetch(&ops,1);
    }
    return NULL;
}
static void *reader(void*x){
    while(!stop){
        DIR*d=opendir(dirp);
        if(d){ struct dirent*e; char p[600];
            while((e=readdir(d))){ snprintf(p,sizeof p,"%s/%s",dirp,e->d_name); }
            closedir(d); }
    }
    return NULL;
}
int main(int argc,char**argv){
    pthread_t w[4],r[4]; int i,secs;
    if(argc!=3){fprintf(stderr,"usage: df3013stress dir secs\n");return 2;}
    dirp=argv[1]; secs=atoi(argv[2]);
    for(i=0;i<4;i++) pthread_create(&w[i],NULL,writer2,(void*)(long)i);
    for(i=0;i<4;i++) pthread_create(&r[i],NULL,reader,NULL);
    sleep(secs); stop=1;
    for(i=0;i<4;i++) pthread_join(w[i],NULL);
    for(i=0;i<4;i++) pthread_join(r[i],NULL);
    printf("ops=%ld survived\n",ops);
    return 0;
}