DF-3071 / df3071b.c
/* DF-3071 node-limit check-then-act race. * usage: df3071b <dir> <nthreads> <files_per_thread> * barrier-start; each thread creates empty files until error or quota. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <pthread.h> static const char *dirp; static int files_each; static volatile int go=0; static long total=0; static pthread_mutex_t mx=PTHREAD_MUTEX_INITIALIZER; static void *w(void *arg){ long id=(long)arg; char p[512]; int i,n=0; while(!go) usleep(100); for(i=0;i<files_each;i++){ snprintf(p,sizeof p,"%s/n%ld_%d",dirp,id,i); int fd=open(p,O_CREAT|O_EXCL,0644); if(fd<0) break; close(fd); n++; } pthread_mutex_lock(&mx); total+=n; pthread_mutex_unlock(&mx); return NULL; } int main(int argc,char**argv){ pthread_t th[128]; long i,n; if(argc!=4){fprintf(stderr,"usage: df3071b dir nthreads files_each\n");return 2;} dirp=argv[1]; n=atol(argv[2]); files_each=atoi(argv[3]); if(n>128)n=128; for(i=0;i<n;i++) pthread_create(&th[i],NULL,w,(void*)i); usleep(50000); go=1; for(i=0;i<n;i++) pthread_join(th[i],NULL); printf("TOTAL_FILES_CREATED=%ld\n",total); return 0; } |