Subversion Repositories HelenOS

Rev

Rev 3538 | Rev 3540 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3538 Rev 3539
Line 46... Line 46...
46
#include <ipc/ipc.h>
46
#include <ipc/ipc.h>
47
#include <as.h>
47
#include <as.h>
48
#include <assert.h>
48
#include <assert.h>
49
#include <futex.h>
49
#include <futex.h>
50
#include <libadt/list.h>
50
#include <libadt/list.h>
-
 
51
#include <libadt/hash_table.h>
51
 
52
 
52
/** Lock protecting the device connection list */
53
/** Lock protecting the device connection list */
53
static futex_t dcl_lock = FUTEX_INITIALIZER;
54
static futex_t dcl_lock = FUTEX_INITIALIZER;
54
/** Device connection list head. */
55
/** Device connection list head. */
55
static LIST_INITIALIZE(dcl_head);
56
static LIST_INITIALIZE(dcl_head);
56
 
57
 
-
 
58
#define CACHE_BUCKETS_LOG2      10
-
 
59
#define CACHE_BUCKETS           (1 << CACHE_BUCKETS_LOG2)
-
 
60
 
-
 
61
typedef struct {
-
 
62
    futex_t lock;
-
 
63
    size_t block_size;      /**< Block size. */
-
 
64
    unsigned block_count;       /**< Total number of blocks. */
-
 
65
    hash_table_t block_hash;
-
 
66
    link_t free_head;
-
 
67
} cache_t;
-
 
68
 
57
typedef struct {
69
typedef struct {
58
    link_t link;
70
    link_t link;
59
    int dev_handle;
71
    int dev_handle;
60
    int dev_phone;
72
    int dev_phone;
61
    void *com_area;
73
    void *com_area;
62
    size_t com_size;
74
    size_t com_size;
63
    void *bb_buf;
75
    void *bb_buf;
64
    off_t bb_off;
76
    off_t bb_off;
65
    size_t bb_size;
77
    size_t bb_size;
-
 
78
    cache_t *cache;
66
} devcon_t;
79
} devcon_t;
67
 
80
 
68
static devcon_t *devcon_search(dev_handle_t dev_handle)
81
static devcon_t *devcon_search(dev_handle_t dev_handle)
69
{
82
{
70
    link_t *cur;
83
    link_t *cur;
Line 97... Line 110...
97
    devcon->com_area = com_area;
110
    devcon->com_area = com_area;
98
    devcon->com_size = com_size;
111
    devcon->com_size = com_size;
99
    devcon->bb_buf = NULL;
112
    devcon->bb_buf = NULL;
100
    devcon->bb_off = 0;
113
    devcon->bb_off = 0;
101
    devcon->bb_size = 0;
114
    devcon->bb_size = 0;
-
 
115
    devcon->cache = NULL;
102
 
116
 
103
    futex_down(&dcl_lock);
117
    futex_down(&dcl_lock);
104
    for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
118
    for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
105
        devcon_t *d = list_get_instance(cur, devcon_t, link);
119
        devcon_t *d = list_get_instance(cur, devcon_t, link);
106
        if (d->dev_handle == dev_handle) {
120
        if (d->dev_handle == dev_handle) {
Line 165... Line 179...
165
   
179
   
166
    devcon_remove(devcon);
180
    devcon_remove(devcon);
167
 
181
 
168
    if (devcon->bb_buf)
182
    if (devcon->bb_buf)
169
        free(devcon->bb_buf);
183
        free(devcon->bb_buf);
-
 
184
 
-
 
185
    if (devcon->cache) {
-
 
186
        hash_table_destroy(&devcon->cache->block_hash);
-
 
187
        free(devcon->cache);
-
 
188
    }
-
 
189
 
170
    munmap(devcon->com_area, devcon->com_size);
190
    munmap(devcon->com_area, devcon->com_size);
171
    ipc_hangup(devcon->dev_phone);
191
    ipc_hangup(devcon->dev_phone);
172
 
192
 
173
    free(devcon);  
193
    free(devcon);  
174
}
194
}
Line 207... Line 227...
207
    devcon_t *devcon = devcon_search(dev_handle);
227
    devcon_t *devcon = devcon_search(dev_handle);
208
    assert(devcon);
228
    assert(devcon);
209
    return devcon->bb_buf;
229
    return devcon->bb_buf;
210
}
230
}
211
 
231
 
-
 
232
static hash_index_t cache_hash(unsigned long *key)
-
 
233
{
-
 
234
    return *key & (CACHE_BUCKETS - 1);
-
 
235
}
-
 
236
 
-
 
237
static int cache_compare(unsigned long *key, hash_count_t keys, link_t *item)
-
 
238
{
-
 
239
    block_t *b = hash_table_get_instance(item, block_t, hash_link);
-
 
240
    return b->boff == *key;
-
 
241
}
-
 
242
 
-
 
243
static void cache_remove_callback(link_t *item)
-
 
244
{
-
 
245
}
-
 
246
 
-
 
247
static hash_table_operations_t cache_ops = {
-
 
248
    .hash = cache_hash,
-
 
249
    .compare = cache_compare,
-
 
250
    .remove_callback = cache_remove_callback
-
 
251
};
-
 
252
 
-
 
253
int block_cache_init(dev_handle_t dev_handle, size_t size, unsigned blocks)
-
 
254
{
-
 
255
    devcon_t *devcon = devcon_search(dev_handle);
-
 
256
    cache_t *cache;
-
 
257
    if (!devcon)
-
 
258
        return ENOENT;
-
 
259
    if (devcon->cache)
-
 
260
        return EEXIST;
-
 
261
    cache = malloc(sizeof(cache_t));
-
 
262
    if (!cache)
-
 
263
        return ENOMEM;
-
 
264
   
-
 
265
    futex_initialize(&cache->lock, 0);
-
 
266
    list_initialize(&cache->free_head);
-
 
267
    cache->block_size = size;
-
 
268
    cache->block_count = blocks;
-
 
269
 
-
 
270
    if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
-
 
271
        &cache_ops)) {
-
 
272
        free(cache);
-
 
273
        return ENOMEM;
-
 
274
    }
-
 
275
 
-
 
276
    devcon->cache = cache;
-
 
277
    return EOK;
-
 
278
}
-
 
279
 
212
/** Read data from a block device.
280
/** Read data from a block device.
213
 *
281
 *
214
 * @param dev_handle    Device handle of the block device.
282
 * @param dev_handle    Device handle of the block device.
215
 * @param bufpos    Pointer to the first unread valid offset within the
283
 * @param bufpos    Pointer to the first unread valid offset within the
216
 *          communication buffer.
284
 *          communication buffer.