Subversion Repositories HelenOS

Rev

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

Rev 3009 Rev 3153
Line 72... Line 72...
72
static futex_t unused_futex = FUTEX_INITIALIZER;
72
static futex_t unused_futex = FUTEX_INITIALIZER;
73
 
73
 
74
/** List of unused structures. */
74
/** List of unused structures. */
75
static LIST_INITIALIZE(unused_head);
75
static LIST_INITIALIZE(unused_head);
76
 
76
 
-
 
77
static void unused_initialize(unused_t *u, dev_handle_t dev_handle)
-
 
78
{
-
 
79
    link_initialize(&u->link);
-
 
80
    u->dev_handle = dev_handle;
-
 
81
    u->next = 0;
-
 
82
    u->remaining = ((uint64_t)((fs_index_t)-1)) + 1;
-
 
83
    list_initialize(&u->freed_head);
-
 
84
}
-
 
85
 
-
 
86
static unused_t *unused_find(dev_handle_t dev_handle, bool lock)
-
 
87
{
-
 
88
    unused_t *u;
-
 
89
    link_t *l;
-
 
90
 
-
 
91
    if (lock)
-
 
92
        futex_down(&unused_futex);
-
 
93
    for (l = unused_head.next; l != &unused_head; l = l->next) {
-
 
94
        u = list_get_instance(l, unused_t, link);
-
 
95
        if (u->dev_handle == dev_handle)
-
 
96
            return u;
-
 
97
    }
-
 
98
    if (lock)
-
 
99
        futex_up(&unused_futex);
-
 
100
    return NULL;
-
 
101
}
-
 
102
 
77
/** Futex protecting the up_hash and ui_hash. */
103
/** Futex protecting the up_hash and ui_hash. */
78
static futex_t used_futex = FUTEX_INITIALIZER;
104
static futex_t used_futex = FUTEX_INITIALIZER;
79
 
105
 
80
/**
106
/**
81
 * Global hash table of all used fat_idx_t structures.
107
 * Global hash table of all used fat_idx_t structures.
Line 188... Line 214...
188
};
214
};
189
 
215
 
190
/** Allocate a VFS index which is not currently in use. */
216
/** Allocate a VFS index which is not currently in use. */
191
static bool fat_idx_alloc(dev_handle_t dev_handle, fs_index_t *index)
217
static bool fat_idx_alloc(dev_handle_t dev_handle, fs_index_t *index)
192
{
218
{
193
    link_t *l;
-
 
194
    unused_t *u;
219
    unused_t *u;
195
   
220
   
196
    assert(index);
221
    assert(index);
197
    futex_down(&unused_futex);
-
 
198
    for (l = unused_head.next; l != &unused_head; l = l->next) {
-
 
199
        u = list_get_instance(l, unused_t, link);
-
 
200
        if (u->dev_handle == dev_handle)
222
    u = unused_find(dev_handle, true);
201
            goto hit;
223
    if (!u)
202
    }
-
 
203
    futex_up(&unused_futex);
-
 
204
   
-
 
205
    /* dev_handle not found */
-
 
206
    return false;  
224
        return false;  
207
 
225
 
208
hit:
-
 
209
    if (list_empty(&u->freed_head)) {
226
    if (list_empty(&u->freed_head)) {
210
        if (u->remaining) {
227
        if (u->remaining) {
211
            /*
228
            /*
212
             * There are no freed indices, allocate one directly
229
             * There are no freed indices, allocate one directly
213
             * from the counter.
230
             * from the counter.
Line 259... Line 276...
259
}
276
}
260
 
277
 
261
/** Free a VFS index, which is no longer in use. */
278
/** Free a VFS index, which is no longer in use. */
262
static void fat_idx_free(dev_handle_t dev_handle, fs_index_t index)
279
static void fat_idx_free(dev_handle_t dev_handle, fs_index_t index)
263
{
280
{
264
    link_t *l;
-
 
265
    unused_t *u;
281
    unused_t *u;
266
 
282
 
267
    futex_down(&unused_futex);
-
 
268
    for (l = unused_head.next; l != &unused_head; l = l->next) {
-
 
269
        u = list_get_instance(l, unused_t, link);
-
 
270
        if (u->dev_handle == dev_handle)
283
    u = unused_find(dev_handle, true);
271
            goto hit;
-
 
272
    }
-
 
273
    futex_up(&unused_futex);
-
 
274
 
-
 
275
    /* should not happen */
-
 
276
    assert(0);
284
    assert(u);
277
 
285
 
278
hit:
-
 
279
    if (u->next == index + 1) {
286
    if (u->next == index + 1) {
280
        /* The index can be returned directly to the counter. */
287
        /* The index can be returned directly to the counter. */
281
        u->next--;
288
        u->next--;
282
        u->remaining++;
289
        u->remaining++;
283
    } else {
290
    } else {
Line 399... Line 406...
399
    futex_up(&used_futex);
406
    futex_up(&used_futex);
400
 
407
 
401
    return fidx;
408
    return fidx;
402
}
409
}
403
 
410
 
-
 
411
int fat_idx_init(void)
-
 
412
{
-
 
413
    if (!hash_table_create(&up_hash, UPH_BUCKETS, 3, &uph_ops))
-
 
414
        return ENOMEM;
-
 
415
    if (!hash_table_create(&ui_hash, UIH_BUCKETS, 2, &uih_ops)) {
-
 
416
        hash_table_destroy(&up_hash);
-
 
417
        return ENOMEM;
-
 
418
    }
-
 
419
    return EOK;
-
 
420
}
-
 
421
 
-
 
422
void fat_idx_fini(void)
-
 
423
{
-
 
424
    /* We assume the hash tables are empty. */
-
 
425
    hash_table_destroy(&up_hash);
-
 
426
    hash_table_destroy(&ui_hash);
-
 
427
}
-
 
428
 
-
 
429
int fat_idx_init_by_dev_handle(dev_handle_t dev_handle)
-
 
430
{
-
 
431
    unused_t *u;
-
 
432
    int rc = EOK;
-
 
433
 
-
 
434
    u = (unused_t *) malloc(sizeof(unused_t));
-
 
435
    if (!u)
-
 
436
        return ENOMEM;
-
 
437
    unused_initialize(u, dev_handle);
-
 
438
    futex_down(&unused_futex);
-
 
439
    if (!unused_find(dev_handle, false))
-
 
440
        list_append(&u->link, &unused_head);
-
 
441
    else
-
 
442
        rc = EEXIST;
-
 
443
    futex_up(&unused_futex);
-
 
444
    return rc;
-
 
445
}
-
 
446
 
-
 
447
void fat_idx_fini_by_dev_handle(dev_handle_t dev_handle)
-
 
448
{
-
 
449
    unused_t *u;
-
 
450
 
-
 
451
    u = unused_find(dev_handle, true);
-
 
452
    assert(u);
-
 
453
    list_remove(&u->link);
-
 
454
    futex_up(&unused_futex);
-
 
455
 
-
 
456
    while (!list_empty(&u->freed_head)) {
-
 
457
        freed_t *f;
-
 
458
        f = list_get_instance(u->freed_head.next, freed_t, link);
-
 
459
        list_remove(&f->link);
-
 
460
        free(f);
-
 
461
    }
-
 
462
    free(u);
-
 
463
}
-
 
464
 
-
 
465
/**
-
 
466
 * @}
-
 
467
 */