engines/libaio: don't reap on EAGAIN and no pending events
[fio.git] / filehash.c
1 #include <stdlib.h>
2 #include <assert.h>
3
4 #include "fio.h"
5 #include "flist.h"
6 #include "hash.h"
7 #include "filehash.h"
8
9 #define HASH_BUCKETS    512
10 #define HASH_MASK       (HASH_BUCKETS - 1)
11
12 unsigned int file_hash_size = HASH_BUCKETS * sizeof(struct flist_head);
13
14 static struct flist_head *file_hash;
15 static struct fio_mutex *hash_lock;
16
17 static unsigned short hash(const char *name)
18 {
19         return jhash(name, strlen(name), 0) & HASH_MASK;
20 }
21
22 void fio_file_hash_lock(void)
23 {
24         if (hash_lock)
25                 fio_mutex_down(hash_lock);
26 }
27
28 void fio_file_hash_unlock(void)
29 {
30         if (hash_lock)
31                 fio_mutex_up(hash_lock);
32 }
33
34 void remove_file_hash(struct fio_file *f)
35 {
36         fio_mutex_down(hash_lock);
37
38         if (fio_file_hashed(f)) {
39                 assert(!flist_empty(&f->hash_list));
40                 flist_del_init(&f->hash_list);
41                 fio_file_clear_hashed(f);
42         }
43
44         fio_mutex_up(hash_lock);
45 }
46
47 static struct fio_file *__lookup_file_hash(const char *name)
48 {
49         struct flist_head *bucket = &file_hash[hash(name)];
50         struct flist_head *n;
51
52         flist_for_each(n, bucket) {
53                 struct fio_file *f = flist_entry(n, struct fio_file, hash_list);
54
55                 if (!f->file_name)
56                         continue;
57
58                 if (!strcmp(f->file_name, name)) {
59                         assert(f->fd != -1);
60                         return f;
61                 }
62         }
63
64         return NULL;
65 }
66
67 struct fio_file *lookup_file_hash(const char *name)
68 {
69         struct fio_file *f;
70
71         fio_mutex_down(hash_lock);
72         f = __lookup_file_hash(name);
73         fio_mutex_up(hash_lock);
74         return f;
75 }
76
77 struct fio_file *add_file_hash(struct fio_file *f)
78 {
79         struct fio_file *alias;
80
81         if (fio_file_hashed(f))
82                 return NULL;
83
84         INIT_FLIST_HEAD(&f->hash_list);
85
86         fio_mutex_down(hash_lock);
87
88         alias = __lookup_file_hash(f->file_name);
89         if (!alias) {
90                 fio_file_set_hashed(f);
91                 flist_add_tail(&f->hash_list, &file_hash[hash(f->file_name)]);
92         }
93
94         fio_mutex_up(hash_lock);
95         return alias;
96 }
97
98 void file_hash_exit(void)
99 {
100         unsigned int i, has_entries = 0;
101
102         fio_mutex_down(hash_lock);
103         for (i = 0; i < HASH_BUCKETS; i++)
104                 has_entries += !flist_empty(&file_hash[i]);
105         fio_mutex_up(hash_lock);
106
107         if (has_entries)
108                 log_err("fio: file hash not empty on exit\n");
109
110         file_hash = NULL;
111         fio_mutex_remove(hash_lock);
112         hash_lock = NULL;
113 }
114
115 void file_hash_init(void *ptr)
116 {
117         unsigned int i;
118
119         file_hash = ptr;
120         for (i = 0; i < HASH_BUCKETS; i++)
121                 INIT_FLIST_HEAD(&file_hash[i]);
122
123         hash_lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
124 }