Hi! :)
J.F. wrote:What happens if you don't do the second sceIoClose()? Perhaps the leak is due to trying to close the file twice.
The same thing. I added the additional close to try to solve the leak...
Here's the full source I'm using:
Code: Select all
#include <pspkernel.h>
#include <pspctrl.h>
#include <pspdebug.h>
#include <pspsdk.h>
#include <stdlib.h>
#include "tremor/ivorbiscodec.h"
#include "tremor/ivorbisfile.h"
PSP_MODULE_INFO("eboot template", 0, 1, 0);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);
PSP_HEAP_SIZE_KB(2048);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Globals:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int runningFlag = 1;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Callbacks:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* Exit callback */
int exit_callback(int arg1, int arg2, void *common) {
runningFlag = 0;
return 0;
}
/* Callback thread */
int CallbackThread(SceSize args, void *argp) {
int cbid;
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);
sceKernelSleepThreadCB();
return 0;
}
/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void) {
int thid = 0;
thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0);
if(thid >= 0)
sceKernelStartThread(thid, 0, 0);
return thid;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Total free memory:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct
{
void *buffer;
void *next;
} _LINK;
int freemem(){
int size = 4096, total = 0;
_LINK *first = NULL, *current = NULL, *lnk;
while(runningFlag){
lnk = (_LINK*)malloc(sizeof(_LINK));
if (!lnk)
break;
total += sizeof(_LINK);
lnk->buffer = malloc(size);
if (!lnk->buffer){
free(lnk);
break;
}
total += size;
lnk->next = NULL;
if (current){
current->next = (void*)lnk;
current = lnk;
} else {
current = first = lnk;
}
}
lnk = first;
while (lnk){
free(lnk->buffer);
current = lnk->next;
free(lnk);
lnk = current;
}
return total;
}
/////////////////////////////////////////////////////////////////////////////////////////
//Callback for vorbis
/////////////////////////////////////////////////////////////////////////////////////////
size_t ogg_callback_read(void *ptr, size_t size, size_t nmemb, void *datasource){
return sceIoRead(*(int *) datasource, ptr, size * nmemb);
}
int ogg_callback_seek(void *datasource, ogg_int64_t offset, int whence){
return sceIoLseek32(*(int *) datasource, (unsigned int) offset, whence);
}
long ogg_callback_tell(void *datasource){
return sceIoLseek32(*(int *) datasource, 0, SEEK_CUR);
}
int ogg_callback_close(void *datasource){
return sceIoClose(*(int *) datasource);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Open/close an OGG file
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int openCloseOGG(char *filename){
int tempFile = 0;
OggVorbis_File vf;
//Apro il file OGG:
tempFile = sceIoOpen(filename, PSP_O_RDONLY, 0777);
if (tempFile >= 0) {
ov_callbacks ogg_callbacks;
ogg_callbacks.read_func = ogg_callback_read;
ogg_callbacks.seek_func = ogg_callback_seek;
ogg_callbacks.close_func = ogg_callback_close;
ogg_callbacks.tell_func = ogg_callback_tell;
if (ov_open_callbacks(&tempFile, &vf, NULL, 0, ogg_callbacks) < 0){
sceIoClose(tempFile);
return -1;
}
ov_clear(&vf);
}
return 0;
}
int openCloseOGGNoCallbacks(char *filename){
FILE *tempFile;
OggVorbis_File vf;
//Apro il file OGG:
tempFile = fopen(filename, "r");
if (tempFile != NULL) {
if (ov_open(tempFile, &vf, NULL, 0) < 0){
fclose(tempFile);
return -1;
}
ov_clear(&vf);
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Main:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main(){
pspDebugScreenInit();
SetupCallbacks();
pspDebugScreenPrintf("Test OGG Vorbis mem. leak\n\n");
pspDebugScreenPrintf("Free memory: %i\n", freemem() / 1024);
pspDebugScreenPrintf("Press X to load and unload with callbacks ms0:/test.ogg\n");
pspDebugScreenPrintf("Press SQUARE to load and unload without callbacks ms0:/test.ogg\n");
SceCtrlData pad;
while(runningFlag){
sceCtrlReadBufferPositive(&pad, 1);
if (pad.Buttons & PSP_CTRL_CROSS){
pspDebugScreenPrintf("Open result: %i\n", openCloseOGG("ms0:/test.ogg"));
pspDebugScreenPrintf("Free memory: %i\n", freemem() / 1024);
sceKernelDelayThread(200000);
}else if (pad.Buttons & PSP_CTRL_SQUARE){
pspDebugScreenPrintf("Open result: %i\n", openCloseOGGNoCallbacks("ms0:/test.ogg"));
pspDebugScreenPrintf("Free memory: %i\n", freemem() / 1024);
sceKernelDelayThread(200000);
}
}
sceKernelExitGame();
return 0;
}
Ciaooo
Sakya