1
0
mirror of https://github.com/libretro/RetroArch synced 2024-07-03 08:48:42 +00:00

wiiu: Add fastpath for already aligned buffers

This commit is contained in:
Ash Logan 2021-07-18 22:31:43 +10:00
parent a3be19214e
commit e43f07b85b
2 changed files with 95 additions and 65 deletions

View File

@ -22,6 +22,9 @@
#include <stdio.h>
#include <stdlib.h>
#if defined(WIIU)
#include <malloc.h>
#endif
#include <file/nbio.h>
#include <encodings/utf.h>
@ -130,8 +133,14 @@ static void *nbio_stdio_open(const char * filename, unsigned mode)
handle->mode = mode;
#if defined(WIIU)
/* hit the aligned-buffer fast path on Wii U */
if (len)
buf = memalign(0x40, (size_t)len);
#else
if (len)
buf = malloc((size_t)len);
#endif
if (len && !buf)
goto error;

View File

@ -279,47 +279,56 @@ static ssize_t sd_fat_write_r (struct _reent *r, void* fd, const char *ptr, size
OSLockMutex(file->dev->pMutex);
size_t len_aligned = FS_ALIGN(len);
if(len_aligned > 0x4000)
len_aligned = 0x4000;
unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned);
if(!tmpBuf) {
r->_errno = ENOMEM;
OSUnlockMutex(file->dev->pMutex);
return 0;
}
size_t done = 0;
while(done < len)
{
size_t write_size = (len_aligned < (len - done)) ? len_aligned : (len - done);
memcpy(tmpBuf, ptr + done, write_size);
int result = FSWriteFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, write_size, file->fd, 0, -1);
#if 0
FSFlushFile(file->dev->pClient, file->dev->pCmd, file->fd, -1);
#endif
if(result < 0)
{
/* fast path: buffer is already correctly aligned */
if (!((uintptr_t)ptr & (FS_ALIGNMENT-1))) {
int result = FSWriteFile(file->dev->pClient, file->dev->pCmd, (uint8_t*)ptr, 1, len, file->fd, 0, -1);
if(result < 0) {
r->_errno = result;
break;
}
else if(result == 0)
{
if(write_size > 0)
done = 0;
break;
}
else
{
done += result;
} else {
done = result;
file->pos += result;
}
} else {
size_t len_aligned = FS_ALIGN(len);
if(len_aligned > 0x4000)
len_aligned = 0x4000;
unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned);
if(!tmpBuf) {
r->_errno = ENOMEM;
OSUnlockMutex(file->dev->pMutex);
return 0;
}
while(done < len)
{
size_t write_size = (len_aligned < (len - done)) ? len_aligned : (len - done);
memcpy(tmpBuf, ptr + done, write_size);
int result = FSWriteFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, write_size, file->fd, 0, -1);
if(result < 0)
{
r->_errno = result;
break;
}
else if(result == 0)
{
if(write_size > 0)
done = 0;
break;
}
else
{
done += result;
file->pos += result;
}
}
free(tmpBuf);
}
free(tmpBuf);
OSUnlockMutex(file->dev->pMutex);
return done;
}
@ -340,44 +349,56 @@ static ssize_t sd_fat_read_r (struct _reent *r, void* fd, char *ptr, size_t len)
OSLockMutex(file->dev->pMutex);
size_t len_aligned = FS_ALIGN(len);
if(len_aligned > 0x4000)
len_aligned = 0x4000;
unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned);
if(!tmpBuf) {
r->_errno = ENOMEM;
OSUnlockMutex(file->dev->pMutex);
return 0;
}
size_t done = 0;
while(done < len)
{
size_t read_size = (len_aligned < (len - done)) ? len_aligned : (len - done);
int result = FSReadFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, read_size, file->fd, 0, -1);
if(result < 0)
{
/* fast path: buffer is already correctly aligned */
if (!((uintptr_t)ptr & (FS_ALIGNMENT-1))) {
int result = FSReadFile(file->dev->pClient, file->dev->pCmd, (uint8_t*)ptr, 1, len, file->fd, 0, -1);
if(result < 0) {
r->_errno = result;
done = 0;
break;
}
else if(result == 0)
{
/*! TODO: error on read_size > 0 */
break;
}
else
{
memcpy(ptr + done, tmpBuf, read_size);
done += result;
} else {
done = result;
file->pos += result;
}
} else {
size_t len_aligned = FS_ALIGN(len);
if(len_aligned > 0x4000)
len_aligned = 0x4000;
unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned);
if(!tmpBuf) {
r->_errno = ENOMEM;
OSUnlockMutex(file->dev->pMutex);
return 0;
}
while(done < len)
{
size_t read_size = (len_aligned < (len - done)) ? len_aligned : (len - done);
int result = FSReadFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, read_size, file->fd, 0, -1);
if(result < 0)
{
r->_errno = result;
done = 0;
break;
}
else if(result == 0)
{
/*! TODO: error on read_size > 0 */
break;
}
else
{
memcpy(ptr + done, tmpBuf, read_size);
done += result;
file->pos += result;
}
}
free(tmpBuf);
}
free(tmpBuf);
OSUnlockMutex(file->dev->pMutex);
return done;
}