1
1
forked from 0ad/0ad

simplification: only VFS allocates output buffer

This was SVN commit r1051.
This commit is contained in:
janwas 2004-08-24 17:34:00 +00:00
parent 13e5f5dc11
commit df5ba1f690
3 changed files with 25 additions and 60 deletions

View File

@ -835,7 +835,7 @@ skip_issue:
ssize_t file_io(File* const f, const off_t data_ofs, size_t data_size, void** const p, ssize_t file_io(File* const f, const off_t data_ofs, size_t data_size, void* const data_buf,
const FileIOCB cb, const uintptr_t ctx) // optional const FileIOCB cb, const uintptr_t ctx) // optional
{ {
#ifdef PARANOIA #ifdef PARANOIA
@ -847,9 +847,6 @@ debug_out("file_io fd=%d size=%d ofs=%d\n", f->fd, data_size, data_ofs);
const bool is_write = !!(f->flags & FILE_WRITE); const bool is_write = !!(f->flags & FILE_WRITE);
const bool no_aio = !!(f->flags & FILE_NO_AIO); const bool no_aio = !!(f->flags & FILE_NO_AIO);
void* data_buf = 0; // I/O source or sink buffer
// when reading: // when reading:
if(!is_write) if(!is_write)
{ {
@ -861,46 +858,21 @@ debug_out("file_io fd=%d size=%d ofs=%d\n", f->fd, data_size, data_ofs);
} }
// bool temp = (data_buf == 0);
// set buffer options
//
enum { TEMP, USER, ALLOC } buf_type;
// .. temp buffer
if(!p)
buf_type = TEMP;
// .. user-specified buffer (=> no align)
else if(*p)
{
buf_type = USER;
data_buf = *p;
}
// .. we allocate the buffer
else
{
buf_type = ALLOC;
// data_buf will be set from actual_buf
}
// sanity checks: // sanity checks:
// .. temp blocks requested AND // .. temp blocks requested AND
// (not reading OR using lowio OR no callback) // (not reading OR using lowio OR no callback)
if(buf_type == TEMP && (is_write || no_aio || !cb)) if(temp && (is_write || no_aio || !cb))
{ {
invalid:
debug_warn("file_io: invalid parameter"); debug_warn("file_io: invalid parameter");
return ERR_INVALID_PARAM; return ERR_INVALID_PARAM;
} }
// .. write, but no buffer passed in.
if(is_write && buf_type != USER)
goto invalid;
// only align if we allocate the buffer and in AIO mode // only align if we allocate the buffer and in AIO mode
const bool do_align = buf_type != USER && !no_aio; const bool do_align = temp;
const bool cache = buf_type == TEMP; const bool cache = temp;
// //
@ -927,14 +899,6 @@ invalid:
actual_size = round_up(ofs_misalign + data_size, BLOCK_SIZE); actual_size = round_up(ofs_misalign + data_size, BLOCK_SIZE);
} }
if(buf_type == ALLOC)
{
actual_buf = mem_alloc(actual_size, BLOCK_SIZE);
if(!actual_buf)
return ERR_NO_MEM;
data_buf = (char*)actual_buf + lead_padding;
}
// warn in debug build if buffer and offset don't match // warn in debug build if buffer and offset don't match
// (=> aio would have to realign every block). // (=> aio would have to realign every block).
#ifndef NDEBUG #ifndef NDEBUG
@ -989,7 +953,7 @@ invalid:
off_t issue_ofs = (off_t)(actual_ofs + issue_cnt); off_t issue_ofs = (off_t)(actual_ofs + issue_cnt);
void* buf = (buf_type == TEMP)? 0 : (char*)actual_buf + issue_cnt; void* buf = (temp)? 0 : (char*)actual_buf + issue_cnt;
ssize_t issued = block_issue(f, slot, issue_ofs, buf); ssize_t issued = block_issue(f, slot, issue_ofs, buf);
if(issued < 0) if(issued < 0)
err = issued; err = issued;
@ -1039,7 +1003,7 @@ invalid:
// we have useable data from a previous temp buffer, // we have useable data from a previous temp buffer,
// but it needs to be copied into the user's buffer // but it needs to be copied into the user's buffer
if(from_cache && buf_type != TEMP) if(from_cache && !temp)
memcpy((char*)data_buf+raw_transferred_cnt, data, size); memcpy((char*)data_buf+raw_transferred_cnt, data, size);
@ -1067,7 +1031,7 @@ if(from_cache && buf_type != TEMP)
if(!from_cache) if(!from_cache)
file_discard_io(slot->io); file_discard_io(slot->io);
if(buf_type == TEMP) if(temp)
{ {
// adding is allowed and we didn't take this from the cache already: add // adding is allowed and we didn't take this from the cache already: add
if(!slot->cached_block) if(!slot->cached_block)
@ -1081,20 +1045,7 @@ if(from_cache && buf_type != TEMP)
// failed (0 means callback reports it's finished) // failed (0 means callback reports it's finished)
if(err < 0) if(err < 0)
{
// user didn't specify output buffer - free what we allocated,
// and clear p (value-return param)
if(buf_type == ALLOC)
{
mem_free(actual_buf);
*p = 0;
// alloc_buf => p != 0
}
return err; return err;
}
if(p)
*p = data_buf;
assert(issue_cnt >= raw_transferred_cnt && raw_transferred_cnt >= data_size); assert(issue_cnt >= raw_transferred_cnt && raw_transferred_cnt >= data_size);

View File

@ -146,7 +146,7 @@ extern int file_discard_io(FileIO io);
// >= 0: bytes output; continue. // >= 0: bytes output; continue.
typedef ssize_t(*FileIOCB)(uintptr_t ctx, void* p, size_t size); typedef ssize_t(*FileIOCB)(uintptr_t ctx, void* p, size_t size);
extern ssize_t file_io(File* f, off_t ofs, size_t size, void** p, FileIOCB cb = 0, uintptr_t ctx = 0); extern ssize_t file_io(File* f, off_t ofs, size_t size, void* buf, FileIOCB cb = 0, uintptr_t ctx = 0);
#endif // #ifndef FILE_H #endif // #ifndef FILE_H

View File

@ -1343,14 +1343,28 @@ debug_out("vfs_io size=%d\n", size);
off_t ofs = vf->ofs; off_t ofs = vf->ofs;
vf->ofs += (off_t)size; vf->ofs += (off_t)size;
void* buf = 0; // assume temp buffer (p == 0)
if(p)
// user-specified buffer
if(*p)
buf = *p;
// we allocate
else
{
buf = mem_alloc(round_up(size, 4096), 4096);
if(!buf)
return ERR_NO_MEM;
*p = buf;
}
// (vfs_open makes sure it's not opened for writing if zip) // (vfs_open makes sure it's not opened for writing if zip)
if(vf_flags(vf) & VF_ZIP) if(vf_flags(vf) & VF_ZIP)
return zip_read(&vf->zf, ofs, size, p, cb, ctx); return zip_read(&vf->zf, ofs, size, buf, cb, ctx);
// normal file: // normal file:
// let file_io alloc the buffer if the caller didn't (i.e. p = 0), // let file_io alloc the buffer if the caller didn't (i.e. p = 0),
// because it knows about alignment / padding requirements // because it knows about alignment / padding requirements
return file_io(&vf->f, ofs, size, p, cb, ctx); return file_io(&vf->f, ofs, size, buf, cb, ctx);
} }