diff --git a/libretro-common/file/nbio/nbio_stdio.c b/libretro-common/file/nbio/nbio_stdio.c index 328e32aedb..e05968b6fa 100644 --- a/libretro-common/file/nbio/nbio_stdio.c +++ b/libretro-common/file/nbio/nbio_stdio.c @@ -22,6 +22,9 @@ #include #include +#if defined(WIIU) +#include +#endif #include #include @@ -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; diff --git a/wiiu/fs/sd_fat_devoptab.c b/wiiu/fs/sd_fat_devoptab.c index a179d10134..f9b6608bac 100644 --- a/wiiu/fs/sd_fat_devoptab.c +++ b/wiiu/fs/sd_fat_devoptab.c @@ -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; }