diff --git a/libisoburn/data_source.c b/libisoburn/data_source.c index 01443086..136f675a 100644 --- a/libisoburn/data_source.c +++ b/libisoburn/data_source.c @@ -27,16 +27,204 @@ #include "isoburn.h" -/* Cached reading of image tree data */ -/* Current implementation : single tile 128 kB */ +/* Powers of 2 only ! Less than 16 makes not much sense. */ +#define Libisoburn_tile_blockS 32 + +/* Undef to get to older single tile version +*/ +#define Libisoburn_cache_tileS 32 + +/* Debugging only: This reports cache loads on stderr. +#define Libisoburn_read_cache_reporT 1 +*/ + + +/* Cached reading of image tree data */ + +#ifdef Libisoburn_cache_tileS + +/* Multi tile: 32 * 64 kB */ + +struct isoburn_cache_tile { + char cache_data[Libisoburn_tile_blockS * 2048]; + uint32_t cache_lba; + uint32_t last_error_lba; + uint32_t last_aligned_error_lba; + int cache_hits; + int age; +}; + +struct isoburn_cached_drive { + struct burn_drive *drive; + struct isoburn_cache_tile tiles[Libisoburn_cache_tileS]; + int current_age; +}; + +#define Libisoburn_max_agE 2000000 + +static int ds_inc_age(struct isoburn_cached_drive *icd, int idx, int flag); + + +int ds_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer) +{ + int ret, i, oldest, oldest_age; + struct burn_drive *d; + off_t count; + uint32_t aligned_lba; + char msg[80]; + struct isoburn_cache_tile *tiles; + struct isoburn_cached_drive *icd; + + if(src == NULL || buffer == NULL) + return -1; + + icd = (struct isoburn_cached_drive *) src->data; + d = (struct burn_drive*) icd->drive; + tiles = (struct isoburn_cache_tile *) icd->tiles; + + aligned_lba= lba & ~(Libisoburn_tile_blockS - 1); + + for(i=0; i 0) + return 1; + tiles[oldest].last_error_lba = lba; + sprintf(msg, "ds_read_block(%lu) returns -1", (unsigned long) lba); + burn_msgs_submit(0x00060000, msg, 0, "DEBUG", NULL); + return -1; + } + +#ifdef Libisoburn_read_cache_reporT + fprintf(stderr, "Tile %2.2d : After %3d hits, new load from %8x , count= %d\n", + oldest, tiles[oldest].cache_hits, aligned_lba, (int) count); +#endif + + tiles[oldest].cache_lba= aligned_lba; + tiles[oldest].cache_hits= 1; + ds_inc_age(icd, oldest, 0); + + memcpy(buffer, tiles[oldest].cache_data + (lba - aligned_lba) * 2048, 2048); + count= 2048; + + return 1; +} + + +static int ds_open(IsoDataSource *src) +{ + /* nothing to do, device is always grabbed */ + return 1; +} + +static int ds_close(IsoDataSource *src) +{ + /* nothing to do, device is always grabbed */ + return 1; +} + +static void ds_free_data(IsoDataSource *src) +{ + /* nothing to do */; + if(src->data != NULL) + free(src->data); + src->data= NULL; +} + +IsoDataSource *isoburn_data_source_new(struct burn_drive *d) +{ + IsoDataSource *ret; + struct isoburn_cached_drive *icd= NULL; + int i; + + if (d==NULL) + return NULL; + ret = malloc(sizeof(IsoDataSource)); + icd = calloc(1,sizeof(struct isoburn_cached_drive)); + if (ret == NULL || icd == NULL) + return NULL; + ret->refcount = 1; + ret->read_block = ds_read_block; + ret->open = ds_open; + ret->close = ds_close; + ret->free_data = ds_free_data; + ret->data = icd; + icd->drive = d; + icd->current_age= 0; + for(i= 0; itiles[i].cache_lba = 0xffffffff; + icd->tiles[i].cache_hits = 0; + icd->tiles[i].last_error_lba = 0xffffffff; + icd->tiles[i].last_aligned_error_lba = 0xffffffff; + icd->tiles[i].age= 0; + } + return ret; +} + + +static int ds_inc_age(struct isoburn_cached_drive *icd, int idx, int flag) +{ + int i; + + (icd->current_age)++; + if(icd->current_age>=Libisoburn_max_agE) { /* reset all ages (allow waste) */ + for(i= 0; itiles)[i].age= 0; + icd->current_age= 1; + } + (icd->tiles)[idx].age= icd->current_age; + return(1); +} + + +#else /* Libisoburn_cache_tileS */ + + +/* Single tile 128 kB */ -/* powers of 2 only ! */ -#define Libisoburn_cache_blockS 64 struct isoburn_cached_drive { struct burn_drive *drive; - char cache_data[Libisoburn_cache_blockS * 2048]; + char cache_data[Libisoburn_tile_blockS * 2048]; uint32_t cache_lba; uint32_t last_error_lba; uint32_t last_aligned_error_lba; @@ -47,9 +235,6 @@ struct isoburn_cached_drive { /* Debugging only: This reports cache loads on stderr. #define Libisoburn_read_cache_reporT 1 */ -#define Libisoburn_use_read_cachE - -#ifdef Libisoburn_use_read_cachE int ds_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer) @@ -68,7 +253,7 @@ ds_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer) icd = (struct isoburn_cached_drive *) src->data; d = (struct burn_drive*) icd->drive; - aligned_lba= lba & ~(Libisoburn_cache_blockS - 1); + aligned_lba= lba & ~(Libisoburn_tile_blockS - 1); if(aligned_lba == icd->cache_lba && icd->cache_lba != 0xffffffff) { (icd->cache_hits)++; memcpy(buffer, icd->cache_data + (lba - aligned_lba) * 2048, 2048); @@ -82,7 +267,7 @@ ds_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer) } else { ret = burn_read_data(d, (off_t) aligned_lba * (off_t) 2048, (char *) icd->cache_data, - Libisoburn_cache_blockS * 2048, &count, 0); + Libisoburn_tile_blockS * 2048, &count, 0); } if (ret <= 0 ) { icd->last_aligned_error_lba = aligned_lba; @@ -114,31 +299,7 @@ ds_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer) return 1; } -#else /* Libisoburn_use_read_cachE */ -static int -ds_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer) -{ - int ret; - struct burn_drive *d; - off_t count; - - if(src == NULL || buffer == NULL) - return -1; - - d = (struct burn_drive*) ((struct isoburn_cached_drive *) src->data)->drive; - - ret = burn_read_data(d, (off_t) lba * (off_t) 2048, (char *) buffer, - 2048, &count, 0); - if (ret <= 0 ) - return -1; - - return 1; -} - -#endif /* ! Libisoburn_use_read_cachE */ - - static int ds_open(IsoDataSource *src) { @@ -188,3 +349,5 @@ isoburn_data_source_new(struct burn_drive *d) return ret; } +#endif /* ! Libisoburn_cache_tileS */ + diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index f2664785..a1b43955 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2008.03.31.081347" +#define Xorriso_timestamP "2008.04.01.213121"