Memory

Data Structures

struct  OSL_MEMSTATUS
 

Macros

#define oslUncacheData(data, size)   sceKernelDcacheWritebackInvalidateRange(data, size);
 
#define oslGetUncachedPtr(adr)   ((void*)((int)(adr)|0x40000000))
 
#define oslGetCachedPtr(adr)   ((void*)((int)(adr)&(~0x40000000)))
 

Functions

int sceDmacMemcpy (void *dest, const void *source, unsigned int size)
 
int sceDmacTryMemcpy (void *dest, const void *source, unsigned int size)
 
void oslFasterMemset (u64 *dst, u64 *src, u32 length)
 
void oslFlushDataCache ()
 
void * memalign (size_t alignment, size_t size)
 
OSL_MEMSTATUS oslGetRamStatus ()
 

Detailed Description

Contains routines about memory (cache, copy, etc.).

Macro Definition Documentation

#define oslUncacheData (   data,
  size 
)    sceKernelDcacheWritebackInvalidateRange(data, size);

This routine will make sure that the data will no more reside in the CPU cache. The CPU does automatically put data in cache when you want to read or write to it, making subsequent accesses faster (because the cache is way faster than conventional RAM). The problem is that if the GE (graphic processor) for example wants to access it, it will read the real memory, and thus if some data is still sitting in the cache (not written to actual RAM yet) the GE will get incorrect data, making it crash or display corrupt graphics.

To avoid problems, you can either bypass the cache by writting to uncached addresses (oslGetUncachedPtr) or by flushing the data from cache before sending them to the GE (or DMA). This function, oslUncacheData, will flush the actual data from cache, writing it to real memory. This does take some time so don't abuse and call it only when necessary.

    \param data
            Adress of the memory area to flush.
    \param size
            Size (in bytes) of the area.

Uncaching should be done after you've accessed raw image / palette / something contents. This includes oslSetImagePixel and accesses to the raw image data pointed to by OSL_IMAGE::data.

Note: There are specific functions to uncache palettes and images, simplier to use. You should rather use them instead.

#define oslGetUncachedPtr (   adr)    ((void*)((int)(adr)|0x40000000))

Returns a pointer to an uncached address. In this case, cache will be bypassed and you'll not have to call oslUncache[something] after modifying data. However performance is usually worse and caching is a good thing, so do it if you know what you are doing.

Important: NEVER mix cached and uncached addresses when accessing somewhere. Either always access them as cached or unached. If you mix them some weird bugs may appear because you could for example write directly in memory bypassing the cache, but some data is still sitting in the cache. So, once the cache is full, data will be flushed and written to the memory, replacing the data you wrote in an uncached way. You will not understand why your data gets corrupted, and as this will maybe happen seconds later in special circumstances, so it will be impossible to detect or debug.

#define oslGetCachedPtr (   adr)    ((void*)((int)(adr)&(~0x40000000)))

Get a pointer to cached data. Same remark as above.

Function Documentation

int sceDmacMemcpy ( void *  dest,
const void *  source,
unsigned int  size 
)

Copies data using the internal DMAC. Should be faster than a memcpy, but requires that data to be copied is no more in the cache, so usually you should issue a oslUncacheData on the source and destination addresses else very strange bugs may happen.

int sceDmacTryMemcpy ( void *  dest,
const void *  source,
unsigned int  size 
)

Same as sceDmacMemcpy.

void oslFasterMemset ( u64 *  dst,
u64 *  src,
u32  length 
)

Does a memset using the 64-bit capabilities of the CPU. Faster than memcpy.

void oslFlushDataCache ( )
inline

Flushes the whole cache. This is slow, absolutely avoid it! Use oslUncacheData instead if possible.

void* memalign ( size_t  alignment,
size_t  size 
)

Allocates a memory block, ensuring it is aligned.

Parameters
alignmentAlignment in bytes
sizeSize of the block
OSL_MEMSTATUS oslGetRamStatus ( )

Gets info about currently available memory in main RAM. The return value is a OSL_MEMSTATUS structure which contains info about available memory.

Example:

//You can either store the result to a structure and access its members
oslDebug("%i bytes available", ram.maxAvailable);
//Or directly use the return value from the function, like this
oslDebug("%i bytes available", oslGetRamStatus().maxAvailable);

Note: About the example above, just notice that each call to oslGetRamStatus costs a lot of time, so if you need to retrieve several results (e.g. both maxAvailable and maxBlockSize) you should not use the second method as it will need two calls to oslGetRamStatus.