void tile_lock (Tile *tile) { /* Increment the global reference count. */ tile_ref_count++; /* Increment this tile's reference count. */ tile->ref_count++; if (tile->ref_count == 1) { /* remove from cache, move to main store */ tile_cache_flush (tile); #ifdef TILE_PROFILING tile_active_count++; #endif } if (tile->data == NULL) { /* There is no data, so the tile must be swapped out */ tile_swap_in (tile); } /* Call 'tile_manager_validate' if the tile was invalid. */ if (! tile->valid) { /* an invalid tile should never be shared, so this should work */ tile_manager_validate_tile (tile->tlink->tm, tile); } }
void tile_cache_insert (Tile *tile) { GList *tmp; if (initialize) tile_cache_init (); /* First check and see if the tile is already * in the cache. In that case we will simply place * it at the end of the tile list to indicate that * it was the most recently accessed tile. */ tmp = g_hash_table_lookup (tile_hash_table, tile); if (tmp) { /* The tile was already in the cache. Place it at * the end of the tile list. */ if (tmp == tile_list_tail) tile_list_tail = tile_list_tail->prev; tile_list_head = g_list_remove_link (tile_list_head, tmp); if (!tile_list_head) tile_list_tail = NULL; g_list_free (tmp); /* Remove the old reference to the tiles list node * in the tile hash table. */ g_hash_table_remove (tile_hash_table, tile); tile_list_tail = g_list_append (tile_list_tail, tile); if (!tile_list_head) tile_list_head = tile_list_tail; tile_list_tail = g_list_last (tile_list_tail); /* Add the tiles list node to the tile hash table. The * list node is indexed by the tile itself. This makes * for a quick lookup of which list node the tile is in. */ g_hash_table_insert (tile_hash_table, tile, tile_list_tail); } else { /* The tile was not in the cache. First check and see * if there is room in the cache. If not then we'll have * to make room first. Note: it might be the case that the * cache is smaller than the size of a tile in which case * it won't be possible to put it in the cache. */ if ((cur_cache_size + max_tile_size) > max_cache_size) { while (tile_list_head && (cur_cache_size + max_cache_size * FREE_QUANTUM) > max_cache_size) tile_cache_zorch_next (); if ((cur_cache_size + max_tile_size) > max_cache_size) return; } /* Place the tile at the end of the tile list. */ tile_list_tail = g_list_append (tile_list_tail, tile); if (!tile_list_head) tile_list_head = tile_list_tail; tile_list_tail = g_list_last (tile_list_tail); /* Add the tiles list node to the tile hash table. */ g_hash_table_insert (tile_hash_table, tile, tile_list_tail); /* Note the increase in the number of bytes the cache * is referencing. */ cur_cache_size += tile_size (tile); /* Reference the tile so that it won't be swapped out * to disk. Swap the tile in if necessary. * "tile_ref" cannot be used here since it calls this * function. */ tile->ref_count += 1; { extern int tile_ref_count; tile_ref_count += 1; } if (tile->ref_count == 1) { tile_swap_in (tile); /* the tile must be clean */ tile->dirty = FALSE; } } }