Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 1 | #include <stdlib.h> |
2 | #include <assert.h> | ||||
3 | |||||
4 | #include "fio.h" | ||||
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 5 | #include "flist.h" |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 6 | #include "crc/crc16.h" |
7 | |||||
8 | #define HASH_BUCKETS 512 | ||||
9 | #define HASH_MASK (HASH_BUCKETS - 1) | ||||
10 | |||||
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 11 | unsigned int file_hash_size = HASH_BUCKETS * sizeof(struct flist_head); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 12 | |
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 13 | static struct flist_head *file_hash; |
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame^] | 14 | static struct fio_mutex *hash_lock; |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 15 | |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 16 | static unsigned short hash(const char *name) |
17 | { | ||||
18 | return crc16((const unsigned char *) name, strlen(name)) & HASH_MASK; | ||||
19 | } | ||||
20 | |||||
21 | void remove_file_hash(struct fio_file *f) | ||||
22 | { | ||||
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame^] | 23 | fio_mutex_down(hash_lock); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 24 | |
25 | if (f->flags & FIO_FILE_HASHED) { | ||||
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 26 | assert(!flist_empty(&f->hash_list)); |
27 | flist_del_init(&f->hash_list); | ||||
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 28 | f->flags &= ~FIO_FILE_HASHED; |
29 | } | ||||
30 | |||||
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame^] | 31 | fio_mutex_up(hash_lock); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 32 | } |
33 | |||||
34 | static struct fio_file *__lookup_file_hash(const char *name) | ||||
35 | { | ||||
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 36 | struct flist_head *bucket = &file_hash[hash(name)]; |
37 | struct flist_head *n; | ||||
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 38 | |
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 39 | flist_for_each(n, bucket) { |
40 | struct fio_file *f = flist_entry(n, struct fio_file, hash_list); | ||||
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 41 | |
42 | if (!strcmp(f->file_name, name)) { | ||||
43 | assert(f->fd != -1); | ||||
44 | return f; | ||||
45 | } | ||||
46 | } | ||||
47 | |||||
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 48 | return NULL; |
49 | } | ||||
50 | |||||
51 | struct fio_file *lookup_file_hash(const char *name) | ||||
52 | { | ||||
53 | struct fio_file *f; | ||||
54 | |||||
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame^] | 55 | fio_mutex_down(hash_lock); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 56 | f = __lookup_file_hash(name); |
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame^] | 57 | fio_mutex_up(hash_lock); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 58 | return f; |
59 | } | ||||
60 | |||||
61 | struct fio_file *add_file_hash(struct fio_file *f) | ||||
62 | { | ||||
63 | struct fio_file *alias; | ||||
64 | |||||
65 | if (f->flags & FIO_FILE_HASHED) | ||||
66 | return NULL; | ||||
67 | |||||
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 68 | INIT_FLIST_HEAD(&f->hash_list); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 69 | |
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame^] | 70 | fio_mutex_down(hash_lock); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 71 | |
72 | alias = __lookup_file_hash(f->file_name); | ||||
73 | if (!alias) { | ||||
74 | f->flags |= FIO_FILE_HASHED; | ||||
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 75 | flist_add_tail(&f->hash_list, &file_hash[hash(f->file_name)]); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 76 | } |
77 | |||||
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame^] | 78 | fio_mutex_up(hash_lock); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 79 | return alias; |
80 | } | ||||
81 | |||||
Jens Axboe | 5e1d306 | 2008-05-23 11:55:53 +0200 | [diff] [blame] | 82 | void file_hash_exit(void) |
83 | { | ||||
84 | unsigned int i, has_entries = 0; | ||||
85 | |||||
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame^] | 86 | fio_mutex_down(hash_lock); |
Jens Axboe | 5e1d306 | 2008-05-23 11:55:53 +0200 | [diff] [blame] | 87 | for (i = 0; i < HASH_BUCKETS; i++) |
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 88 | has_entries += !flist_empty(&file_hash[i]); |
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame^] | 89 | fio_mutex_up(hash_lock); |
Jens Axboe | 5e1d306 | 2008-05-23 11:55:53 +0200 | [diff] [blame] | 90 | |
91 | if (has_entries) | ||||
92 | log_err("fio: file hash not empty on exit\n"); | ||||
93 | |||||
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame^] | 94 | file_hash = NULL; |
95 | fio_mutex_remove(hash_lock); | ||||
Jens Axboe | 5e1d306 | 2008-05-23 11:55:53 +0200 | [diff] [blame] | 96 | hash_lock = NULL; |
97 | } | ||||
98 | |||||
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 99 | void file_hash_init(void *ptr) |
100 | { | ||||
101 | unsigned int i; | ||||
102 | |||||
103 | file_hash = ptr; | ||||
104 | for (i = 0; i < HASH_BUCKETS; i++) | ||||
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 105 | INIT_FLIST_HEAD(&file_hash[i]); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 106 | |
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame^] | 107 | hash_lock = fio_mutex_init(1); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 108 | } |