Mercurial > libdvdnav.hg
diff read_cache.c @ 225:9b1b740e3fc9 src
big build system changes
* cleaned up all Makefiles and added a Makefile.common
* added relchk script
* moved libdvdread files to a dvdread subdir
* moved DVD VM to a vm subdir
* removed unused code in read_cache.c
author | mroi |
---|---|
date | Sun, 11 Jan 2004 21:43:13 +0000 |
parents | 7eda95524e83 |
children | 065a2835ba90 |
line wrap: on
line diff
--- a/read_cache.c Wed Jan 07 19:35:12 2004 +0000 +++ b/read_cache.c Sun Jan 11 21:43:13 2004 +0000 @@ -20,6 +20,11 @@ * $Id$ * */ +/* + * There was a multithreaded read ahead cache in here for some time, but + * it had only been used for a short time. If you want to have a look at it, + * search the CVS attic. + */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -31,42 +36,6 @@ #include <sys/time.h> #include <time.h> - -#define DVDNAV_PROFILE - - -/* Read-ahead cache structure. */ -#if _MULTITHREAD_ - -/* For the multithreaded cache, the cache is a ring buffer + writing - * thread that continuously reads data into the buffer until it is - * full or the 'upper-bound' has been reached. - */ - -#define CACHE_BUFFER_SIZE 2048 /* Cache this number of blocks at a time */ - -struct read_cache_s { - pthread_mutex_t cache_lock; - pthread_t read_thread; - - /* Buffer */ - uint8_t *buffer; - - /* Size of buffer */ - int32_t size; - /* block offset from sector start of buffer 'head' */ - uint32_t pos; - /* block offset from sector start of read point */ - uint32_t read_point; - /* block offset from buffer start to ring-boundary */ - uint32_t start; - - /* Bit of strange cross-linking going on here :) -- Gotta love C :) */ - dvdnav_t *dvd_self; -}; - -#else - #define READ_CACHE_CHUNKS 10 /* all cache chunks must be memory aligned to allow use of raw devices */ @@ -98,7 +67,6 @@ /* Bit of strange cross-linking going on here :) -- Gotta love C :) */ dvdnav_t *dvd_self; }; -#endif /* #define READ_CACHE_TRACE 0 @@ -122,241 +90,6 @@ # endif #endif -#if _MULTITHREAD_ - -void * read_cache_read_thread (void * this_gen) { - int cont = 1; - int32_t diff, start; - uint32_t pos, size, startp, endp; - uint32_t s,c; - uint8_t *at; - read_cache_t *self = (read_cache_t*)this_gen; - - while(cont) { - - pthread_mutex_lock(&self->cache_lock); - - if(self->size >= 0) { - diff = self->read_point - self->pos; - if(diff >= self->size/2) { - dprintf("(II) Read thread -- "); - - startp = (self->start) % CACHE_BUFFER_SIZE; - endp = abs((self->start + diff - 1) % CACHE_BUFFER_SIZE); - dprintf("startp = %i, endp = %i -- ",startp, endp); - - pos = self->pos + diff; - size = self->size - diff; - start = (self->start + diff) % CACHE_BUFFER_SIZE; - - /* Fill remainder of buffer */ - - if(startp > endp) { - s = pos + size; c = CACHE_BUFFER_SIZE - startp; - at = self->buffer + (startp * DVD_VIDEO_LB_LEN); - if(c > 0) { - dprintf("(1) Reading from %i to %i to %i ", s, s+c-1, startp); - pthread_mutex_unlock(&self->cache_lock); - DVDReadBlocks(self->dvd_self->file, s,c, at); - pthread_mutex_lock(&self->cache_lock); - } - - s = pos + size + c; c = CACHE_BUFFER_SIZE - size - c; - at = self->buffer; - if(c > 0) { - dprintf("(2) Reading from %i to %i to %i ", s, s+c-1, 0); - pthread_mutex_unlock(&self->cache_lock); - DVDReadBlocks(self->dvd_self->file, s,c, at); - pthread_mutex_lock(&self->cache_lock); - } - } else { - s = pos + size; c = CACHE_BUFFER_SIZE - size; - at = self->buffer + (startp * DVD_VIDEO_LB_LEN); - if(c > 0) { - dprintf("(3) Reading from %i to %i to %i ", s, s+c-1, startp); - pthread_mutex_unlock(&self->cache_lock); - DVDReadBlocks(self->dvd_self->file, s,c, at); - pthread_mutex_lock(&self->cache_lock); - } - } - - dprintf("\n"); - - self->pos = pos; - self->start = start; self->size = CACHE_BUFFER_SIZE; - } - } - - pthread_mutex_unlock(&self->cache_lock); - cont = (self->buffer != NULL); - usleep(100); - } - - return NULL; -} - -read_cache_t *dvdnav_read_cache_new(dvdnav_t* dvd_self) { - read_cache_t *me; - - me = (read_cache_t*)malloc(sizeof(struct read_cache_s)); - - if(me) { - int err; - - me->dvd_self = dvd_self; - me->buffer = (uint8_t*)malloc(CACHE_BUFFER_SIZE * DVD_VIDEO_LB_LEN); - me->start = 0; - me->pos = 0; - me->read_point = 0; - me->size = -1; - - /* Initialise the mutex */ - pthread_mutex_init(&me->cache_lock, NULL); - - if ((err = pthread_create (&me->read_thread, - NULL, read_cache_read_thread, me)) != 0) { - dprintf("read_cache: can't create new thread (%s)\n",strerror(err)); - } - } - - return me; -} - -void dvdnav_read_cache_free(read_cache_t* self) { - dvdnav_t *tmp; - - pthread_mutex_lock(&self->cache_lock); - - if(self->buffer) { - free(self->buffer); - self->buffer = NULL; - self->size = -2; - } - - pthread_mutex_unlock(&self->cache_lock); - - pthread_join(self->read_thread, NULL); - - pthread_mutex_destroy(&self->cache_lock); - - tmp = self->dvd_self; - free(self); - - /* We free the main structure, too, because we have no buffers out there. */ - free(tmp); -} - -/* This function MUST be called whenever self->file changes. */ -void dvdnav_read_cache_clear(read_cache_t *self) { - if(!self) - return; - - pthread_mutex_lock(&self->cache_lock); - self->size = -1; - self->start = 0; - self->pos = 0; - self->read_point = 0; - pthread_mutex_unlock(&self->cache_lock); -} - -/* This function is called just after reading the NAV packet. */ -void dvdnav_pre_cache_blocks(read_cache_t *self, int sector, size_t block_count) { - if(!self) - return; - - if(!self->dvd_self->use_read_ahead) { - return; - } - - pthread_mutex_lock(&self->cache_lock); - dprintf("Requested pre-cache (%i -> +%i) : current state pos=%i, size=%i.\n", - sector, block_count, self->pos, self->size); - - /* Are the contents of the buffer in any way relevant? */ - if((self->size > 0) && (sector >= self->pos) && (sector <= self->pos+self->size)) { - dprintf("Contents relevant ... adjusting\n"); - self->read_point = sector; - } else { - /* Flush the cache as its not much use */ - dprintf("Contents irrelevent... flushing\n"); - self->size = 0; - self->start = 0; - self->pos = sector; - self->read_point = sector; - } - - pthread_mutex_unlock(&self->cache_lock); -} - -/* This function will do the cache read */ -int dvdnav_read_cache_block( read_cache_t *self, int sector, size_t block_count, uint8_t **buf) { - int result, diff; - - if(!self) - return 0; - - pthread_mutex_lock(&self->cache_lock); - dprintf("Read from %i -> +%i (buffer pos=%i, read_point=%i, size=%i)... ", sector, block_count, - self->pos, self->read_point, self->size); - if((self->size > 0) && (sector >= self->read_point) && - (sector + block_count <= self->pos + self->size)) { - /* Hit */ - - /* Drop any skipped blocks */ - diff = sector - self->read_point; - if(diff > 0) - self->read_point += diff; - - diff = self->read_point - self->pos; - - if(((self->start + diff) % CACHE_BUFFER_SIZE) + block_count <= CACHE_BUFFER_SIZE) { - dprintf("************** Single read\n"); - memcpy(*buf, self->buffer + (((self->start + diff) % CACHE_BUFFER_SIZE) * DVD_VIDEO_LB_LEN), - block_count * DVD_VIDEO_LB_LEN); - self->read_point += block_count; - pthread_mutex_unlock(&self->cache_lock); - - return (int)block_count; - } else { - int32_t boundary = CACHE_BUFFER_SIZE - self->start; - - dprintf("************** Multiple read\n"); - memcpy(*buf, self->buffer + (((self->start + diff) % CACHE_BUFFER_SIZE) * DVD_VIDEO_LB_LEN), - boundary * DVD_VIDEO_LB_LEN); - memcpy(*buf + (boundary * DVD_VIDEO_LB_LEN), self->buffer, - (block_count-boundary) * DVD_VIDEO_LB_LEN); - self->read_point += block_count; - pthread_mutex_unlock(&self->cache_lock); - - return (int)block_count; - } - } else { - /* Miss */ - - fprintf(MSG_OUT, "libdvdnav: DVD read cache miss! (not bad but a performance hit) sector=%d\n", sector); - result = DVDReadBlocks( self->dvd_self->file, sector, block_count, *buf); - self->read_point = sector+block_count; - if(self->read_point > self->pos + self->size) { - /* Flush the cache as its not much use */ - dprintf("Contents irrelevent... flushing\n"); - self->size = 0; - self->start = 0; - self->pos = sector+block_count; - } - pthread_mutex_unlock(&self->cache_lock); - usleep(300); - return result; - } - - /* Should never get here */ - return 0; -} - -dvdnav_status_t dvdnav_free_cache_block(dvdnav_t *self, unsigned char *buf) { - return DVDNAV_STATUS_OK; -} - -#else read_cache_t *dvdnav_read_cache_new(dvdnav_t* dvd_self) { read_cache_t *self; @@ -520,7 +253,8 @@ /* Increment read-ahead size if sector follows the last sector */ if (sector == (self->last_sector + 1)) { - self->read_ahead_incr++; + if (self->read_ahead_incr < READ_AHEAD_SIZE_MAX) + self->read_ahead_incr++; } else { self->read_ahead_size = READ_AHEAD_SIZE_MIN; self->read_ahead_incr = 0; @@ -539,34 +273,33 @@ chunk->usage_count++; pthread_mutex_unlock(&self->lock); - /* Read blocks if needed */ - if (sector >= (chunk->cache_start_sector + chunk->cache_read_count)) { + dprintf("libdvdnav: sector=%d, start_sector=%d, last_sector=%d\n", sector, chunk->cache_start_sector, chunk->cache_start_sector + chunk->cache_block_count); - dprintf("libdvdnav: sector=%d, start_sector=%d, last_sector=%d\n", sector, chunk->cache_start_sector, chunk->cache_start_sector + chunk->cache_block_count); + /* read_ahead_size */ + incr = self->read_ahead_incr >> 1; + if ((self->read_ahead_size + incr) > READ_AHEAD_SIZE_MAX) { + self->read_ahead_size = READ_AHEAD_SIZE_MAX; + } else { + self->read_ahead_size += incr; + } - /* read_ahead_size */ - incr = self->read_ahead_incr >> 1; - if ((self->read_ahead_size + incr) > READ_AHEAD_SIZE_MAX) { - self->read_ahead_size = READ_AHEAD_SIZE_MAX; - } else { - self->read_ahead_size = self->read_ahead_size + incr; - } - self->read_ahead_incr = 0; + /* real read size */ + start = chunk->cache_start_sector + chunk->cache_read_count; + if (chunk->cache_read_count + self->read_ahead_size > chunk->cache_block_count) { + size = chunk->cache_block_count - chunk->cache_read_count; + } else { + size = self->read_ahead_size; + /* ensure that the sector we want will be read */ + if (sector >= chunk->cache_start_sector + chunk->cache_read_count + size) + size = sector - chunk->cache_start_sector - chunk->cache_read_count; + } + dprintf("libdvdnav: read_ahead_size=%d, size=%d\n", self->read_ahead_size, size); - /* real read size */ - start = chunk->cache_start_sector + chunk->cache_read_count; - if (chunk->cache_read_count + self->read_ahead_size > chunk->cache_block_count) { - size = chunk->cache_block_count - chunk->cache_read_count; - } else { - size = self->read_ahead_size; - } - dprintf("libdvdnav: read_ahead_size=%d, size=%d\n", self->read_ahead_size, size); - + if (size) chunk->cache_read_count += DVDReadBlocks(self->dvd_self->file, start, size, read_ahead_buf); - } res = DVD_VIDEO_LB_LEN * block_count; @@ -611,5 +344,3 @@ return DVDNAV_STATUS_OK; } - -#endif