Changeset e1c88d5 in mainline
- Timestamp:
- 2008-11-02T15:57:30Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9df7918
- Parents:
- f1ba5d6
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libblock/libblock.c
rf1ba5d6 re1c88d5 263 263 return ENOMEM; 264 264 265 futex_initialize(&cache->lock, 0);265 futex_initialize(&cache->lock, 1); 266 266 list_initialize(&cache->free_head); 267 267 cache->block_size = size; … … 337 337 } 338 338 339 block_t *block_get(dev_handle_t dev_handle, off_t offset, size_t bs) 340 { 341 /* FIXME */ 339 static bool cache_can_grow(cache_t *cache) 340 { 341 return true; 342 } 343 344 static void block_initialize(block_t *b) 345 { 346 futex_initialize(&b->lock, 1); 347 b->refcnt = 1; 348 b->dirty = false; 349 rwlock_initialize(&b->contents_lock); 350 link_initialize(&b->free_link); 351 link_initialize(&b->hash_link); 352 } 353 354 /** Instantiate a block in memory and get a reference to it. 355 * 356 * @param dev_handle Device handle of the block device. 357 * @param boff Block offset. 358 * 359 * @return Block structure. 360 */ 361 block_t *block_get(dev_handle_t dev_handle, off_t boff, size_t bs) 362 { 363 devcon_t *devcon; 364 cache_t *cache; 342 365 block_t *b; 343 off_t bufpos = 0; 344 size_t buflen = 0; 345 off_t pos = offset * bs; 346 347 b = malloc(sizeof(block_t)); 348 if (!b) 349 return NULL; 350 351 b->data = malloc(bs); 352 if (!b->data) { 353 free(b); 354 return NULL; 355 } 356 b->size = bs; 357 358 if (block_read(dev_handle, &bufpos, &buflen, &pos, b->data, 359 bs, bs) != EOK) { 360 free(b->data); 361 free(b); 362 return NULL; 363 } 364 366 link_t *l; 367 unsigned long key = boff; 368 369 devcon = devcon_search(dev_handle); 370 371 assert(devcon); 372 assert(devcon->cache); 373 374 cache = devcon->cache; 375 futex_down(&cache->lock); 376 l = hash_table_find(&cache->block_hash, &key); 377 if (l) { 378 /* 379 * We found the block in the cache. 380 */ 381 b = hash_table_get_instance(l, block_t, hash_link); 382 futex_down(&b->lock); 383 if (b->refcnt++ == 0) 384 list_remove(&b->free_link); 385 futex_up(&b->lock); 386 } else { 387 /* 388 * The block was not found in the cache. 389 */ 390 int rc; 391 off_t bufpos = 0; 392 size_t buflen = 0; 393 off_t pos = boff * cache->block_size; 394 395 if (cache_can_grow(cache)) { 396 /* 397 * We can grow the cache by allocating new blocks. 398 * Should the allocation fail, we fail over and try to 399 * recycle a block from the cache. 400 */ 401 b = malloc(sizeof(block_t)); 402 if (!b) 403 goto recycle; 404 b->data = malloc(cache->block_size); 405 if (!b->data) { 406 free(b); 407 goto recycle; 408 } 409 } else { 410 /* 411 * Try to recycle a block from the free list. 412 */ 413 unsigned long temp_key; 414 recycle: 415 assert(!list_empty(&cache->free_head)); 416 l = cache->free_head.next; 417 list_remove(l); 418 b = hash_table_get_instance(l, block_t, hash_link); 419 assert(!b->dirty); 420 temp_key = b->boff; 421 hash_table_remove(&cache->block_hash, &temp_key, 1); 422 } 423 424 block_initialize(b); 425 b->dev_handle = dev_handle; 426 b->size = cache->block_size; 427 b->boff = boff; 428 /* read block from the device */ 429 rc = block_read(dev_handle, &bufpos, &buflen, &pos, b->data, 430 cache->block_size, cache->block_size); 431 assert(rc == EOK); 432 hash_table_insert(&cache->block_hash, &key, &b->hash_link); 433 } 434 435 futex_up(&cache->lock); 365 436 return b; 366 437 } … … 368 439 void block_put(block_t *block) 369 440 { 370 /* FIXME */ 371 free(block->data); 372 free(block); 441 373 442 } 374 443
Note:
See TracChangeset
for help on using the changeset viewer.