Help improving UnRAR performance

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
AnonymousTipster
Posts: 197
Joined: Fri Jul 01, 2005 2:50 am

Help improving UnRAR performance

Post by AnonymousTipster »

In order to add .rar support to my unzipping utility, I ported the UnRAR library from rarlabs. It took a little fiddling with to make it PSP-compatible, but soon enough I had it extracting .rar (including RAR3) files to the memory stick.
Problem was that it was slow on my Sony MS because it uses the POSIX io functions (fopen, fclose etc). To speed up writing I need to convert the data to 64bit aligned (easily done), and port to sceIo functions which is what i'm having trouble with.

I have three main options:
1. Port all the code in file.cpp to use sceIo functions.
This was the first thing I tried to do, however it proved unsuccessful for some reason. Most of the functions were ported fine from fopen - sceIoOpen, except functions such as fflush and ferror which I either commented out or forced a succeed value.
The functions I couldn't find for sceIo were: fflush ferror clearerr and fileno; might these be important? The other function was ftell, which I substituted as: sceIoLseek((SceUID)hFile,0,SEEK_CUR);
This code ends up making the app throw a memory exception, which is odd, as I don't see where I can be losing memory from.

2. Try to port just the write code by closing the FILE and opening a SceUID, writing, closing then re-opening as FILE. My code ended up looking like this:

Code: Select all

u8* data2;data2=(u8*)memalign(64,Size);
	memcpy(data2,Data,Size);
	long told;
	told = ftell(hFile);
	fclose(hFile);
	SceUID tempHFILE;
	tempHFILE = sceIoOpen(hFileName,O_RDWR | O_CREAT, 0777);
    //int Written=fwrite(data2,1,Size,hFile);
	sceIoLseek(tempHFILE,told,SEEK_SET);
	int Written=sceIoWrite(tempHFILE,data2,Size);
	sceIoClose(tempHFILE);
	hFile = fopen(hFileName,"rwb");
	fseek(hFile,told+Written,SEEK_SET);
	free(data2);
    Success=Written==Size;// && !ferror(hFile);
But this didn't work (though I'm not surprised). The memory stick light just stays on.

3. Some sort of way to write the file using fwrite to memory, then using sceIoWrite to write to the stick.

Can anyone help with any of these?
Thanks.
Arwin
Posts: 426
Joined: Tue Jul 12, 2005 7:00 pm

Post by Arwin »

I assume you need flush to make sure asynch stuff gets written? I'm totally not sure.

However, you can maybe download the Lua Player source code and take your cues from there, as it should have all IO operations implemented?
User avatar
Jim
Posts: 476
Joined: Sat Jul 02, 2005 10:06 pm
Location: Sydney
Contact:

Post by Jim »

You could always write your own functions to emulate the posix ones so that you are using a decent sized write cache. Little tiny read and writes to the MS are excruciatingly slow.

Jim
AnonymousTipster
Posts: 197
Joined: Fri Jul 01, 2005 2:50 am

Post by AnonymousTipster »

I've added in some printfs to find out when the File::Open command is used, and what it is opening, and there seems to be a problem coming from here.
I'm using the version that I've converted all the IO functions to sceIo.
First it attempts to open a file that appears as lots of \n and then a few random characters. This errors out (as it should). Then the extractor tries to open ms0:/test.rar which also fails, despite the file existing on the memory stick.

Code: Select all

SceUID handle;
  handle=sceIoOpen((const char*)Name,flags,0777);
  pspDebugScreenPrintf("Opened%s",Name);
  if&#40;handle < 0&#41;&#123;pspDebugScreenPrintf&#40;"ERROR!!"&#41;;sceIoClose&#40;handle&#41;;handle = BAD_HANDLE;ErrorType=FILE_NOTFOUND;&#125;
In the case of test.rar, flags should be O_RDONLY, but sceIoOpen returns < 0. Oddly, if I force the flags to O_RDWR, the file open succeeds, but cannot be read, and leaves me with a corrupt 0kb file.

Any thoughts on what might be causing this behaviour?
raf
Posts: 57
Joined: Thu Oct 13, 2005 7:38 am

Post by raf »

AnonymousTipster wrote:I've added in some printfs to find out when the File::Open command is used, and what it is opening, and there seems to be a problem coming from here.
I'm using the version that I've converted all the IO functions to sceIo.
First it attempts to open a file that appears as lots of \n and then a few random characters. This errors out (as it should). Then the extractor tries to open ms0:/test.rar which also fails, despite the file existing on the memory stick.

Code: Select all

SceUID handle;
  handle=sceIoOpen&#40;&#40;const char*&#41;Name,flags,0777&#41;;
  pspDebugScreenPrintf&#40;"Opened%s",Name&#41;;
  if&#40;handle < 0&#41;&#123;pspDebugScreenPrintf&#40;"ERROR!!"&#41;;sceIoClose&#40;handle&#41;;handle = BAD_HANDLE;ErrorType=FILE_NOTFOUND;&#125;
In the case of test.rar, flags should be O_RDONLY, but sceIoOpen returns < 0. Oddly, if I force the flags to O_RDWR, the file open succeeds, but cannot be read, and leaves me with a corrupt 0kb file.

Any thoughts on what might be causing this behaviour?
You need to map the POSIX flags in the code to the SCE flags....
They are defined pspiofilemgr_fcntl.h, as PSP_O_RDONLY, etc...

Raf.
AnonymousTipster
Posts: 197
Joined: Fri Jul 01, 2005 2:50 am

Post by AnonymousTipster »

Ah, thanks a lot raf, that's just what I needed to know ^_^
Post Reply