forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Free memory available functions

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
johnmph



Joined: 23 Jul 2005
Posts: 119

PostPosted: Tue Jan 24, 2006 1:47 am    Post subject: Free memory available functions Reply with quote

Hello, i have coded little functions to know all memory available and maximum lineare memory available :

Header :

Code:


#ifndef RAM_INCLUDED
#define RAM_INCLUDED

/* RAM simple check functions header */


// *** INCLUDES ***

#include <psptypes.h>
#include <malloc.h>


// *** DEFINES ***

#define RAM_BLOCK      (1024 * 1024)


// *** FUNCTIONS DECLARATIONS ***

u32 ramAvailableLineareMax (void);
u32 ramAvailable (void);

#endif



Source :

Code:


/* RAM simple check functions source */


// *** INCLUDES ***

#include "ram.h"


// *** FUNCTIONS ***

u32 ramAavailableLineareMax (void)
{
 u32 size, sizeblock;
 u8 *ram;


 // Init variables
 size = 0;
 sizeblock = RAM_BLOCK;

 // Check loop
 while (sizeblock)
 {
  // Increment size
  size += sizeblock;

  // Allocate ram
  ram = malloc(size);

  // Check allocate
  if (!(ram))
  {
   // Restore old size
   size -= sizeblock;

   // Size block / 2
   sizeblock >>= 1;
  }
  else
   free(ram);
 }

 return size;
}

u32 ramAvailable (void)
{
 u8 **ram, **temp;
 u32 size, count, x;


 // Init variables
 ram = NULL;
 size = 0;
 count = 0;

 // Check loop
 for (;;)
 {
  // Check size entries
  if (!(count % 10))
  {
   // Allocate more entries if needed
   temp = realloc(ram,sizeof(u8 *) * (count + 10));
   if (!(temp)) break;
 
   // Update entries and size (size contains also size of entries)
   ram = temp;
   size += (sizeof(u8 *) * 10);
  }

  // Find max lineare size available
  x = ramAvailableLineareMax();
  if (!(x)) break;

  // Allocate ram
  ram[count] = malloc(x);
  if (!(ram[count])) break;

  // Update variables
  size += x;
  count++;
 }

 // Free ram
 if (ram)
 {
  for (x=0;x<count;x++) free(ram[x]);
  free(ram);
 }

 return size;
}



Last edited by johnmph on Tue Jan 24, 2006 2:59 am; edited 1 time in total
Back to top
View user's profile Send private message
AnonymousTipster



Joined: 01 Jul 2005
Posts: 197

PostPosted: Tue Jan 24, 2006 2:58 am    Post subject: Reply with quote

I also coded one a week or so ago:
http://forums.ps2dev.org/viewtopic.php?t=4567&highlight=ram+free
Which calculates to 0.1MB each time. Yours is more elegant, though.
Back to top
View user's profile Send private message
johnmph



Joined: 23 Jul 2005
Posts: 119

PostPosted: Tue Jan 24, 2006 3:16 am    Post subject: Reply with quote

AnonymousTipster wrote:
I also coded one a week or so ago:
http://forums.ps2dev.org/viewtopic.php?t=4567&highlight=ram+free
Which calculates to 0.1MB each time. Yours is more elegant, though.


Thanks, yes it's similary.

I have coded a little sample for test it :

Code:


int main (void)
{
 int x;
 u8 **ram;


 pspDebugScreenInit();
 pspDebugScreenClear();
 SetupCallbacks();


 printf("Memory available before : %d\n",ramAvailable());

 ram = malloc(100 * sizeof(u8 *));

 if (ram)
 {
  memset(ram,0,sizeof(u8 *) * 100);

  for (x=0;x<100;x++) ram[x] = malloc(1000);

  printf("Memory available after malloc : %d\n",ramAvailable());

  for (x=0;x<100;x++) if (ram[x]) free(ram[x]);

  free(ram);
 }

 printf("Memory available after free : %d\n",ramAvailable());

 printf("HOME for quit\n");
 for (;;) sceDisplayWaitVblankStart();

 sceKernelExitGame();

 return 0;
}



The program allocates 100 blocks of 1000 bytes (100000 bytes) + array of pointers to these blocks (100 * sizeof(U8 *) -> 100 * 4 = 400) = 100400 bytes.


When the program begins, it shows the free memory available before it allocates block :

23551384 bytes

and after block allocation :

23450176 bytes

but 23551384 - 100400 = 23450984 bytes

23450984 - 23450176 = 808 bytes

What is these 808 bytes ?, malloc structure informations ?, alignement of memory ??
Back to top
View user's profile Send private message
TyRaNiD



Joined: 18 Jan 2004
Posts: 918

PostPosted: Tue Jan 24, 2006 4:28 am    Post subject: Reply with quote

Of course if you know your heap size (by using the PSP_HEAP_SIZE_KB macro) you can find the free space pretty easily.

Code:

#include <malloc.h>

PSP_HEAP_SIZE_KB(20*1024);

...

   struct mallinfo mi;

   mi = mallinfo();
   printf("freememory %dbytes\n", ((20*1024*1024) - mi.arena + mi.fordblks);


Perhaps it would be a good idea to provide an accessor to get the ELF allocated heap size (which is as much memory as it can get) into newlib so you can do this sort of calculation trivially.

There does seem to be some wastage as you point out, probably for alignment and control structures I guess, not 100% sure without digging into the malloc routines ;) I also don't know how to easily determine the largest contiguous block available without doing something like you are doing.
Back to top
View user's profile Send private message
johnmph



Joined: 23 Jul 2005
Posts: 119

PostPosted: Tue Jan 24, 2006 6:14 am    Post subject: Reply with quote

TyRaNiD wrote:
Of course if you know your heap size (by using the PSP_HEAP_SIZE_KB macro) you can find the free space pretty easily.

Code:

#include <malloc.h>

PSP_HEAP_SIZE_KB(20*1024);

...

   struct mallinfo mi;

   mi = mallinfo();
   printf("freememory %dbytes\n", ((20*1024*1024) - mi.arena + mi.fordblks);


Perhaps it would be a good idea to provide an accessor to get the ELF allocated heap size (which is as much memory as it can get) into newlib so you can do this sort of calculation trivially.

There does seem to be some wastage as you point out, probably for alignment and control structures I guess, not 100% sure without digging into the malloc routines ;) I also don't know how to easily determine the largest contiguous block available without doing something like you are doing.


Thanks for mallinfo tricks ;-).

In fact, i have coded these functions to know if in my code, i didn't forget to free all memory.

But when i use a simple png load or save function, not all the memory is free (+- 400 bytes lost).

This is the save function, i have checked it and i don't found any errors :

Code:


 // Open file
 fd = fopen(filename,"wb");
 if (!(fd)) return 2;

 // Create PNG write structure
 pngWrite = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
 if (!(pngWrite))
 {
  fclose(fd);

  return 3;
 }

 // Create PNG info structure
 pngInfo = png_create_info_struct(pngWrite);
 if (!(pngInfo))
 {
  png_destroy_write_struct(&pngWrite,png_infopp_NULL);
  fclose(fd);

  return 4;
 }

 // Write file
 png_init_io(pngWrite,fd);
 png_set_IHDR(pngWrite,pngInfo,image->width,image->height,8,PNG_COLOR_TYPE_RGB,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
 png_write_info(pngWrite,pngInfo);

 // Allocate one line
 line = (u8 *) malloc(image->width * 3);
 if (!(line))
 {
  png_destroy_write_struct(&pngWrite,&pngInfo);
  fclose(fd);

  return 5;
 }

 // Initialize bmp pointer
 bmp = image->bmp;

 // Height loop
 for (y=0;y<image->height;y++)
 {
  // Width loop
  for (x=0,x2=0;x<image->width;x++)
  {
   // Write pixel in line
   line[x2++] = GRAPHIC_GET_COLOR_R(bmp[x]);
   line[x2++] = GRAPHIC_GET_COLOR_G(bmp[x]);
   line[x2++] = GRAPHIC_GET_COLOR_B(bmp[x]);
  }

  // Write line
  png_write_row(pngWrite,line);

  // Go to the next line
  bmp += image->widthA;
 }

 // Free memory
 free(line);
 png_write_end(pngWrite,pngInfo);
 png_destroy_write_struct(&pngWrite,&pngInfo);
 fclose(fd);

 return 0;




It's possible that png functions doesn't free correctly memory ???
Back to top
View user's profile Send private message
johnmph



Joined: 23 Jul 2005
Posts: 119

PostPosted: Thu Jan 26, 2006 3:56 am    Post subject: Reply with quote

With these functions, i have found some errors (forget to free memory) in my code, now the code is clean ;-) WITHOUT png functions.

I have coded a little bmp load function to test it and the program works and all memory is free but if i use png functions instead my bmp functions, there is always these bytes lost (+- 400).

I think seriously that png functions doesn't free all memory.
Back to top
View user's profile Send private message
johnmph



Joined: 23 Jul 2005
Posts: 119

PostPosted: Thu Jan 26, 2006 4:52 am    Post subject: Reply with quote

I have found the function that cause the bytes lost, it's fopen.

When i use fopen and fclose, 384 bytes are lost, maybe it's normal, i don't know.
Back to top
View user's profile Send private message
jimparis



Joined: 10 Jun 2005
Posts: 1179
Location: Boston

PostPosted: Thu Jan 26, 2006 6:03 am    Post subject: Reply with quote

How about just open() and close()? We allocate some mem in open() but it should get freed in close(). If the problem is just fopen/fclose, it's probably the internal buffering that newlib does; we didn't touch that code but it might be buggy.
Back to top
View user's profile Send private message
johnmph



Joined: 23 Jul 2005
Posts: 119

PostPosted: Fri Jan 27, 2006 1:49 am    Post subject: Reply with quote

jimparis wrote:
How about just open() and close()? We allocate some mem in open() but it should get freed in close(). If the problem is just fopen/fclose, it's probably the internal buffering that newlib does; we didn't touch that code but it might be buggy.


The problem is just fopen/fclose, if you write a little program like :

Code:


FILE *f;

printf("ram available before : %d\n",ramAvailable());

f=fopen("ms0:/test.bin","rb");
if (f) fclose(f);

printf("ram available after : %d\n",ramAvailable());



The ram available after has 384 bytes less than before the fopen/fclose call even if the file is not opened (if the file doesn't exist).
Back to top
View user's profile Send private message
dot_blank



Joined: 28 Sep 2005
Posts: 498
Location: Brasil

PostPosted: Thu Apr 13, 2006 4:34 pm    Post subject: Reply with quote

has this been remedied yet
_________________
10011011 00101010 11010111 10001001 10111010
Back to top
View user's profile Send private message
PeterM



Joined: 31 Dec 2005
Posts: 125
Location: Edinburgh, UK

PostPosted: Thu Apr 13, 2006 6:32 pm    Post subject: Reply with quote

Is it something that needs fixed? I'm quite happy for functions to maintain an internal buffer, as long as they don't leak each time they're called.
Back to top
View user's profile Send private message Visit poster's website
Art



Joined: 09 Nov 2005
Posts: 647

PostPosted: Sat Aug 05, 2006 1:48 am    Post subject: Reply with quote

Code:
   printf("ESTIMATED FREE RAM: %d BYTES", ((20*1024*1024) - mi.arena + mi.fordblks);

I'm not having the best time with it...
any idea why I get a syntax error in this line when I have included
include <malloc.h>
?
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Sat Aug 05, 2006 1:56 am    Post subject: Reply with quote

You sure you also did include these lines:
Quote:
PSP_HEAP_SIZE_KB(20*1024);

...

struct mallinfo mi;

mi = mallinfo();

They are crucial for this method to work.
_________________
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Back to top
View user's profile Send private message Visit poster's website
Art



Joined: 09 Nov 2005
Posts: 647

PostPosted: Sat Aug 05, 2006 2:22 am    Post subject: Reply with quote

Doh, I think I put the bottom two lines inside the function.. which is probably wrong.

I *think* I have johnMPH's code working now... just got to use more
or less RAM to check it.
Cheers, Art.
Back to top
View user's profile Send private message
Art



Joined: 09 Nov 2005
Posts: 647

PostPosted: Sat Aug 05, 2006 4:13 am    Post subject: Reply with quote

Although the function appears to work,
My program reports the same amount of available memory right down
to the exact byte whether it was started from IRshell or not.

IRshell must use some memory.. it hangs around because you can use
the note button to take a screenshot when your app is running.. so it must
be running somethng that uses RAM.
Back to top
View user's profile Send private message
AnonymousTipster



Joined: 01 Jul 2005
Posts: 197

PostPosted: Sat Aug 05, 2006 4:22 am    Post subject: Reply with quote

Actually, iRShell resides almost entirely in kernel memory space and only breaks into user space with wifi and image viewing functions.
I think a better way to detect if running from a shell is to look at the psplink source to find what modules are running, and see if there are any more than usual.
You might want to ask Tyranid about this though, as the number may fluctuate, and I think it may also require a kernel mode application to work.
Back to top
View user's profile Send private message
Fanjita



Joined: 28 Sep 2005
Posts: 217

PostPosted: Sat Aug 05, 2006 7:02 am    Post subject: Reply with quote

AnonymousTipster wrote:
Actually, iRShell resides almost entirely in kernel memory space and only breaks into user space with wifi and image viewing functions.
I think a better way to detect if running from a shell is to look at the psplink source to find what modules are running, and see if there are any more than usual.
You might want to ask Tyranid about this though, as the number may fluctuate, and I think it may also require a kernel mode application to work.


You should be able to get sufficient info from the user-mode module info functions for these purposes, kernel isn't necessary.
_________________
Got a v2.0-v2.80 firmware PSP? Download the eLoader here to run homebrew on it!
The PSP Homebrew Database needs you!
Back to top
View user's profile Send private message
Art



Joined: 09 Nov 2005
Posts: 647

PostPosted: Sat Aug 05, 2006 7:48 am    Post subject: Reply with quote

It even reports the same amount of memory,
if I start it from IRshell with an mp3 playing!
Back to top
View user's profile Send private message
siberianstar



Joined: 22 Jun 2006
Posts: 70

PostPosted: Wed Aug 09, 2006 10:44 pm    Post subject: Reply with quote

i wrote this in 2 seconds

Code:
#include <malloc.h>
int __freemem()
{
 void *ptrs[480];
 int mem, x, i;
 for (x = 0; x < 480; x++)
 {
    void *ptr = malloc(51200);
    if (!ptr) break;
 
    ptrs[x] = ptr;
 }
 mem = x * 51200;
 for (i = 0; i < x; i++)
  free(ptrs[i]);

 return mem;
}


simple and fast
Back to top
View user's profile Send private message
flatmush



Joined: 07 Aug 2007
Posts: 28
Location: Here

PostPosted: Sun Aug 26, 2007 6:20 am    Post subject: Reply with quote

Well I made quite a large post on psp-programming that is quite relevant to this topic, I hate to link to another forum but there seems little point in replicating the post here as it's quite large.
You will find a better free space function and lots of other memory related info here: http://www.psp-programming.com/forums/index.php?topic=2731.0

Old Post wrote:
Hate to bring up an old topic, but as it's a recurring question and this is the main thread for the answers to this question, I thought I'd post my algorithm.

This should be faster and more accurate than most the previous methods (except TyRaNiDs).

Code:

#define MEMORY_USER_SIZE 0x01800000

u32 memFreeSpace(u32 inAccuracy) {
    if(!inAccuracy)
         inAccuracy = 1;

    u32 tempBlockSize = (MEMORY_USER_SIZE >> 1);
    u32 tempTests;
   
    for(tempTests = 0; tempBlockSize > inAccuracy; tempTests++)
         tempBlockSize >>= 1;
    tempBlockSize = (MEMORY_USER_SIZE >> 1);

    void* tempPointers[tempTests];
   
    u32 i;
    u32 tempSpace = 0;
    for(i = 0; i < tempTests; i++) {
         tempPointers[i] = malloc(tempBlockSize);
         tempSpace += (tempPointers[i] ? tempBlockSize : 0);
         tempBlockSize >>= 1;
    }
   
    for(i = 0; i < tempTests; i++) {
         if(tempPointers[i])
              free(tempPointers[i]);
    }
   
    return tempSpace;
}


The inAccuracy parameter is how accurate you want the results to be, so 1 would give you the number of bytes, and 1024 would give the whole number of kilobytes etc.

EDIT: oops I feel stupid now, this will only work if your memory isn't fragmented at all, I'll have to think of a different approach (maybe recursive).
Back to top
View user's profile Send private message Visit poster's website AIM Address MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group