ExtMem how to ?

This forum is for general developer support questions.
Post Reply
User avatar
TSK
Beta Tester
Beta Tester
Posts: 223
Joined: Mon Dec 20, 2010 1:15 pm
Location: Home land of Santa C., sauna, sisu and salmiakki

ExtMem how to ?

Post by TSK »

Could somebody give an example how to use the ExtMem feature ?
Keep the party going !
User avatar
colinw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 191
Joined: Mon Aug 15, 2011 9:20 am
Location: Brisbane, QLD. Australia.

Re: ExtMem how to ?

Post by colinw »

Here's something to get you going...

Code: Select all


/****************************************************************************/
/*
**  This example allocates blocks from the extmem space. 
**  The map() and unmap() allocate and free address space for the datablock->data.
**
**  Note that memory returned in extmem space has addresses mapped above the
**  first 2 gig.  (ie: High bit is always set).
**  Be carefull passing these addresses to other system and user functions,
**  they may not use unsigned pointers and addresses may appear negative. 
**
**  This example is written without test compilation or decent formatting,
**   be carefull of typos.  cjw.
*/




/****************************************************************************/



/*
** Example of a data block that can go into a list. 
*/
struct DataBlock   
{
     struct MinNode         node;          /* minlist node */
     struct ExtMemIFace *iextmem;     /* extmem interface pointer */
     uint32                     allocsize;     /* size of data allocated */
     APTR                      data;            /* pointer to the mapped memory or 0 if unmapped */
};




/****************************************************************************/



/*
**  Block free function.
*/
void free_block(struct DataBlock *block)
{
	if( block )
	{
		if( block->iextmem )
		{
			IExec->FreeSysObject(ASOT_EXTMEM,block->iextmem);
		}
		IExec->FreeVec(block);
	}

	return;
}





/****************************************************************************/




/*
**  Deallocate all blocks in a list.
*/
void free_block_list( struct List *list )
{
	struct Node *n;

	/*
	**  free all blocks in a list.
	*/
	while(( n = IExec->RemTail(list) ))
	{
		free_block((APTR)n);
	}

	return;
}





/****************************************************************************/





/*
**  Allocate a single block.
*/
struct DataBlock * allocate_block(uint32 size)
{
	struct DataBlock *block, *result = NULL;
	uint64 size64;

	if((block = IExec->AllocVecTags(sizeof(*block),AVT_Type,MEMF_SHARED,AVT_Lock,FALSE,AVT_ClearWithValue,0,TAG_END)))
	{
		size64 = size;  /* must be in a uint64 variable.*/

		block->iextmem = IExec->AllocSysObjectTags(ASOT_EXTMEM, 
			                                       ASOEXTMEM_Size, &size64,
		                                               ASOEXTMEM_AllocationPolicy, EXTMEMPOLICY_IMMEDIATE,
		                                               TAG_END);
		if( block->iextmem )
		{
			block->allocsize = size;
			result = block;
		}
		else
		{
			free_block(block); /* free datablock struct on failure */
		}
	}

	return(result);
}





/****************************************************************************/




/*
**  Map address space for block data.
*/
int32 map_block_data(struct DataBlock *block)
{
	int32 result = FALSE;   /* default for failure */

	if( block )
	{
		if( block->iextmem )
		{
			block->data = block->iextmem->Map(0,block->allocsize, 0LL, 0);

			if( block->data )
			{
				result = TRUE;
			}
		}
	}

	return(result);
}

 


/****************************************************************************/




/*
**  Release address space for block data.
*/
void unmap_block_data(struct DataBlock *block)
{
	if( block )
	{
		if( block->iextmem )
		{
			if( block->data )
			{
				block->iextmem->Unmap(block->data, block->allocsize);
				block->data = NULL;   /* clear pointer */
			}
		}
	}
}


/****************************************************************************/
/* EOF */

User avatar
ssolie
Beta Tester
Beta Tester
Posts: 1010
Joined: Mon Dec 20, 2010 8:51 pm
Location: Canada
Contact:

Re: ExtMem how to ?

Post by ssolie »

I've consolidated the docs I could find into this article:
http://wiki.amigaos.net/wiki/Exec_Extended_Memory

Thanks to Colin for the example. :)
ExecSG Team Lead
xenic
Posts: 1168
Joined: Sun Jun 19, 2011 12:06 am

Re: ExtMem how to ?

Post by xenic »

ssolie wrote:I've consolidated the docs I could find into this article:
http://wiki.amigaos.net/wiki/Exec_Extended_Memory
Maybe that extended memory would be more useful to the avarage user if we had an option to put RAM: in extended memory and free up all the normal system memory for program use. Since RAD: no longer survives a reboot and is less useful, another option might be the ability to put a RAD: drive in extended memory.
AmigaOne X1000 with 2GB memory - OS4.1 FE
User avatar
salass00
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 521
Joined: Sat Jun 18, 2011 3:12 pm
Location: Finland
Contact:

Re: ExtMem how to ?

Post by salass00 »

xenic wrote: Maybe that extended memory would be more useful to the avarage user if we had an option to put RAM: in extended memory and free up all the normal system memory for program use. Since RAD: no longer survives a reboot and is less useful, another option might be the ability to put a RAD: drive in extended memory.
The latest beta versions of ram-handler have supported extmem for quite some time thanks to Colin Wenzel. The wiki article is a little out of date in this respect.
chris
Posts: 552
Joined: Sat Jun 18, 2011 11:05 am
Contact:

Re: ExtMem how to ?

Post by chris »

colinw wrote:Here's something to get you going...
Very interesting, thanks. Where is the documentation for iextmem->Map()? I can't see it in ssolie's wiki article nor in the Autodoc (although I've probably missed it). The ASOT_EXTMEM doc is missing ASOEXTMEM_AllocationPolicy and possibly other tags too.
User avatar
colinw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 191
Joined: Mon Aug 15, 2011 9:20 am
Location: Brisbane, QLD. Australia.

Re: ExtMem how to ?

Post by colinw »

chris wrote: Very interesting, thanks. Where is the documentation for iextmem->Map()?
I can't see it in ssolie's wiki article nor in the Autodoc (although I've probably missed it).
The ASOT_EXTMEM doc is missing ASOEXTMEM_AllocationPolicy and possibly other tags too.
iextmem->Map() / UnMap() = sdk:include/include_h/exec/extmem.h
ASOEXTMEM_AllocationPolicy = sdk:include/include_h/exec/exectags.h
Extmem doc =

****** exec.library/ASOT_EXTMEM ******************************************
*
* NAME
* ASOT_EXTMEM - Extended memory object
*
* TAGS
* ASOEXTMEM_Size Size of the object, in bytes.
* The data is a pointer to a 64 bit integer.
*
* NOTES
* Creating this object only allocates the memory, it does not
* map anything.
*
*****************************************************************************
User avatar
colinw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 191
Joined: Mon Aug 15, 2011 9:20 am
Location: Brisbane, QLD. Australia.

Re: ExtMem how to ?

Post by colinw »

I just put together a new autodoc with more information. Here's a preview;

****** exec.library/ASOT_EXTMEM ******************************************
*
* NAME
* ASOT_EXTMEM - Extended memory object
*
* TAGS
* ASOEXTMEM_Size - The size of the object, in bytes.
* The data is a pointer to a 64 bit integer.
* There is no limit to the size, but there might not be enough free
* pages to map all of the object. This tag item is mandatory.
*
* ASOEXTMEM_AllocationPolicy - The allocation policy.
* This tag determines what way the pages for the memory object are
* allocated. There are three possible allocation policies right now:
* EXTMEMPOLICY_IMMEDIATE, EXTMEMPOLICY_DELAYED, EXTMEMPOLICY_ACCESS.
* The default policy is EXTMEMPOLICY_DELAYED.
*
* NOTES
* Creating this object only allocates memory, it does not map anything.
* After its creation the returned pointer is an interface ready to use.
* Right now, the interface contains two functions, Map and Unmap.
*
* The Map call looks like this:
* APTR Map(APTR baseAddr, uint32 length, uint64 offset, uint32 flags);
*
* 'baseAddr' is the address for the mapped window.
* If it is NULL, the operating system will pick a suitable address by
* itself, this may also be an address above 2 gig. Otherwise,
* the system will attempt to map the window at the given address.
* The flags parameter can influence the behavior of this (see below).
* The base address must be aligned to a page boundary.
*
* 'length' is the length of the window and by extension, the length of
* the mapped portion of the object. The parameter is limited by the
* available virtual address space. It is recommended to keep it
* reasonably large so that the application doesn't have to constantly
* remap the object, but small enough so that address space is not
* immediately exhausted.
*
* 'offset' is a 64 bit offset into the object at which the window
* begins. For all intent and purpose, the object itself has no address
* it just exists somewhere without a fixed address.
* The offset is the number of bytes, from the beginning of the object
* that should be mapped coiniciding with the base address.
* In other words, the mapping maps the byte at offset offset onto the
* address at baseAddr (whether it is system- or application-supplied),
* and all consecutive bytes until length bytes are mapped.
* As with the base address, the offset must be page-aligned.
*
* 'flags' determine a few options of the mapping.
* Currently, the following flags are defined and can be OR'ed.
* EXTMEMF_READONLY; If set, the mapped area is write-protected,
* and any nonsupervisor user can only read from it but not write.
* The default is to allow read and write access.
* EXTMEMF_PRIVATE;
* If set, the mapped area is inaccessible to anybody but the caller.
* This means that it cannot be used for message passing or other
* tasks that require a different process to access the memory.
* At the time of writing, this flag isn't implemented and does
* nothing yet, however, you are still encouraged to use it.
* EXTMEMF_FAIL_UNAVAIL;
* If the caller specifies a base address, this flag will determine
* how the allocation works if the base address is not available.
* If this is not set, the system will adjust the base address as
* it sees fit to make sure the mapping can be performed.
* It might move the base address around in order to achieve this.
* If the flag is set, and the base address is not available,
* the call will fail. The Map call will return either the base
* address of the mapping on successful completion, or NULL if an
* error occurred. In the latter case, no mapping will be done,
* not even partial, but pages might have been allocated for a
* portion of the window, depending on the allocation policy.
*
* The Unmap call looks like this:
* void Unmap(APTR baseAddr, uint32 length);
*
* As the name implies, this undoes what the Map call created.
* baseAddr must be the address returned by the Map call,
* the length must be the same length as used during mapping.
* Invalid input data is silently ignored.
*
*
*****************************************************************************
Post Reply