/* * buffer is the start address in memory to be written from * if used in inode_write_at, buffer = 'buffer' + bytes_written * sector_ofs is the start point to actually write the buffer cache * chunk_size is the actual size to be written to buffer cache */ void write_via_cache(struct inode *inode, const uint8_t *buffer, block_sector_t sector_idx, int sector_ofs, int chunk_size) { //lookup buffer and check if sector_indx exits in buffer cache int buffer_arr_indx = lookup_sector(sector_idx); //lookup result indx for a valid sector in cache if (buffer_arr_indx > BUFFER_SIZE) { PANIC("lookup_sector wrong\n"); } if (buffer_arr_indx >= 0){ //if yes, just write buffer cache void *buffer_cache_start_addr = buffer_vaddr + buffer_arr_indx * BLOCK_SECTOR_SIZE + sector_ofs; memcpy (buffer_cache_start_addr, (void *)buffer, chunk_size); } else { //the sector_idx is not in buffer cache //check if empty sector exists in buffer cache int buffer_indx = lookup_empty_buffer(); if (buffer_indx == -1) { //if no, evict sector from buffer cache, and get its indx //choose a sector to evict //lookup_evict contains 'clock algorithm' //lookup_evict() takes care of case when buffer_evict_indx == -1 int buffer_evict_indx = lookup_evict(); //buffer_evict_indx should be a valid indx buffer_evict_indx = buffer_evict(buffer_evict_indx); buffer_indx = buffer_evict_indx; } //buffer_cache_start_addr is the start addr of buffer cache sector void *buffer_cache_start_addr = buffer_vaddr + buffer_indx * BLOCK_SECTOR_SIZE; //get sector from disk to buffer cache //copy the sector from disk to buffer cache if (sector_ofs != 0 || chunk_size != BLOCK_SECTOR_SIZE) { // Write partial sector cache, need to fetch from disk first. block_read (fs_device, sector_idx, buffer_cache_start_addr); } //change buffer_cache_start_addr to the offset of buffer cache sector buffer_cache_start_addr += sector_ofs; //write sector to buffer cache //copy the sector from buffer cache to buffer_read memcpy (buffer_cache_start_addr, (void *)buffer, chunk_size); //fill the info into buffer_info_array buffer_info_array[buffer_indx].sector_num = sector_idx; buffer_info_array[buffer_indx].buffer_inode = inode; buffer_info_array[buffer_indx].dirty = true; buffer_info_array[buffer_indx].recentlyUsed = true; } }
/* * buffer is the start address in memory to be read from * if used in inode_read_at, buffer = 'buffer' + bytes_read * sector_ofs is the start point to actually read from the buffer cache * chunk_size is the actual size to be read to buffer cache */ void read_via_cache(struct inode *inode, uint8_t *buffer, block_sector_t sector_idx, int sector_ofs, int chunk_size) { //printf("sector_idx %d, size %d\n", sector_idx, size); int buffer_arr_indx = lookup_sector(sector_idx); //lookup result indx for a valid sector in cache if (buffer_arr_indx > BUFFER_SIZE) { PANIC("lookup_sector wrong\n"); } // printf("sector_idx %d\n", sector_idx); if (buffer_arr_indx >= 0){ // printf("indx %d, sector_idx %d size %d\n", buffer_arr_indx, sector_idx, size); void *buffer_cache_start_addr = buffer_vaddr + buffer_arr_indx * BLOCK_SECTOR_SIZE + sector_ofs; memcpy((void *)buffer, buffer_cache_start_addr, chunk_size); } else { //the sector_idx is not in buffer cache //printf("new start\n"); int buffer_indx = lookup_empty_buffer(); if (buffer_indx == -1) { //choose a sector to evict //lookup_evict contains 'clock algorithm' //lookup_evict() takes care of case when buffer_evict_indx == -1 int buffer_evict_indx = lookup_evict(); //buffer_evict_indx should be a valid indx buffer_evict_indx = buffer_evict(buffer_evict_indx); buffer_indx = buffer_evict_indx; //printf("evicting!\n"); } //buffer_cache_start_addr is the start addr of buffer cache sector void *buffer_cache_start_addr = buffer_vaddr + buffer_indx * BLOCK_SECTOR_SIZE; //copy the sector from disk to buffer cache block_read (fs_device, sector_idx, buffer_cache_start_addr); //change buffer_cache_start_addr to the offset of buffer cache sector buffer_cache_start_addr += sector_ofs; //copy the sector from buffer cache to buffer_read memcpy ((void *)buffer, buffer_cache_start_addr, chunk_size); //fill the info into buffer_info_array if(sector_idx < -2) buffer_info_array[buffer_indx].sector_num = sector_idx; buffer_info_array[buffer_indx].buffer_inode = inode; buffer_info_array[buffer_indx].dirty = false; buffer_info_array[buffer_indx].recentlyUsed = true; } }
bool S_LoadBuffer( sfx_t *sfx ) { ALenum error; void *data; snd_info_t info; ALuint format; if( !sfx ) { return false; } if( sfx->filename[0] == '\0' || sfx->inMemory ) return false; if( trap_FS_IsUrl( sfx->filename ) ) return false; data = S_LoadSound( sfx->filename, &info ); if( !data ) { //Com_DPrintf( "Couldn't load %s\n", sfx->filename ); return false; } if( info.channels > 1 ) { void *temp = stereo_mono( data, &info ); if( temp ) { S_Free( data ); data = temp; } } format = S_SoundFormat( info.width, info.channels ); qalGenBuffers( 1, &sfx->buffer ); if( ( error = qalGetError() ) != AL_NO_ERROR ) { S_Free( data ); Com_Printf( "Couldn't create a sound buffer for %s (%s)\n", sfx->filename, S_ErrorMessage( error ) ); return false; } qalBufferData( sfx->buffer, format, data, info.size, info.rate ); error = qalGetError(); // If we ran out of memory, start evicting the least recently used sounds while( error == AL_OUT_OF_MEMORY ) { if( !buffer_evict() ) { S_Free( data ); Com_Printf( "Out of memory loading %s\n", sfx->filename ); return false; } // Try load it again qalGetError(); qalBufferData( sfx->buffer, format, data, info.size, info.rate ); error = qalGetError(); } // Some other error condition if( error != AL_NO_ERROR ) { S_Free( data ); Com_Printf( "Couldn't fill sound buffer for %s (%s)", sfx->filename, S_ErrorMessage( error ) ); return false; } S_Free( data ); sfx->inMemory = true; return true; }