static void sfree_pool(struct pool *pool, void *ptr) { struct block_hdr *hdr; unsigned int i, idx; unsigned long offset; if (!ptr) return; ptr -= sizeof(*hdr); hdr = ptr; assert(ptr_valid(pool, ptr)); sfree_check_redzone(hdr); offset = ptr - pool->map; i = offset / SMALLOC_BPL; idx = (offset % SMALLOC_BPL) / SMALLOC_BPB; fio_mutex_down(pool->lock); clear_blocks(pool, i, idx, size_to_blocks(hdr->size)); if (i < pool->next_non_full) pool->next_non_full = i; pool->free_blocks += size_to_blocks(hdr->size); fio_mutex_up(pool->lock); }
int fio_start_gtod_thread(void) { struct fio_mutex *mutex; pthread_attr_t attr; int ret; mutex = fio_mutex_init(FIO_MUTEX_LOCKED); if (!mutex) return 1; pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, 2 * PTHREAD_STACK_MIN); ret = pthread_create(>od_thread, &attr, gtod_thread_main, mutex); pthread_attr_destroy(&attr); if (ret) { log_err("Can't create gtod thread: %s\n", strerror(ret)); goto err; } ret = pthread_detach(gtod_thread); if (ret) { log_err("Can't detach gtod thread: %s\n", strerror(ret)); goto err; } dprint(FD_MUTEX, "wait on startup_mutex\n"); fio_mutex_down(mutex); dprint(FD_MUTEX, "done waiting on startup_mutex\n"); err: fio_mutex_remove(mutex); return ret; }
int helper_thread_create(struct fio_mutex *startup_mutex, struct sk_out *sk_out) { struct helper_data *hd; int ret; hd = smalloc(sizeof(*hd)); setup_disk_util(); hd->sk_out = sk_out; pthread_cond_init(&hd->cond, NULL); pthread_mutex_init(&hd->lock, NULL); hd->startup_mutex = startup_mutex; ret = pthread_create(&hd->thread, NULL, helper_thread_main, hd); if (ret) { log_err("Can't create helper thread: %s\n", strerror(ret)); return 1; } helper_data = hd; dprint(FD_MUTEX, "wait on startup_mutex\n"); fio_mutex_down(startup_mutex); dprint(FD_MUTEX, "done waiting on startup_mutex\n"); return 0; }
struct fio_file *lookup_file_hash(const char *name) { struct fio_file *f; fio_mutex_down(hash_lock); f = __lookup_file_hash(name); fio_mutex_up(hash_lock); return f; }
static void *__smalloc_pool(struct pool *pool, size_t size) { size_t nr_blocks; unsigned int i; unsigned int offset; unsigned int last_idx; void *ret = NULL; fio_mutex_down(pool->lock); nr_blocks = size_to_blocks(size); if (nr_blocks > pool->free_blocks) goto fail; i = pool->next_non_full; last_idx = 0; offset = -1U; while (i < pool->nr_blocks) { unsigned int idx; if (pool->bitmap[i] == -1U) { i++; pool->next_non_full = i; last_idx = 0; continue; } idx = find_next_zero(pool->bitmap[i], last_idx); if (!blocks_free(pool, i, idx, nr_blocks)) { idx += nr_blocks; if (idx < SMALLOC_BPI) last_idx = idx; else { last_idx = 0; while (idx >= SMALLOC_BPI) { i++; idx -= SMALLOC_BPI; } } continue; } set_blocks(pool, i, idx, nr_blocks); offset = i * SMALLOC_BPL + idx * SMALLOC_BPB; break; } if (i < pool->nr_blocks) { pool->free_blocks -= nr_blocks; ret = pool->map + offset; } fail: fio_mutex_up(pool->lock); return ret; }
void remove_file_hash(struct fio_file *f) { fio_mutex_down(hash_lock); if (f->flags & FIO_FILE_HASHED) { assert(!flist_empty(&f->hash_list)); flist_del_init(&f->hash_list); f->flags &= ~FIO_FILE_HASHED; } fio_mutex_up(hash_lock); }
void remove_file_hash(struct fio_file *f) { fio_mutex_down(hash_lock); if (fio_file_hashed(f)) { assert(!flist_empty(&f->hash_list)); flist_del_init(&f->hash_list); fio_file_clear_hashed(f); } fio_mutex_up(hash_lock); }
void file_hash_exit(void) { unsigned int i, has_entries = 0; fio_mutex_down(hash_lock); for (i = 0; i < HASH_BUCKETS; i++) has_entries += !flist_empty(&file_hash[i]); fio_mutex_up(hash_lock); if (has_entries) log_err("fio: file hash not empty on exit\n"); file_hash = NULL; fio_mutex_remove(hash_lock); hash_lock = NULL; }
static struct fio_flow *flow_get(unsigned int id) { struct fio_flow *flow = NULL; struct flist_head *n; if (!flow_lock) return NULL; fio_mutex_down(flow_lock); flist_for_each(n, flow_list) { flow = flist_entry(n, struct fio_flow, list); if (flow->id == id) break; flow = NULL; }
struct fio_file *add_file_hash(struct fio_file *f) { struct fio_file *alias; if (f->flags & FIO_FILE_HASHED) return NULL; INIT_FLIST_HEAD(&f->hash_list); fio_mutex_down(hash_lock); alias = __lookup_file_hash(f->file_name); if (!alias) { f->flags |= FIO_FILE_HASHED; flist_add_tail(&f->hash_list, &file_hash[hash(f->file_name)]); } fio_mutex_up(hash_lock); return alias; }
struct fio_file *add_file_hash(struct fio_file *f) { struct fio_file *alias; if (fio_file_hashed(f)) return NULL; INIT_FLIST_HEAD(&f->hash_list); fio_mutex_down(hash_lock); alias = __lookup_file_hash(f->file_name); if (!alias) { fio_file_set_hashed(f); flist_add_tail(&f->hash_list, &file_hash[hash(f->file_name)]); } fio_mutex_up(hash_lock); return alias; }
static inline void pool_lock(struct pool *pool) { fio_mutex_down(pool->lock); }
void fio_file_hash_lock(void) { if (hash_lock) fio_mutex_down(hash_lock); }