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