Changeset d68e4d5 in mainline
- Timestamp:
- 2009-07-04T13:04:13Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7114d83
- Parents:
- 2a77841d
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libblock/libblock.c
r2a77841d rd68e4d5 64 64 size_t block_size; /**< Block size. */ 65 65 unsigned block_count; /**< Total number of blocks. */ 66 unsigned blocks_cached; /**< Number of cached blocks. */ 66 67 hash_table_t block_hash; 67 68 link_t free_head; … … 73 74 dev_handle_t dev_handle; 74 75 int dev_phone; 76 fibril_mutex_t com_area_lock; 75 77 void *com_area; 76 78 size_t com_size; … … 113 115 devcon->dev_handle = dev_handle; 114 116 devcon->dev_phone = dev_phone; 117 fibril_mutex_initialize(&devcon->com_area_lock); 115 118 devcon->com_area = com_area; 116 119 devcon->com_size = com_size; … … 212 215 return ENOMEM; 213 216 217 fibril_mutex_lock(&devcon->com_area_lock); 214 218 rc = read_block(devcon, 0, size); 215 219 if (rc != EOK) { 220 fibril_mutex_unlock(&devcon->com_area_lock); 216 221 free(bb_buf); 217 222 return rc; 218 223 } 219 220 224 memcpy(bb_buf, devcon->com_area, size); 225 fibril_mutex_unlock(&devcon->com_area_lock); 221 226 222 227 devcon->bb_buf = bb_buf; … … 272 277 cache->block_size = size; 273 278 cache->block_count = blocks; 279 cache->blocks_cached = 0; 274 280 cache->mode = mode; 275 281 … … 284 290 } 285 291 292 #define CACHE_LO_WATERMARK 10 293 #define CACHE_HI_WATERMARK 20 286 294 static bool cache_can_grow(cache_t *cache) 287 295 { 296 if (cache->blocks_cached < CACHE_LO_WATERMARK) 297 return true; 298 if (!list_empty(&cache->free_head)) 299 return false; 288 300 return true; 289 301 } … … 316 328 link_t *l; 317 329 unsigned long key = boff; 330 bn_t oboff; 318 331 319 332 devcon = devcon_search(dev_handle); … … 356 369 goto recycle; 357 370 } 371 cache->blocks_cached++; 358 372 } else { 359 373 /* … … 365 379 l = cache->free_head.next; 366 380 list_remove(l); 367 b = hash_table_get_instance(l, block_t, hash_link);381 b = list_get_instance(l, block_t, free_link); 368 382 sync = b->dirty; 383 oboff = b->boff; 369 384 temp_key = b->boff; 370 385 hash_table_remove(&cache->block_hash, &temp_key, 1); … … 390 405 * the device before we can read in the new contents. 391 406 */ 392 abort(); /* TODO: block_write() */ 407 fibril_mutex_lock(&devcon->com_area_lock); 408 memcpy(devcon->com_area, b->data, b->size); 409 rc = write_block(devcon, oboff, cache->block_size); 410 assert(rc == EOK); 411 fibril_mutex_unlock(&devcon->com_area_lock); 393 412 } 394 413 if (!(flags & BLOCK_FLAGS_NOREAD)) { … … 397 416 * the new contents from the device. 398 417 */ 418 fibril_mutex_lock(&devcon->com_area_lock); 399 419 rc = read_block(devcon, b->boff, cache->block_size); 400 420 assert(rc == EOK); 401 421 memcpy(b->data, devcon->com_area, cache->block_size); 422 fibril_mutex_unlock(&devcon->com_area_lock); 402 423 } 403 424 … … 427 448 if (!--block->refcnt) { 428 449 /* 429 * Last reference to the block was dropped, put the block on the 430 * free list. 450 * Last reference to the block was dropped. Either free the 451 * block or put it on the free list. 452 */ 453 if (cache->blocks_cached > CACHE_HI_WATERMARK) { 454 /* 455 * Currently there are too many cached blocks. 456 */ 457 if (block->dirty) { 458 fibril_mutex_lock(&devcon->com_area_lock); 459 memcpy(devcon->com_area, block->data, 460 block->size); 461 rc = write_block(devcon, block->boff, 462 block->size); 463 assert(rc == EOK); 464 fibril_mutex_unlock(&devcon->com_area_lock); 465 } 466 /* 467 * Take the block out of the cache and free it. 468 */ 469 unsigned long key = block->boff; 470 hash_table_remove(&cache->block_hash, &key, 1); 471 free(block); 472 free(block->data); 473 cache->blocks_cached--; 474 fibril_mutex_unlock(&cache->lock); 475 return; 476 } 477 /* 478 * Put the block on the free list. 431 479 */ 432 480 list_append(&block->free_link, &cache->free_head); 433 481 if (cache->mode != CACHE_MODE_WB && block->dirty) { 482 fibril_mutex_lock(&devcon->com_area_lock); 434 483 memcpy(devcon->com_area, block->data, block->size); 435 484 rc = write_block(devcon, block->boff, block->size); 436 485 assert(rc == EOK); 486 fibril_mutex_unlock(&devcon->com_area_lock); 437 487 438 488 block->dirty = false; … … 465 515 assert(devcon); 466 516 517 fibril_mutex_lock(&devcon->com_area_lock); 467 518 while (left > 0) { 468 519 size_t rd; … … 490 541 491 542 rc = read_block(devcon, *pos / block_size, block_size); 492 if (rc != EOK) 543 if (rc != EOK) { 544 fibril_mutex_unlock(&devcon->com_area_lock); 493 545 return rc; 546 } 494 547 495 548 *bufpos = 0; … … 497 550 } 498 551 } 552 fibril_mutex_unlock(&devcon->com_area_lock); 499 553 500 554 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.