TABLE OF CONTENTS exec.library/AbortIO exec.library/AddDevice exec.library/AddHead exec.library/AddInterface exec.library/AddIntServer exec.library/AddLibrary exec.library/AddMemhandler exec.library/AddMemList exec.library/AddPort exec.library/AddResetCallback exec.library/AddResource exec.library/AddSemaphore exec.library/AddTail exec.library/AddTask exec.library/AddTrackable exec.library/Alert exec.library/AllocAbs exec.library/Allocate exec.library/AllocEntry exec.library/AllocMem exec.library/AllocNamedMemory exec.library/AllocPooled exec.library/AllocSignal exec.library/AllocSysObject exec.library/AllocTaskMemEntry exec.library/AllocTrap exec.library/AllocVec exec.library/AllocVecPooled exec.library/AllocVecTags exec.library/ASOT_DMAENTRY exec.library/ASOT_EXTMEM exec.library/ASOT_HOOK exec.library/ASOT_INTERRUPT exec.library/ASOT_IOREQUEST exec.library/ASOT_ITEMPOOL exec.library/ASOT_LIST exec.library/ASOT_MEMPOOL exec.library/ASOT_MESSAGE exec.library/ASOT_MUTEX exec.library/ASOT_NODE exec.library/ASOT_PORT exec.library/ASOT_RMAP exec.library/ASOT_SEMAPHORE exec.library/ASOT_TAGLIST exec.library/AttemptNamedMemory exec.library/AttemptSemaphore exec.library/AttemptSemaphoreShared exec.library/AvailMem exec.library/AVL_AddNode exec.library/AVL_FindFirstNode exec.library/AVL_FindLastNode exec.library/AVL_FindNextNodeByAddress exec.library/AVL_FindNextNodeByKey exec.library/AVL_FindNode exec.library/AVL_FindPrevNodeByAddress exec.library/AVL_FindPrevNodeByKey exec.library/AVL_RemNodeByAddress exec.library/AVL_RemNodeByKey exec.library/BeginIO exec.library/CacheClearE exec.library/CacheClearU exec.library/CacheControl exec.library/CachePostDMA exec.library/CachePreDMA exec.library/Cause exec.library/CheckIO exec.library/CloseDevice exec.library/CloseLibrary exec.library/ColdReboot exec.library/CopyMem exec.library/CopyMemQuick exec.library/CreateIORequest exec.library/CreateLibrary exec.library/CreateMsgPort exec.library/CreatePool exec.library/CreatePort exec.library/CreateTask exec.library/debug/AddDebugHook exec.library/debug/Disassemble68k exec.library/debug/DisassembleNative exec.library/debug/GetDebugLevel exec.library/debug/IsIn68kEmulator exec.library/debug/ObtainDebugSymbol exec.library/debug/ReadTaskContext exec.library/debug/ReleaseDebugSymbol exec.library/debug/StackTrace exec.library/debug/WriteTaskContext exec.library/DebugPrintF exec.library/DeleteInterface exec.library/DeleteIORequest exec.library/DeleteLibrary exec.library/DeleteMsgPort exec.library/DeletePool exec.library/DeletePort exec.library/DeleteTask exec.library/DeleteTrackable exec.library/Dellocate exec.library/Disable exec.library/DoIO exec.library/DropInterface exec.library/Emulate exec.library/Enable exec.library/EndDMA exec.library/Enqueue exec.library/FindIName exec.library/FindName exec.library/FindNamedMemory exec.library/FindPort exec.library/FindResident exec.library/FindSemaphore exec.library/FindTask exec.library/FindTrackable exec.library/Forbid exec.library/FreeEntry exec.library/FreeMem exec.library/FreeNamedMemory exec.library/FreePooled exec.library/FreeSignal exec.library/FreeSysObject exec.library/FreeTrap exec.library/FreeVec exec.library/FreeVecPooled exec.library/GetCC exec.library/GetCPUInfo exec.library/GetDMAList exec.library/GetHead exec.library/GetInterface exec.library/GetMsg exec.library/GetPred exec.library/GetSucc exec.library/GetTail exec.library/IceColdReboot exec.library/InitCode exec.library/InitData exec.library/InitResident exec.library/InitSemaphore exec.library/InitStruct exec.library/Insert exec.library/IsNative exec.library/ItemPoolAlloc exec.library/ItemPoolControl exec.library/ItemPoolFlush exec.library/ItemPoolFree exec.library/ItemPoolGC exec.library/LockMem exec.library/LockNamedMemory exec.library/MakeFunctions exec.library/MakeInterface exec.library/MakeLibrary exec.library/MMU/GetMemoryAttrs exec.library/MMU/GetPhysicalAddress exec.library/MMU/MapMemory exec.library/MMU/RemapMemory exec.library/MMU/SetMemoryAttrs exec.library/MMU/UnmapMemory exec.library/MoveList exec.library/MutexAttempt exec.library/MutexAttemptWithSignal exec.library/MutexObtain exec.library/MutexRelease exec.library/Named exec.library/NewList exec.library/NewMinList exec.library/NewStackRun exec.library/ObtainQuickVector exec.library/ObtainSemaphore exec.library/ObtainSemaphoreList exec.library/ObtainSemaphoreShared exec.library/OpenDevice exec.library/OpenLibrary exec.library/OpenResource exec.library/Permit exec.library/Procure exec.library/PutMsg exec.library/RawDoFmt exec.library/ReallocVec exec.library/ReleaseSemaphore exec.library/ReleaseSemaphoreList exec.library/RemDevice exec.library/RemHead exec.library/RemInterface exec.library/RemIntServer exec.library/RemLibrary exec.library/RemMemHandler exec.library/Remove exec.library/RemPort exec.library/RemResetCallback exec.library/RemResource exec.library/RemSemaphore exec.library/RemTail exec.library/RemTask exec.library/RemTrackable exec.library/ReplyMsg exec.library/RestartTask exec.library/RMapAlloc exec.library/RMapExtAlloc exec.library/RMapExtFree exec.library/RMapFree exec.library/ScanNamedMemory exec.library/SendIO exec.library/SetExcept exec.library/SetFunction exec.library/SetIntVector exec.library/SetMethod exec.library/SetSignal exec.library/SetSR exec.library/SetTaskPri exec.library/SetTaskTrap exec.library/Signal exec.library/StackSwap exec.library/StartDMA exec.library/SumInterface exec.library/SumKickData exec.library/SumLibrary exec.library/SuperState exec.library/Supervisor exec.library/SuspendTask exec.library/TypeOfMem exec.library/UnlockMem exec.library/UnlockNamedMemory exec.library/UpdateNamedMemory exec.library/UserState exec.library/Vacate exec.library/Wait exec.library/WaitIO exec.library/WaitPort exec.library/AbortIO exec.library/AbortIO NAME AbortIO - attempt to abort an in-progress I/O request SYNOPSIS AbortIO(iORequest) VOID AbortIO(struct IORequest *); FUNCTION Ask a device to abort a previously started IORequest. This is done by calling the device's ABORTIO vector, with your given IORequest. AbortIO is a command that the device may or may not grant. If successful, the device will stop processing the IORequest, and reply to it earlier than it would otherwise have done. NOTE AbortIO() does NOT Remove() the IORequest from your reply port, OR wait for it to complete. After an AbortIO() you must wait normally for the reply message before actually reusing the request. AbortIO() MUST be followed either by a call to WaitIO() or an equivalent GetMsg() call (see WaitIO() for an example). If a request has already completed when AbortIO() is called, no action is taken. You must not call AbortIO() on an IORequest that has never been successfully used with OpenDevice() and that is not a duplicate of an IORequest which was successfully used with OpenDevice(). If you use it on an IORequest that was just created with CreateIORequest() or which was just used with the CloseDevice() function, you will either cause your task to hang, or you may crash the operating system. INPUTS iORequest - pointer to an I/O request block (must have been used at least once. May be active or finished). EXAMPLE AbortIO(timer_request); WaitIO(timer_request); /* Message is free to be reused */ SEE ALSO WaitIO(), DoIO(), SendIO(), CheckIO() exec.library/AddDevice exec.library/AddDevice NAME AddDevice -- add a device to the system SYNOPSIS AddDevice(device) void AddDevice(struct Device *); FUNCTION This function adds a new device to the system device list, making it available to other programs. The device must be ready to be opened at this time. INPUTS device - pointer to a properly initialized device node SEE ALSO RemDevice, OpenDevice, CloseDevice, MakeLibrary exec.library/AddHead exec.library/AddHead NAME AddHead -- insert node at the head of a list SYNOPSIS AddHead(list, node) void AddHead(struct List *, struct Node *) FUNCTION Add a node to the head of a doubly linked list. WARNING This function does not arbitrate for access to the list. The calling task must be the owner of the involved list. INPUTS list - a pointer to the target list header node - the node to insert at head SEE ALSO AddTail, Enqueue, Insert, Remove, RemHead, RemTail exec.library/AddInterface exec.library/AddInterface NAME AddInterface -- Add an interface to a library (V50) SYNOPSIS AddInterface(library, interface); void AddInterface(struct Library *, struct Interface *); FUNCTION Add the given interface to the library, making it available to other programs. The interface must be fully initialized and ready to be used as soon as it's added. AddInterface will also automatically sum the interface. INPUTS library - Pointer to a library this interface should be added to interface - Pointer to the interface to be added. NOTE This function is a low-level function used by CreateLibrary. Normal applications normally don't need this function. However, it enables programs to dynamically add interfaces to an existing library, thus expanding it's functionality at runtime. SEE ALSO CreateLibrary, RemInterface, MakeInterface exec.library/AddIntServer exec.library/AddIntServer NAME AddIntServer -- add an interrupt server to a system server chain SYNOPSIS success = AddIntServer(intNum, interrupt) BOOL AddIntServer(ULONG, struct Interrupt *); FUNCTION This function adds a new interrupt server to a given server chain. The node is located on the chain in a priority dependent position. If this is the first server on a particular chain, interrupts will be enabled for that chain. Each link in the chain will be called in priority order until the chain ends or one of the servers returns with a non-zero return value. Interrupts number 0 to 15 are "legacy" interrupts, corresponding to the Amiga's original Paula interrupt levels. However, starting in V50, other interrupts might exist. This function can also be used to add global trap handlers. See exec/interrupts.h Starting with V50, the interrupt handler function will look like this: ULONG handler(struct ExceptionContext *Context, struct ExecBase *SysBase, APTR userData); Context is a pointer to the register storage area. Under normal conditions, only volatile register will have been saved, and the appropriate flag will be clear to reflect this. Note, though, that you have to be prepared to handle all cases (if you need access to the interrupted task's registers, anyway). Additionally, userData is the pointer to the user data field taken from the Interrupt's data structure. INPUTS intNum - The interrupt number. interrupt - pointer to an Interrupt structure. By convention, the LN_NAME of the interrupt structure must point a descriptive string so that other users may identify who currently has control of the interrupt. RESULT If the interrupt could be added, a result of TRUE is returned, otherwise, FALSE is returned. FALSE might indicate that the appropriate interrupt does not exist. SEE ALSO RemIntServer, SetIntVector, hardware/intbits.i, exec/interrupts.i exec.library/AddLibrary exec.library/AddLibrary NAME AddLibrary -- add a library to the system SYNOPSIS AddLibrary(library) void AddLibrary(struct Library *); FUNCTION This function adds a new library to the system, making it available to other programs. The library should be ready to be opened at this time. It will be added to the system library name list, and the checksum on the library entries will be calculated. INPUTS library - pointer to a properly initialized library structure SEE ALSO RemLibrary, CloseLibrary, OpenLibrary, MakeLibrary exec.library/AddMemhandler exec.library/AddMemhandler NAME AddMemHandler - Add a low memory handler to exec (V39) SYNOPSIS AddMemHandler(memHandler) VOID AddMemHandler(struct Interrupt *); FUNCTION This function adds a low memory handler to the system. The handler is described in the Interrupt structure. Due to multitasking issues, the handler must be ready to run the moment this function call is made. (The handler may be called before the call returns) INPUTS memHandler - A pointer to a completely filled in Interrupt structure The priority field determine the position of the handler with respect to other handlers in the system. The higher the priority, the earlier the handler is called. Positive priorities will have the handler called before any of the library expunge vectors are called. Negative priority handlers will be called after the library expunge routines are called. (Note: RAMLIB is a handler at priority 0) Upon exit, the handler function should return one of the following values: MEM_DID_NOTHING - The handler didn't do anything. This means the next handler will be invoked, without repeating the failed allocation. MEM_ALL_DONE - The handler is done, and the allocation will be repeated. The next handler will be invoked. MEM_TRY_AGAIN - The handler will be called again. The function's protoype looks like this: LONG Handler(struct ExecBase *, struct MemHandlerData *, APTR); Look below for an example. NOTE Adding a handler from within a handler will cause undefined actions. It is safe to add a handler to the list while within a handler but the newly added handler may or may not be called for the specific failure currently running. EXAMPLE struct Interrupt *myInt; /* Assume it is allocated */ myInt->is_Node.ln_Pri = 50; /* Very early, before RAMLIB */ myInt->is_Node.ln_Name = "Example Handler"; /* Do give it a name ! */ myInt->is_Node.ln_Type = NT_INTERRUPT; myInt->is_Data = (APTR)mydata_pointer; myInt->is_Code = (VOID (*)())myhandler_code; AddMemHandler(myInt); ... /* and so on */ /* Be advised that the is_Node.ln_Type may be changed to either */ /* NT_INTERRUPT or NT_EXTINTERRUPT by the AddMemHandler() call, */ /* based on whether the is_Code field is pointing to native or */ /* legacy 68K code. */ /* * This is the handler code. * We are passed a pointer to ExecBase in r3, * a pointer to a struct MemHandlerData in r4, * the value of is_Data in r5. * We must not break forbid!!! */ LONG myhandler_code(struct ExecBase *ExecBase, struct MemHandlerData *memHandlerData, APTR is_Data UNUSED) { /* Assume we did nothing */ ULONG retval = MEM_DID_NOTHING; if (memHandlerData->memh_RequestFlags & MEMF_CHIP) { /* Do whatever we can do to free chip ram */ retval = MEM_ALL_DONE; } return retval; } SEE ALSO RemMemHandler, exec/interrupts.i exec.library/AddMemList exec.library/AddMemList NAME AddMemList - add memory to the system free pool SYNOPSIS AddMemList( size, attributes, pri, base, name ) void AddMemList(ULONG, ULONG, LONG, APTR, STRPTR); FUNCTION Add a new region of memory to the system free pool. The first few bytes will be used to hold the MemHeader structure. The remainder will be made available to the rest of the world. INPUTS size - the size (in bytes) of the memory area attributes - the attributes word that the memory pool will have pri - the priority for this memory. CHIP memory has a pri of -10, 16 bit expansion memory has a priority of 0. The higher the priority, the closer to the head of the memory list it will be placed. base - the base of the new memory area name - the name that will be used in the memory header, or NULL if no name is to be provided. This name is not copied, so it must remain valid for as long as the memory header is in the system. NOTES *DO NOT* add memory to the system with the attribute of MEMF_KICK. EXEC will mark your memory as such if it is of the right type. SEE ALSO AllocMem, exec/memory.h exec.library/AddPort exec.library/AddPort NAME AddPort -- add a public message port to the system SYNOPSIS AddPort(port) void AddPort(struct MsgPort *); FUNCTION This function attaches a message port structure to the system's public message port list, where it can be found by the FindPort() function. The name and priority fields of the port structure must be initialized prior to calling this function. If the user does not require the priority field, it should be initialized to zero. Only ports that will be searched for with FindPort() need to be added to the system list. In addition, adding ports is often useful during debugging. If the port will be searched for, the priority field should be at least 1 (to avoid the large number of inactive ports at priority zero). If the port will be searched for often, set the priority in the 50-100 range (so it will be before other less used ports). Once a port has been added to the naming list, you must be careful to remove the port from the list (via RemPort) before deallocating its memory. NOTE A point of confusion is that clearing a MsgPort structure to all zeros is not enough to prepare it for use. As mentioned in the Exec chapter of the ROM Kernel Manual, the List for the MsgPort must be initialized. This is automatically handled by AddPort(), and amiga.lib/CreatePort. This initialization can be done manually with amiga.lib/NewList or the assembly NEWLIST macro. Do not AddPort an active port. INPUTS port - pointer to a message port SEE ALSO RemPort, FindPort exec.library/AddResetCallback exec.library/AddResetCallback NAME AddResetCallback -- Add a reset handler to the system (V50) SYNOPSIS BOOL AddResetCallback(struct Interrupt *resetCallback); FUNCTION The given interrupt structure is added to a priority sorted list. Upon calling ColdReboot(), the system will walk through this list in order of priority and invoke each callback. The code pointed to must be native and is called with the following prototype (equal to other invokations of interrupts): uint32 is_Code(struct ExceptionContext *ctx, struct Library * ExecBase, APTR is_Data); Note that in this context, ctx is always 0 (the prototype just reflects the usual way for calling interrupts). The function is always called in user mode (contrary to "normal" interrupt calling) and during a Forbid(). The return value is ignored. INPUTS resetCallback - A fully initialized interrupt structure. Note that insertion into the list is by priority. RESULT If the callback could not be added for some reason, FALSE is returned. Otherwise, the callback is added and TRUE returned. SEE ALSO ColdReboot(), RemResetCallback() exec.library/AddResource exec.library/AddResource NAME AddResource -- add a resource to the system SYNOPSIS AddResource(resource) void AddResource(APTR); FUNCTION This function adds a new resource to the system and makes it available to other users. The resource must be ready to be called at this time. Resources currently have no system-imposed structure, however they must start with a standard named node (LN_SIZE), and should with a standard Library node (LIB_SIZE). INPUTS resource - pointer an initialized resource node SEE ALSO RemResource, OpenResource, MakeLibrary exec.library/AddSemaphore exec.library/AddSemaphore NAME AddSemaphore -- initialize then add a signal semaphore to the system SYNOPSIS AddSemaphore(signalSemaphore) void AddSemaphore(struct SignalSemaphore *); FUNCTION This function attaches a signal semaphore structure to the system's public signal semaphore list. The name and priority fields of the semaphore structure must be initialized prior to calling this function. If you do not want to let others rendezvous with this semaphore, use InitSemaphore() instead. If a semaphore has been added to the naming list, you must be careful to remove the semaphore from the list (via RemSemaphore) before deallocating its memory. Semaphores that are linked together in an allocation list (which ObtainSemaphoreList() would use) may not be added to the system naming list, because the facilities use the link field of the signal semaphore in incompatible ways INPUTS signalSemaphore -- an signal semaphore structure SEE ALSO RemSemaphore, FindSemaphore, InitSemaphore exec.library/AddTail exec.library/AddTail NAME AddTail -- append node to tail of a list SYNOPSIS AddTail(list, node) void AddTail(struct List *, struct Node *); FUNCTION Add a node to the tail of a doubly linked list. Assembly programmers may prefer to use the ADDTAIL macro from "exec/lists.i". WARNING This function does not arbitrate for access to the list. The calling task must be the owner of the involved list. INPUTS list - a pointer to the target list header node - a pointer to the node to insert at tail of the list SEE ALSO AddHead, Enqueue, Insert, Remove, RemHead, RemTail exec.library/AddTask exec.library/AddTask NAME AddTask -- add a task to the system AddTaskTags -- vararg stub (V50) SYNOPSIS task = AddTask(task, initialPC, finalPC, tags) APTR AddTask(struct Task *, APTR, APTR, struct TagItem *); task = AddTaskTags(task, initialPC, finalPC, tag, ...) APTR AddTaskTags(struct Task *, APTR, APTR, ULONG, ...); FUNCTION Add a task to the system. A reschedule will be run; the task with the highest priority in the system will start to execute (this may or may not be the new task). Certain fields of the task control block must be initialized and a stack allocated prior to calling this function. The absolute smallest stack that is allowable is something in the range of 4K bytes, but in general the stack size is dependent on what subsystems are called. In general 4K bytes is sufficient if only Exec is called, and 8K will do if anything in the system is called. DO NOT UNDERESTIMATE. If you use a stack sniffing utility, leave a healthy pad above the minimum value. The system guarantees that its stack operations will leave the stack longword aligned. This function will temporarily use space from the new task's stack for the task's initial set of registers. This space is allocated starting at the SPREG location specified in the task control block (not from SPUPPER). This means that a task's stack may contain static data put there prior to its execution. This is useful for providing initialized global variables or some tasks may want to use this space for passing the task its initial arguments. A task's initial registers are set to zero (except the PC). The TC_MEMENTRY field of the task structure may be extended by the user to hold additional MemLists (as returned by AllocEntry()). These will be automatically be deallocated at RemTask() time. If the code you have used to start the task has already added something to the MEMENTRY list, simply use AddHead to add your new MemLists in. If no initialization has been done, a NewList will need to be performed. As of V50, AddTask will automatically set TF_ETASK. INPUTS task - pointer to the task control block (TCB). All unset fields must be zero. initialPC - the initial entry point's address finalPC - the finalization code entry point's address. If zero, the system will use a general finalizer. This pointer is placed on the stack as if it were the outermost return address. tagList - A list of tag items. Curently, the following is defined: AT_Param(1-8) The tag's value will be passed as the n'th parameter to the new task, accessible through the appropriate ABI registers (for PowerPC, the values are placed into r3-r10). RESULT For V36, AddTask returns either a NULL or the address of the new task. Old code need not check this. WARNING Tasks are a low-level building block, and are unable to call dos.library, or any system function that might call dos.library. See the AmigaDOS CreateProc() for information on Processes. SEE ALSO RemTask, FindTask, dos/CreateProc exec.library/AddTrackable exec.library/AddTrackable NAME AddTrackable -- Add a trackable resource to a task (V50) SYNOPSIS trackable = AddTrackable(task, object, destFn); struct Trackable *AddTrackable(struct Task *, APTR, struct Hook *); FUNCTION AddTrackable adds a trackable object to a task. The object is stored within the task context and can be automatically destroyed when the task is removed. The destructor hook is called with the Trackable as object and a copy of the exec main interface will be passed as message pointer. INPUTS task - The task that will track this object. Passing 0 will use the current task. object - The object to track. It's safe to pass 0, but doing so will not create a trackable. destFn - A hook that will be called to destroy the object. The hook will be copied into the Trackable. RESULT A pointer to the newly created structure is returned, and the structure is stored in the task context. NOTES This function is manly used internally by the system, and is probably of no use for application programmers. SEE ALSO FindTrackable, RemTrackable, DeleteTrackable, AllocSysObject exec.library/Alert exec.library/Alert NAME Alert -- Alert the user of an error SYNOPSIS void Alert(uint32 alertNum) FUNCTION Alerts the user of a serious system problem. This function will bring the system to a grinding halt, and do whatever is necessary to present the user with a message stating what happened. Interrupts are disabled, and an attempt to post the alert is made. If that fails, the system is reset. When the system comes up again, Exec notices the cause of the failure and tries again to post the alert. If the Alert is a recoverable type, this call MAY return. This call may be made at any time, including interrupts. (Well, only in interrupts if it is non-recoverable) New, for V39: The alert now times out based on the value in LastAlert[3] This value is transfered across warm-reboots and thus will let you set it once. The value is the number of frames that need to be displayed before the alert is auto-answered. A value of 0 will thus make the alert never be displayed. Note that it is recommended that applications *NOT* change the value in LastAlert[] since the main reason for this is to make unattended operation of the Amiga (in production enviroments) possible. POST-MORTEM DIAGNOSIS There are several options for determining the cause of a crash. Descriptions of each alert number can be found in the "alerts.h" include file. A remote terminal can be attached to the Amiga's first built-in serial port. Set the communication parameters to 9600 baud, 8 bits, no parity. Before resetting the machine, the Alert function will blink the power LED 10 times. While the power indicator is flashing, pressing DELETE on the remote terminal will invoke the ROM debugger. INPUT alertNum - a number indicating the particular alert. -1 is not a valid input. NOTE Much more needs to be said about this function and its implications. SEE ALSO exec/alerts.h exec.library/AllocAbs exec.library/AllocAbs NAME AllocAbs -- allocate at a given location SYNOPSIS memoryBlock = AllocAbs(byteSize, location) void *AllocAbs(ULONG, APTR); FUNCTION This function attempts to allocate memory at a given absolute memory location. Often this is used by boot-surviving entities such as recoverable ram-disks. If the memory is already being used, or if there is not enough memory to satisfy the request, AllocAbs will return NULL. This block may not be exactly the same as the requested block because of rounding, but if the return value is non-zero, the block is guaranteed to contain the requested range. INPUTS byteSize - the size of the desired block in bytes This number is rounded up to the next larger block size for the actual allocation. location - the address where the memory MUST be. RESULT memoryBlock - a pointer to the newly allocated memory block, or NULL if failed. NOTE If the free list is corrupt, the system will panic with alert AN_MemCorrupt, $01000005. The 8 bytes past the end of an AllocAbs will be changed by Exec relinking the next block of memory. Generally you can't trust the first 8 bytes of anything you AllocAbs. SEE ALSO AllocMem, FreeMem exec.library/Allocate exec.library/Allocate NAME Allocate - allocate a block of memory SYNOPSIS memoryBlock=Allocate(memHeader, byteSize) void *Allocate(struct MemHeader *, ULONG); FUNCTION This function is used to allocate blocks of memory from a given private free memory pool (as specified by a MemHeader and its memory chunk list). Allocate will return the first free block that is greater than or equal to the requested size. All blocks, whether free or allocated, will be block aligned; hence, all allocation sizes are rounded up to the next block even value (e.g. the minimum allocation resolution is currently 8 bytes. A request for 8 bytes will use up exactly 8 bytes. A request for 7 bytes will also use up exactly 8 bytes.). This function can be used to manage an application's internal data memory. Note that no arbitration of the MemHeader and associated free chunk list is done. You must be the owner before calling Allocate. INPUTS memHeader - points to the local memory list header. byteSize - the size of the desired block in bytes. RESULT memoryBlock - a pointer to the just allocated free block. If there are no free regions large enough to satisfy the request, return zero. EXAMPLE #include #include void *AllocMem(); #define BLOCKSIZE 4096L /* Or whatever you want */ void main() { struct MemHeader *mh; struct MemChunk *mc; APTR block1; APTR block2; /* Get the MemHeader needed to keep track of our new block */ mh = (struct MemHeader *) AllocMem((long)sizeof(struct MemHeader), MEMF_CLEAR ); if( !mh ) exit(10); /* Get the actual block the above MemHeader will manage */ mc = (struct MemChunk *)AllocMem( BLOCKSIZE, 0L ); if( !mc ) { FreeMem( mh, (long)sizeof(struct MemHeader) ); exit(10); } mh->mh_Node.ln_Type = NT_MEMORY; mh->mh_Node.ln_Name = "myname"; mh->mh_First = mc; mh->mh_Lower = (APTR) mc; mh->mh_Upper = (APTR) ( BLOCKSIZE + (ULONG) mc ); mh->mh_Free = BLOCKSIZE; /* Set up first chunk in the freelist */ mc->mc_Next = NULL; mc->mc_Bytes = BLOCKSIZE; block1 = (APTR) Allocate( mh, 20L ); block2 = (APTR) Allocate( mh, 314L ); printf("mh=$%lx mc=$%lx\n",mh,mc); printf("Block1=$%lx, Block2=$%lx\n",block1,block2); FreeMem( mh, (long)sizeof(struct MemHeader) ); FreeMem( mc, BLOCKSIZE ); } NOTE If the free list is corrupt, the system will panic with alert AN_MemCorrupt, $01000005. SEE ALSO Deallocate, exec/memory.h exec.library/AllocEntry exec.library/AllocEntry NAME AllocEntry -- Allocate many regions of memory. (-DEPRECATED-) -- Use AllocTaskMemEntry() from V51+ SYNOPSIS struct MemList *memList = AllocEntry(struct memList *memList); FUNCTION This function takes a memList structure and allocates enough memory to hold the required memory as well as a MemList structure to keep track of it. These MemList structures may be linked together in a task control block to keep track of the total memory usage of this task. (See the description of TC_MEMENTRY under RemTask). INPUTS memList -- A MemList structure filled in with MemEntry structures. RESULTS memList -- A different MemList filled in with the actual memory allocated in the me_Addr field, and their sizes in me_Length. If enough memory cannot be obtained, then the requirements of the allocation that failed is returned and bit 31 is set. WARNING: The result is unusual! Bit 31 indicates failure. NOTES This function is deprecated because it breaks on address spaces past the first 2gig boundary. Use AllocTaskMemEntry() from V51+ SEE ALSO FreeEntry, exec/memory.h exec.library/AllocMem exec.library/AllocMem NAME AllocMem -- allocate memory given certain requirements SYNOPSIS memoryBlock = AllocMem(byteSize, attributes) void *AllocMem(ULONG, ULONG); FUNCTION This is the memory allocator to be used by system code and applications. It provides a means of specifying that the allocation should be made in a memory area accessible to the chips, or accessible to shared system code. Memory is allocated based on requirements and options. Any "requirement" must be met by a memory allocation, any "option" will be applied to the block regardless. AllocMem will try all memory spaces until one is found with the proper requirements and room for the memory request. INPUTS byteSize - the size of the desired block in bytes. (The operating system will automatically round this number to a multiple of the system memory chunk size) attributes - requirements If no flags are set, the system will return the best available memory block. For expanded systems, the fast memory pool is searched first. MEMF_ANY: Any memory that is available should be used. MEMF_CHIP: If the requested memory will be used by the classic Amiga custom chips, this flag *must* be set. Only certain parts of memory are reachable by the special chip sets' DMA circuitry. Chip DMA includes screen memory, images that are blitted, audio data, copper lists, sprites and Pre-V36 trackdisk.device buffers. This flag is obsolete and interpreted as MEMF_SHARED in exec.library 51.34 or higher when not running on a classic machine. MEMF_FAST: This is non-chip memory. If no flag is set MEMF_FAST is taken as the default. DO NOT SPECIFY MEMF_FAST unless you know exactly what you are doing! If MEMF_FAST is set, AllocMem() will fail on machines that only have chip memory! This flag may not be set when MEMF_CHIP is set. This flag is obsolete and interpreted as MEMF_SHARED in exec.library 51.34 or higher. MEMF_EXECUTABLE:This memory will have execute permission, i.e. code loaded into this memory can be jumped to. Note that this basically defines a new memory "type" (like MEMF_CHIP, MEMF_FAST). Executable memory might be virtual (i.e. phyiscal and visible addresses might differ), but is never swapped. Note: - All other memory does *NOT* have execute permission. - Execute permission is only necessary for native code. - Code that might be shared between several tasks has to be allocated with MEMF_SHARED. ALLOCATING MEMF_EXECUTABLE MIGHT BREAK A FORBID. MEMF_PUBLIC: Memory that is not protected, i.e. is freely accessible by anyone. This includes IPC related data structures, like Messages, MessagePorts, etc. This memory will never be swapped out, or otherwise made non-addressable. It will also be guaranteed that memory allocated as MEMF_PUBLIC will have equal physical and virtual addresses. ALL MEMORY THAT IS REFERENCED VIA INTERRUPTS MUST BE PUBLIC. MEMF_PUBLIC is a stronger form of MEMF_SHARED: MEMF_SHARED is automatically implied with MEMF_PUBLIC. MEMF_SHARED: Memory of this type is shareable between tasks. This means that different tasks can access it. MEMF_PRIVATE: Accesses from other tasks than the allocating tasks are not allowed. The OS may protect this memory against these accesses. MEMF_LOCAL: This is memory that will not go away after the CPU RESET instruction. Normally, autoconfig memory boards become unavailable after RESET while motherboard memory may still be available. This flag is obsolete and ignored in exec.library 51.34 or higher. MEMF_24BITDMA: This is memory that is within the address range of 24-bit DMA devices. (Zorro-II) This is required if you run a Zorro-II DMA device on a machine that has memory beyond the 24-bit addressing limit of Zorro-II. This flag is obsolete and ignored in exec.library 51.34 or higher. MEMF_KICK: This memory is memory that EXEC was able to access during/before the KickMem and KickTags are processed. This means that if you wish to use these, you should allocate memory with this flag. Also, *DO NOT* ever add memory the system with this flag set. EXEC will set the flag as needed if the memory matches the needs of EXEC. This flag is obsolete and ignored in exec.library 51.34 or higher. options MEMF_CLEAR: The memory will be initialized to all zeros. MEMF_REVERSE: This allocates memory from the top of the memory pool. It searches the pools in the same order, such that FAST memory will be found first. However, the memory will be allocated from the highest address available in the pool. This option is new as of V36. Note that this option has a bug in pre-V39 systems. This flag is obsolete and ignored in exec.library 51.34 or higher, except when running on a classic machine and MEMF_CHIP was set also. MEMF_NO_EXPUNGE This will prevent an expunge to happen on a failed memory allocation. This option is new to V39 and will be ignored in V37. If a memory allocation with this flag set fails, the allocator will not cause any expunge operations. (See AddMemHandler()) MEMF_HWALIGNED: To be able to set the attributes of a certain memory area, giving this flag to AllocMem will enforce a certain alignment of the memory. Normally, this means that the returned block will be the only memory in a hardware page. The size of this page depends on the CPU. You should not assume any alignemnt yourself. Note: This flag might allocate much more memory than you actually request. Don't use it without reason. RESULT memoryBlock - a pointer to the newly allocated memory block. If there are no free memory regions large enough to satisfy the request, zero will be returned. The pointer must be checked for zero before the memory block may be used! The memory block returned is long word aligned. By default, the memory block is set to MEMATTRF_SUPER_RW_USER_RW. If the memory is allocated with MEMF_CHIP, it's additionally MEMATTRF_CACHEINHIBIT. WARNING The result of any memory allocation MUST be checked, and a viable error handling path taken. ANY allocation may fail if memory has been filled. EXAMPLES AllocMem(64,0L) - Allocate the best available memory AllocMem(25,MEMF_CLEAR) - Allocate the best available memory, and clear it before returning. AllocMem(128,MEMF_CHIP) - Allocate chip memory AllocMem(128,MEMF_CHIP|MEMF_CLEAR) - Allocate cleared chip memory AllocMem(821,MEMF_CHIP|MEMF_PUBLIC|MEMF_CLEAR) - Allocate cleared, public, chip memory. NOTE If the free list is corrupt, the system will panic with alert AN_MemCorrupt, $01000005. This function may not be called from interrupts. A DOS process will have its pr_Result2 field set to ERROR_NO_FREE_STORE if the memory allocation fails. This function is obsolete, use AllocVecTagList SEE ALSO FreeMem, AllocVecTagList exec.library/AllocNamedMemory exec.library/AllocNamedMemory NAME AllocNamedMemory -- Allocate a named memory object (V51) SYNOPSIS void *AllocNamedMemory(uint32 byteSize, STRPTR space, STRPTR name, struct TagItem *tagList); void *AllocNamedMemoryTags(uint32 byteSize, STRPTR space, STRPTR name, uint32 tag1, ...); FUNCTION AllocNamedMemory tries to allocate a block of memory of the given size with a type of memType. When successfull, the block is returned and will be available to others under the given name. If the name space does not exist, it is automatically created if the allocation succeeds. INPUTS byteSize - size of the block in bytes. Note that the system can adjust this value to a large number, depending on alignment or other constraints. space - The name space for this named memory block. If NULL, a global namespace is assumed. name - The name for the memory block. The name is copied and need not remain valid after the call. Note that the name must be unique in the scope it's created in. tagList - Pointer to a list of tags. Currently, the following tags are defined: ANMT_CheckSum (BOOL) For resident memory, compute and store a checksum with the block. On reboot, the checksum is recomputed and if it differs, the block will be discarded. Without this flag, validation of resident memory must be carried out by the application. Default: TRUE if the namespace is "resident", FALSE otherwise ANMT_Error (uint32 *) Allocation can fail not only due to memory shortage, but also because a block with the given name might already exist. If you pass a pointer along via this tag, an error code will be placed into this location. RESULT A pointer to a new memory block is returned, or NULL if there was an error. Note that this points directly to the memory, and is NOT a handle of some sort. An error can be generated when there's not enough memory, or when a block with the same name already exists in the name space. If ANMT_Error points to a variable, the error code will be placed into this variable. Possible values are: ANMERROR_NOERROR No error, operation successful. Note that success is also indicated by a non-NULL return value. ANMERROR_NOMEMORY Insufficient memory available ANMERROR_DUPLICATENAME A block of that name already exists in the given namespace. ANMERROR_PARAMETER A parameter was missing or wrong EXAMPLE void *block = IExec->AllocNamedMemory(100, "myapp", "some_mem", NULL); ... void *some_mem = IExec->FindNamedMemory("myapp", "some_mem"); ... IExec->FreeNamedMemory("myapp", "some_mem"); NOTES Memory allocated via AllocNamedMemory must NEVER be freed with any other function but FreeNamedMemory (i.e. don't pass the block to FreeMem or FreeVec). SEE ALSO FreeNamedMemory, FindNamedMemory, UpdateNamedMemory exec.library/AllocPooled exec.library/AllocPooled NAME AllocPooled -- Allocate memory with the pool manager (V39) SYNOPSIS memory = AllocPooled(poolHeader,memSize) void *AllocPooled(void *,ULONG); FUNCTION Allocate memSize bytes of memory, and return a pointer. NULL is returned if the allocation fails. Doing a DeletePool() on the pool will free all of the puddles and thus all of the allocations done with AllocPooled() in that pool. (No need to FreePooled() each allocation) INPUTS memSize - the number of bytes to allocate poolHeader - a specific private pool header. RESULT A pointer to the memory, or NULL. The memory block returned is long word aligned. NOTES The pool function do not protect an individual pool from multiple accesses. The reason is that in most cases the pools will be used by a single task. If your pool is going to be used by more than one task you must Semaphore protect the pool from having more than one task trying to allocate within the same pool at the same time. Warning: Forbid() protection *will not work* in the future. *Do NOT* assume that we will be able to make it work in the future. AllocPooled() may well break a Forbid() and as such can only be protected by a semaphore. SEE ALSO FreePooled(), CreatePool(), DeletePool(), FreeVecPooled(), AllocVecPooled() exec.library/AllocSignal exec.library/AllocSignal NAME AllocSignal -- allocate a signal bit SYNOPSIS signalNum = AllocSignal(signalNum) BYTE AllocSignal(BYTE); FUNCTION Allocate a signal bit from the current tasks' pool. Either a particular bit, or the next free bit may be allocated. The signal associated with the bit will be properly initialized (cleared). At least 16 user signals are available per task. Signals should be deallocated before the task exits. If the signal is already in use (or no free signals are available) a -1 is returned. Allocated signals are only valid for use with the task that allocated them. WARNING Signals may not be allocated or freed from exception handling code. INPUTS signalNum - the desired signal number {of 0..31} or -1 for no preference. RESULT signalNum - the signal bit number allocated {0..31}. If no signals are available, this function returns -1. SEE ALSO FreeSignal exec.library/AllocSysObject exec.library/AllocSysObject NAME AllocSysObject - Create a system object (V50) SYNOPSIS ptr = AllocSysObject(type, tags); APTR AllocSysObject(ULONG, struct TagItem *); ptr = AllocSysObjectTags(type, Tag1, ...); APTR AllocSysObjectTags(ULONG, Tag, ...); FUNCTION This function creates a system object, initializes it, and returns a pointer to it. The objects created by this function can be tracked by the system, and automatically deleted when the task ends. Additional information will be passed through tag items. The actual tag items depend on the type of the object to be created. This function should always be used to create system objects. The "old" method of just using a static struct, or just allocating memory via AllocMem is discouraged. Most objects also offer the possibility of initialization. INPUTS type - type of object to be created (see exec/exectags.h for a list) tags - pointer to a taglist with additional information Currently supported are: ASO_NoTrack A boolean value that indicates whether the object should be tracked or not. This might be useful for stuff that is dangrous to get rid of automatically, like semaphores. Also, tracking has a slight additional memory overhead. Default: TRUE (i.e do not track) ASO_MemoryOvr Specify memory type for the allocation. Normally, each object's constructing function "knows" what memory type to choose. However, there might be reasons to change that. DO NOT USE THIS TAG. It's normally not needed, and should only be used if absolutely necessary. Note: It's generally dangerous to request MEMF_PRIVATE for system objects. Various objects might also require/allow additional tag items. See the AutoDoc of the appropriate types to find out about the supported tags for different objects. Most objects offer a size tag. By default, all of these tags have sensible default value, i.e. a ASOHOOK_Size is by default sizeof(struct Hook). You can, however, override these sizes, if you want to add additional data in the structure (you could allocate the Data pointer of a hook directly after the structure itself). RESULT A pointer to the newly created (and possibly initialized) object, or NULL if the object could not be created. EXAMPLE /* * Creating an empty list of fonts. * The list is initialized (similar to the NEWLIST macro). */ struct List *newList; newList = (struct List *)IExec->AllocSysObjectTags(ASOT_LIST, ASOLIST_Type, NT_FONT, TAG_DONE); if (NULL != newList) { /* The list is now ready to take up nodes... */ IExec->AddHead(newList, fontNode); ... } /* * Free the list again * Warning: Make sure it's empty. This is not handled by FreeSysObject! */ IExec->FreeSysObject(ASOT_LIST, (APTR)newList); NOTES ALWAYS FREE YOUR RESOURCES!! Even though the resources will be tracked and deleted, this is *only* a method to get rid of the program's resources when the program crashes or exits unexpectedly. DO NOT RELY ON THIS MECHANISM. It's for emergency cases only. SEE ALSO FreeSysObject(), exec.library/AllocTaskMemEntry exec.library/AllocTaskMemEntry NAME AllocTaskMemEntry -- Allocates memory for the task memlist. (V51) SYNOPSIS struct MemList *memList = AllocTaskMemEntry( struct MemList *memList); FUNCTION This function takes a memList structure and allocates enough memory to hold the required memory as well as a MemList structure to keep track of it. These MemList structures may be linked together in a task control block to keep track of the total memory usage of this task. (See the description of TC_MEMENTRY under RemTask). INPUTS memList -- A MemList structure filled in with MemEntry structures. RESULTS memList -- A different MemList filled in with the actual memory allocated in the me_Addr field, and their sizes in me_Length. If enough memory cannot be obtained, then NULL is returned. NOTES This is a V51 replacement for the old AllocEntry() function which had an unusual return value upon failure and would also break on address space >2gig. Applications should free all their task memlist allocations with FreeEntry() before the program exits. EXAMPLE Add a single memory allocation to the current tasks memlist. APTR addTaskMemEntry( uint32 memsize, uint32 memtype ) { struct Task *me = IExec->FindTask(0); struct MemList ML; struct MemList *mlist; APTR result = NULL; /* default return for failure */ ML.ml_NumEntries = 1; ML.ml_ME[0].me_Un.meu_Reqs = memtype; ML.ml_ME[0].me_Length = memsize; if(( mlist = IExec->AllocTaskMemEntry(&ML) )) { /* Adds the memory block to the current tasks memlist */ IExec->AddHead( &(me->tc_MemEntry), (struct Node *)mlist); result = mlist->ml_ME[0].me_Un.meu_Addr; } return(result); /* return the memory block, or NULL on failure */ } SEE ALSO FreeEntry(), exec/memory.h exec.library/AllocTrap exec.library/AllocTrap NAME AllocTrap -- allocate a processor trap vector (Obsolete) SYNOPSIS trapNum = AllocTrap(trapNum) LONG AllocTrap(LONG); FUNCTION Allocate a trap number from the current task's pool. These trap numbers are those associated with the 68000 TRAP type instructions. Either a particular number, or the next free number may be allocated. If the trap is already in use (or no free traps are available) a -1 is returned. This function only affects the currently running task. Traps are sent to the trap handler pointed at by tc_TrapCode. Unless changed by user code, this points to a standard trap handler. The stack frame of the exception handler will be: 0(SP) = Exception vector number. This will be in the range of 32 to 47 (corresponding to the Trap #1...Trap #15 instructions). 4(SP) = 68000/68010/68020/68030, etc. exception frame tc_TrapData is not used. WARNING Traps may not be allocated or freed from exception handling code. You are not allowed to write to the exception table yourself. In fact, on some machines you will have trouble finding it - the VBR register may be used to remap its location. INPUTS trapNum - the desired trap number {of 0..15} or -1 for no preference. RESULTS trapNum - the trap number allocated {of 0..15}. If no traps are available, this function returns -1. Instructions of the form "Trap #trapNum" will be sent to the task's trap handler. NOTES This function is obsolete from V50 upwards. SEE ALSO FreeTrap exec.library/AllocVec exec.library/AllocVec NAME AllocVec -- allocate memory and keep track of the size (V36) SYNOPSIS memoryBlock = AllocVec(byteSize, attributes) void *AllocVec(ULONG, ULONG); FUNCTION This function works identically to AllocMem(), but tracks the size of the allocation. See the AllocMem() documentation for details. WARNING The result of any memory allocation MUST be checked, and a viable error handling path taken. ANY allocation may fail if memory has been filled. NOTE This function is obsolete, use AllocVecTagList SEE ALSO FreeVec, AllocMem, AllocVecTagList exec.library/AllocVecPooled exec.library/AllocVecPooled NAME AllocVecPooled -- Allocate memory with the pool manager and track size (V50) SYNOPSIS memory=AllocVecPooled(poolHeader,memSize) void *AllocVecPooled(void *,ULONG); FUNCTION This function works exactly like AllocPooled, but tracks the size of the allocation. Note that when using AllocVecPooled, the tracking information counts towards the threshold size, which may result in an allocation to exceed the threshold size. Currently, up to 8 bytes are used. INPUTS memSize - the number of bytes to allocate poolHeader - a specific private pool header. RESULT A pointer to the memory, or NULL. The memory block returned is long word aligned. NOTES The pool functions do not protect an individual pool from multiple accesses. The reason is that in most cases the pools will be used by a single task. If your pool is going to be used by more than one task you must Semaphore protect the pool from having more than one task trying to allocate within the same pool at the same time. Warning: Forbid() protection *will not work* in the future. *Do NOT* assume that we will be able to make it work in the future. AllocPooled() may well break a Forbid() and as such can only be protected by a semaphore. SEE ALSO FreePooled(), CreatePool(), DeletePool(), FreeVecPooled(), AllocPooled() exec.library/AllocVecTags exec.library/AllocVecTags NAME AllocVecTagList -- Allocate memory (V51) SYNOPSIS void *AllocVecTagList(uint32 size, struct TagItem *tags); void *AllocVecTags(uint32 size, uint32 tag1, ...); FUNCTION AllocVecTagList is the main entry point for allocating memory directly from the system's global memory pool. In it's simplest form, AllocVecTagList will give you a private memory block of at least size bytes. In addition, further constraints can be given, for example alignemnt of the memory block. It's also possible to have the newly allocated block cleared to a certain value. Memory obtained through this function must be returned to the system via the FreeVec function. Note: In contrast to earlier memory allocation functions, calling this function might cause a Forbid/Permit lock to break, regardless of the type of memory allocated. See AVT_Wait for more information. INPUTS size - The minimal byte size of the block to be allocated. The system will return a block that is at least size bytes. The system might however make the block larger to cope with constraints or availability of memory. tags - A list of tag items defining further constraints or additional operations to be carried out on the memory block before returning control back to the caller. Currently, the following tags are defined (the information in brackets refers to the data type of the tag item, as well as it's default value): AVT_Type (uint32, MEMF_PRIVATE) Allocate memory from the indicated heap. The following types are allowed: MEMF_PRIVATE: Allocate from the private heap. This memory will not be visible to any other address space MEMF_SHARED: Allocate from the shared heap. This memory can be shared between all address spaces, and will alwyays appear at the same address in any address space. MEMF_EXECUTABLE: Allocate memory that is marked executable. Note: No other value, or combination of value is allowed. specifying an invalid value will result in failure. AVT_Contiguous (BOOL, FALSE) Memory allocated with this property is allocated from a contiguous block of physical memory. This makes the memory suitable for DMA purposes when the DMA device does not support scatter/gather operation. Note: Physical pages can move at any time, be removed from memory due to paging, or otherwise made unavailable, unless the memory pages are locked (see LockMemory, or AVT_Lock). Also note that allocating contiguous memory is really only necessary for DMA drivers. Do not use otherwise. AVT_Lock (BOOL, FALSE or TRUE) After allocating memory, lock the associated pages in memory. This will prevent the pages from being moved, swapped out or otherwise being made unavailable. This is useful in conjunction with the AVT_Contiguous tag, since it will ensure that the memory will stay continous after allocation. This tag defaults to FALSE for MEMF_PRIVATE allocations, and to TRUE for anything else. AVT_Alignment (uint32, 16) Define an alignment constraint for the allocated memory block. The returned memory block will be aligned to the given size (in bytes) i.e. it's virtual address will be at least a multiple of the AVT_Alignment value. Note: Alignment values must be powers of two. Executable memory is always aligned to the current page size AVT_PhysicalAlignment (uint32, 16) Define an alignment constraint for the allocated memory block physical address. See AVT_Alignment for more information. Note: This functionality is mainly used for DMA drivers that require a specific alignment. In general, you don't need this. Alignment values must be powers of two. Executable memory is always aligned to the current page size AVT_ClearWithValue (uint8, no default) Clear the newly allocated memory with the given value. If this tag isn't given, the memory block is not cleared. Note: This is _NOT_ a boolean tag, and not equivalent to MEMF_CLEAR in AllocVec. AVT_Wait (BOOL, TRUE) Wait for the memory subsystem to be available. If TRUE, the calling task will be retired until the memory subsystem is available. This might cause a Forbid to break. When FALSE, and the memory subsystem is not currently available, the function will return immediately and the allocation will fail. AVT_NoExpunge (BOOL, FALSE) If allocation fails because of unavailability, prevent invokation of cleanup handlers. The default is FALSE, which means that when memory is not available, cleanup handlers are invoked. RESULT A pointer to the newly allocated memory block is returned, or 0 if unsufficient resources are available. EXAMPLE /* Allocate a block of shared memory wich is 16 bytes aligned, * suitable for AltiVec data. */ void *ptr = IExec->AllocVecTags(16*NUM_VECTORS, AVT_Type, MEMF_SHARED, AVT_Alignment, 16, TAG_DONE); SEE ALSO FreeVec exec.library/ASOT_DMAENTRY exec.library/ASOT_DMAENTRY NAME ASOT_DMAENTRY -- DMAEntry array TAGS ASODMAE_Size Raw size of the array, i.e. the size of the complete array, _NOT_ one element. Default: 0 ASODMAE_NumEntries Number of entries to allocate. For this type of object, it's more convenient to use this tag instead of ASODMAE_Size. Note that this tag is mutually exlusive with ASODMAE_Size. Default: 0 NOTES Memory for this object is allocated as MEMF_PRIVATE, as it's scope is usually only the device. exec.library/ASOT_EXTMEM 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. exec.library/ASOT_HOOK exec.library/ASOT_HOOK NAME ASOT_HOOK -- Hook TAGS ASOHOOK_Size Size of the structure to be allocated. Default: sizeof(struct Hook). ASOHOOK_Entry Address to put into the Hook's entry. Default: see notes. ASOHOOK_Subentry Address to put into the Hook's sub entry. Default: see notes. ASOHOOK_Data Address to put into the Hook's user data field. Default: 0xffffffff NOTES Memory for this object is allocated as MEMF_SHARED. The entry and subentry fields of the hook are by default set to a dummy function. This function generates an alert AN_BadHook when called, indicating that you forgot to initialize the hook properly. exec.library/ASOT_INTERRUPT exec.library/ASOT_INTERRUPT NAME ASOT_INTERRUPT -- Interrupt TAGS ASOINTR_Size Size of the object. Default: sizeof(struct Interrupt). ASOINTR_Code Interrupt code. Default: 0 ASOINTR_Data Interrupt data. Default: 0 ASOINTR_SoftInt Interrupt is used as a software interrupt triggered by Cause(). This affects the node's type field, setting it to NT_UNKNOWN instead of NT_INTERRUPT Default: FALSE NOTES Memory for this object is allocated as MEMF_PUBLIC. Interrupts _MUST_ be allocated MEMF_PUBLIC. exec.library/ASOT_IOREQUEST exec.library/ASOT_IOREQUEST NAME ASOT_IOREQUEST -- IORequest TAGS ASOIOR_Size Size of the IO request to be created Default: sizeof(struct IORequest). ASOIOR_ReplyPort Preinitialized ReplyPort. Default: None, mandatory if no ASOIOR_Duplicate. ASOIOR_Duplicate Duplicate the given IO request. A new request is allocated and a copy is created. ASOIOR_Size and ASOIOR_ReplyPort can be used to override the fields from this request. Default: None NOTES Memory for this object is allocated as MEMF_SHARED. If the request is to be used from an interrupt, override it to MEMF_PUBLIC. exec.library/ASOT_ITEMPOOL exec.library/ASOT_ITEMPOOL NAME ASOT_ITEMPOOL TAGS ASOITEM_MFlags Memory flags for the allocation. Defaults to MEMF_ANY. See NOTES. ASOITEM_ItemSize Size of an individual item. Note that the system might enlarge the item size for better alignment or other purposes, so don't assume that slabs are adjacent to each other. This tag is mandatory. Minimum size is 8 bytes. ASOITEM_BatchSize Number of items to allocate when there are no items left in the pool. Note that the system might choose a bigger (or lower) number. Default is undefined and selected by the system. ASOITEM_MaxSize The maximum number of items ever to be allocated through this pool. The number must be a multiple of the ASOITEM_BatchSize.Trying to allocate more will result in failure. Default is 0, meaning no upper limit. ASOITEM_GCPolicy Set the policy of garbage collection. The following policies are defined: ITEMGC_AFTERCOUNT - start garbage collection after a number of items have been de- allocated. The number of operations can be adjusted using ASOITEM_GCParameter. The default number of operations is the value of ASOITEM_GCParameter. ITEMGC_NONE - never do garbage colection but rely on the user calling ItemPoolGC() Default is ITEMGC_NONE ASOITEM_GCParameter A parameter for the garbage policy. Default is 100. ASOITEM_Protected Protect the pool access by a semaphore. The semaphore will be created automatically and is automatically handled by the functions accessing the pool. You do not need to lock the semaphore yourself. Default: FALSE ASOITEM_Constructor A pointer to a struct Hook to be invoked when an item is allocated. The hook is called with a pointer to the memory allocated as object pointer. The message contains the long word ASOITEM_Constructor (to allow you to use the same hook for ASOITEM_Destructor too) Your hook is supposed to return non-null to indicate that the construction succeeded, or null otherwise. Default is NULL (no constructor). ASOITEM_Destructor A pointer to a struct Hook to be inoked when an item is deallocated. The same rules apply as with the constructor (only that message contains ASOITEM_Destructor) Default is NULL (no destructor). BACKGROUND Many applications frequently allocate very similar pieces of memory, like list nodes, rectangles, or similar structures. If these items are sufficiently large, their constant allocation and deallocation will produce a potentially large amount of fragmented memory nodes. An Item Pool is a special memory pool that can only allocate and de- allocate predefined slabs of memory. Every allocation from this pool is exactly ASOITEM_ItemSize bytes (possibly rounded up) large. There are no exceptions to this rule. Allocation and deallocating of these items is typically extremely fast (unless the pool needs to be enlarged or garbage collection takes place). The pool is created with an inital number of item storage space, and automatically extends when space runs out, unless the maximum number of allocations is reached (settable using ASOITEM_MaxSize). If set to non-NULL values, the constructor and destructor hooks are called with the newly allocated item or an item to be deallocated. If the MEMF_CLEAR bit was set in the memory flags, the memory is cleared *before* the actual hook is invoked. An item pool should be used whenever an application wants to allocate a large number of equally sized object. For example, an application allocating a couple thousand of Rectangle structures, or list items, could use an item pool for that to dramatically reduce the allocation time AND memory fragmentation. Item pools are commonly called 'slab allocators', although the latter usually also refers to a kind of allocation that leaves data intact between calls. Similar to old exec memory pools, all memory allocated in the item pool is delete as soon as the item pool itself is freed (via a call to FreeSysObject). NOTES You must not make any assumption about the contents of a newly created item (other than having it cleared when MEMF_CLEAR is specified). Most notably, the content of an item may change when it is re-allocated. Items are not necessarily packed closely together. The system may adjust the item size for better cache coherency or other factors. Setting MEMF_CLEAR in the memory flags will result in clearing each allocated item (prior to calling any defined constructor hook) so it might introduce a certain overhead. SEE ALSO ItemPoolAlloc(), ItemPoolFree(), ItemPoolControl(), ItemPoolFlush(), ItemPoolGC() exec.library/ASOT_LIST exec.library/ASOT_LIST NAME ASOT_LIST -- Exec List TAGS ASOLIST_Size Size of the object. Default: sizeof(struct List), or sizeof(struct MinList), depending on ASOLIST_Min ASOLIST_Type The new list's type. Default: NT_UNKNOWN ASOLIST_Min Make it a MinList. Default: FALSE NOTES Memory for this object is allocated as MEMF_SHARED. The list is also initialized to an empty list. exec.library/ASOT_MEMPOOL exec.library/ASOT_MEMPOOL NAME ASOT_MEMPOOL -- Exec MemoryPool TAGS ASOPOOL_MFlags Memory flags for allocation from this pool Default: MEMF_ANY ASOPOOL_Puddle Puddle size Default: See below ASOPOOL_Threshold Threshold size Default: See below ASOPOOL_Protected Protect the pool with a semaphore on each access. Default: FALSE ASOPOOL_Name Name for the pool. This is used for informational purposes only. Default: NULL ASOPOOL_CopyName Make a copy of the name string. Default: FALSE ASOPOOL_LockMem Automatically lock memory allocated from this pool. Default: TRUE for MEMF_SHARED, FALSE for MEMF_PRIVATE NOTES Memory for this object is allocated with MEMF_PRIVATE. Additionally, MEMF_ANY will be converted to MEMF_VIRTUAL. Puddle and threshold size: Normally, the default sizes for these tags are 0. However, when the pool is allocating virtual memory, the size and threshold is rounded up to be a multiple of the system's page size. Currently, this is 4KB. This allows the system to make efficient use of virtual memory. Virtual memory includes MEMF_VIRTUAL and MEMF_ANY. exec.library/ASOT_MESSAGE exec.library/ASOT_MESSAGE NAME ASOT_MESSAGE -- Message TAGS ASOMSG_Size Size of the structure to be allocated. You might want to add your "payload" to this. Default: sizeof(struct Message). ASOMSG_ReplyPort Reply port to use for ReplyMsg. Default: 0 ASOMSG_Length The length of the complete message, including the payload (corresponding to message mn_Length). Default: The value given with ASOMSG_Size ASOMSG_Name Pointer to a name string for the node's name field. The name pointer must remain addressable throughout the object's life time. Default: 0 NOTES Memory for this object is allocated as MEMF_SHARED. For interrupt accessability, you might want to change this to MEMF_PUBLIC. If ASOMSG_Length is not specified, the value given with ASOMSG_Size is used. exec.library/ASOT_MUTEX exec.library/ASOT_MUTEX NAME ASOT_MUTEX -- Mutex (V52) TAGS ASOMUTEX_Recursive Make the Mutex recursive (maybe be obtained multiple times by the same task) Default: TRUE NOTES Memory for this object is allocated as MEMF_SHARED. exec.library/ASOT_NODE exec.library/ASOT_NODE NAME ASOT_NODE -- List node TAGS ASONODE_Size Size of the structure to be allocated. Default: sizeof(struct Node) or sizeof(struct MinNode), depending on the value of ASONODE_Min. ASONODE_Min Make this node a MinNode. Default: FALSE ASONODE_Type The node's type (see exec/nodes.h). Default: NT_UNKNOWN ASONODE_Pri The node's priority. This tag is ignored for MinNodes. Default: 0 ASONODE_Name A pointer to a string for the node's name. This pointer is copied verbatim to the appropriate field in the node. This tag is ignored for MinNodes. Default: 0 NOTES Memory for this object is allocated as MEMF_SHARED. For non-public nodes, it might be desirable to override the memory to MEMF_PRIVATE. exec.library/ASOT_PORT exec.library/ASOT_PORT NAME ASOT_PORT -- Message Port TAGS ASOPORT_Size Size of the structure to be allocated. Default: sizeof(struct MsgPort). ASOPORT_AllocSig A boolean value, indicating whether a signal should be allocated or not. Default: TRUE ASOPORT_Signal A signal number to use. If this tag is not -1, ASOPORT_AllocSig is assumed to be FALSE. Default: -1 ASOPORT_Action An action to carry out when a message arrives. (see exec/ports.h, enMsgPortActions). Default: PA_SIGNAL ASOPORT_Pri Priority of the port for list enqeueing. Default: 0 ASOPORT_Name Pointer to a name for the port. The pointer is copied to the port's node name field, and must remain addressable (i.e. static or allocated) unless ASOPORT_CopyName is set to true. Default: 0 (no name) ASOPORT_CopyName A boolean value, indicating whether the name string should be copied or not. If TRUE, the string is duplicated and the soure pointer given by ASOPORT_Name can be freed again. Default: FALSE (ASOPORT_Name is not copied) ASOPORT_Target Pointer to the port's target, either a task (for PA_SIGNAL), or a software interrupt. Default: The current task's address ASOPORT_Public Make the port public by calling AddPort on it. Default: TRUE when a name is given, FALSE otherwise NOTES Memory for this object is allocated as MEMF_PUBLIC. exec.library/ASOT_RMAP exec.library/ASOT_RMAP NAME ASOT_RMAP -- Resource map TAGS ASORMAP_Base Base of the managed resources ASORMAP_Size Size of the managed resources ASORMAP_Quantum Minimal quantum for one allocation. All allocations will be at least this big. Default: MEM_BLOCKSIZE ASORMAP_CacheMax Maximum size for quantum cache. All allocations smaller than this size will be taken from caches. Note that creation can fail if there are too many caches required. Default: 0 (No caches) exec.library/ASOT_SEMAPHORE exec.library/ASOT_SEMAPHORE NAME ASOT_SEMAPHORE -- Signal Semaphore TAGS ASOSEM_Size Size of the structure to be allocated. Default: sizeof(struct SignalSemaphore). ASOSEM_Name Pointer to a string used as name for the semaphore. The pointer must remain valid, unless ASOSEM_CopyName is TRUE. Default: 0 (necessary for public semaphores). ASOSEM_CopyName A boolean value, indicating whether the name string should be copied or not. If TRUE, the string is duplicated and the soure pointer given by ASOSEM_Name can be freed again. Default: FALSE (ASOSEM_Name is not copied) ASOSEM_Pri Priority to use when adding to system list. Default: 0 ASOSEM_Public Boolean value, indicating whether to make the semaphore public or not (by calling AddSemaphore). Default: FALSE if ASOSEM_Name == 0, otherwise TRUE NOTES Memory for this object is allocated as MEMF_SHARED. The semaphore is automatically initalized (via InitSemaphore) when it's created by this function. If the semaphore was allocated with ASOSEM_Public, it is automatically removed when freeing it. exec.library/ASOT_TAGLIST exec.library/ASOT_TAGLIST NAME ASOT_TAGLIST -- TagItem array TAGS ASOTAGS_Size Raw size of the array, i.e. the size of the complete array, _NOT_ one element. Default: 0 ASOTAGS_NumEntries Number of entries to allocate. For this type of object, it's more convenient to use this tag instead of ASOTAGS_Size. Note that this tag is mutually exlusive with ASOTAGS_Size. Default: 0 NOTES Memory for this object is allocated as MEMF_PRIVATE. You might want to change this depending on how the taglist is used. exec.library/AttemptNamedMemory exec.library/AttemptNamedMemory NAME AttemptNamedMemory -- Try to get access to named memory (V51) SYNOPSIS void *AttemptNamedMemory(STRPTR space, STRPTR name); FUNCTION Calling this function will try to lock the named memory block for exclusive access by the caller. If successful, the pointer to the block is returned. If the block does not exist, NULL is returned. If the block is locked by another entity, the call will return immediately with a result of NULL. This function will never block. INPUTS space - Namespace to search for the block. name - Name of the block to update. RESULT If successful, the pointer to the memory block is returned. If the block does not exist, NULL is returned. SEE ALSO AllocNamedMemory, FreeNamedMemory, FindNamedMemory, LockNamedMemory, UnlockNamedMemory exec.library/AttemptSemaphore exec.library/AttemptSemaphore NAME AttemptSemaphore -- try to obtain without blocking SYNOPSIS success = AttemptSemaphore(signalSemaphore) LONG AttemptSemaphore(struct SignalSemaphore *); FUNCTION This call is similar to ObtainSemaphore(), except that it will not block if the semaphore could not be locked. INPUT signalSemaphore -- an initialized signal semaphore structure RESULT success -- TRUE if the semaphore was locked, false if some other task already possessed the semaphore. SEE ALSO ObtainSemaphore() ObtainSemaphoreShared(), ReleaseSemaphore(), exec/semaphores.h exec.library/AttemptSemaphoreShared exec.library/AttemptSemaphoreShared NAME AttemptSemaphoreShared -- try to obtain without blocking (V37) SYNOPSIS success = AttemptSemaphoreShared(signalSemaphore) LONG AttemptSemaphoreShared(struct SignalSemaphore *); FUNCTION This call is similar to ObtainSemaphoreShared(), except that it will not block if the semaphore could not be locked. INPUT signalSemaphore -- an initialized signal semaphore structure RESULT success -- TRUE if the semaphore was granted, false if some other task already possessed the semaphore in exclusive mode. NOTE This call does NOT preserve registers. Starting in V39 this call will grant the semaphore if the caller is already the owner of an exclusive lock on the semaphore. In pre-V39 systems this would not be the case. If you need this feature you can do the following workaround: LONG myAttemptSempahoreShared(struct SignalSemaphore *ss) { LONG result; /* Try for a shared semaphore */ if (!(result=AttemptSemaphoreShared(ss))) { /* Now try for the exclusive one... */ result=AttempSemaphore(ss); } return(result); } SEE ALSO ObtainSemaphore() ObtainSemaphoreShared(), ReleaseSemaphore(), exec/semaphores.h exec.library/AvailMem exec.library/AvailMem NAME AvailMem -- memory available given certain requirements SYNOPSIS size = AvailMem(attributes) ULONG AvailMem(ULONG); FUNCTION This function returns the amount of free memory given certain attributes. To find out what the largest block of a particular type is, add MEMF_LARGEST into the requirements argument. Returning the largest block is a slow operation. Note that AvailMem(MEMF_TOTAL|MEMF_FAST|MEMF_CHIP) is not the same as AvailMem(MEMF_TOTAL). Passing attribute flags will only consider memory that is flagged as such. As some memory might not be directly accessible (being used as backup storage for virtual memory), the only way to get the complete memory size of the system is AvailMem(MEMF_TOTAL). WARNING Due to the effect of multitasking, the value returned may not actually be the amount of free memory available at that instant. INPUTS requirements - a requirements mask as specified in AllocMem. Additionally, these flags modify the behavior of AvailMem: MEMF_LARGEST - Find the largest block matching the given attribues. Note that this only checks physically addressed memory. Virtually addressed memory is not checked. MEMF_TOTAL - Return the total amount of memory matching the given attributes. Note that MEMF_VIRTUAL might return more than is actually physically installed in the system. MEMF_CORE_RESIDENT - Return the amount of memory that is currently available in-core, i.e. memory that is not paged out. RESULT size - total free space remaining (or the largest free block). NOTE For V36 Exec, AvailMem(MEMF_LARGEST) does a consistency check on the memory list. Alert AN_MemoryInsane will be pulled if any mismatch is noted. EXAMPLE /* return size of largest available chip memory chunk */ AvailMem(MEMF_CHIP|MEMF_LARGEST); /* return the total amount of memory in the system */ AvailMem(MEMF_TOTAL); /* return the amount of virtually addressable memory */ AvailMem(MEMF_TOTAL|MEMF_VIRTUAL); SEE ALSO exec/memory.h exec.library/AVL_AddNode exec.library/AVL_AddNode NAME AVL_AddNode -- Add node to the tree (V45) SYNOPSIS result = AVL_AddNode( root, node, func ) struct AVLNode *AVL_FindNextNodeByKey(struct AVLNode **, struct AVLNode *, AVLNODECOMP); FUNCTION The function will add the given node to the AVL tree in the correct position. The correct position is determined by the compare function which is also passed in and which defines relative value of nodes by determining their "key" values and comparing them. Note that the compare function works like strcmp() by returning <0, 0, >0 results to define a less/equal/greater relationship. Note that there is no arbitration for access to the tree. You should use a SignalSemaphore if arbitration is required. INPUTS root - Address of(!) the root pointer(!) of the AVL tree. Initially, the root pointer must be set to NULL, which represents an empty AVL tree. node - The node to add func - The compare function to find the right position for the node in the tree RESULT If the node could be added, NULL is returned. If there is already a node in the tree that has the same key, the pointer to that node be returned and the given node will not be added. NOTES There are a few things to remember about AVL trees. First, they are binary balanced trees. You can expect O(log2(n)) performance for adding, removing, and searching by key. Second, the implementation does not care what kind of compare functions you provide to the AVL functions, i.e., what sort order you define. To work with an AVL tree you need two compare functions: AVLNODECOMP - Determines keys of two nodes and compares them AVLKEYCOMP - Compares a node's key to a given key The interpretation of the keys in these two functions must match. If your compare functions are flawed, the AVL trees will not work. The implementation does not compare keys or makes any assumption about them. A key can be anything that fits into a 32 bit value, even a pointer to the "true" key, whatever it may be. Remember that each key in a tree must be unique. If you want to add elements with identical keys, you could use, e.g., the memory address of the element as "second level" key to ensure unique keys for insertion into the tree. In that case, however, it is obviously not possible to retrieve the node by a single key. Also, remember that a struct AVLNode can be embedded anywhere within your element's structure. The example below illustrates all the points made above. If you don't need second level keys or embedded struct AVLNode's, you can simplify things. Finally, the implementation is not recursive and you don't have to provide a huge stack even when using AVL functions on huge trees. EXAMPLE struct Element { struct Node el_Node; /* Normal maintenance */ UWORD el_pad; ULONG el_SortKey; /* Bringing order into things ... */ struct AVLNode el_AVLNode; /* Fast access */ ULONG el_Content; /* Magic private content */ }; ... LONG ASM AVLNodeComp(REG(a0) struct AVLNode *avlnode1, REG(a1) struct AVLNode *avlnode2) { struct Element *el1, *el2; LONG res; el1 = ElementStart(avlnode1); el2 = ElementStart(avlnode2); res = (LONG)(el1->el_SortKey - el2->el_SortKey); if(res == 0) { // For identical keys, use, e.g., the address as 2nd key res = (LONG)((ULONG)avlnode1 - (ULONG)avlnode2); } /* if */ return(res); } /* AVLNodeComp */ static LONG ASM AVLKeyComp(REG(a0) struct AVLNode *avlnode, REG(a1) AVLKey avlkey) { struct Element *el; LONG res; el = ElementStart(avlnode); res = (LONG)(el->el_SortKey - (ULONG)avlkey); return(res); } /* AVLKeyComp */ ... /* Initially, the tree must be marked as empty! */ avlroot = NULL; ... if(AVL_AddNode(&avlroot, &el->el_AVLNode, AVLNodeComp)) { // This should not happen because our AVLNodeComp() // ensures that each node's key is unique by using its address. // If it happens it means that we are trying to readd a // node that already has been added in this case. } /* if */ BUGS SEE ALSO AVL_FindLastNode(), AVL_FindFirstNode(), AVL_RemNodeByKey(), AVL_RemNodeByAddress(), AVL_FindNextNodeByKey(), AVL_FindNextNodeByAddress() exec.library/AVL_FindFirstNode exec.library/AVL_FindFirstNode NAME AVL_FindFirstNode -- return the lowest/smallest node (V45) SYNOPSIS result = AVL_FindFirstNode( root ) struct AVLNode *AVL_FindFirstNode(const struct AVLNode *root) FUNCTION This functions will return the pointer to the first node in the given AVL tree. Using this function, you can start to walk the tree in a "linear" fashion. INPUTS root - The pointer to the root of the AVL tree RESULT A pointer to the smallest/lowest node in the tree or NULL for an empty tree. NOTES BUGS SEE ALSO AVL_FindNextNodeByAddress(), AVL_RemNodeByAddress() exec.library/AVL_FindLastNode exec.library/AVL_FindLastNode NAME AVL_FindLastNode -- return the highest/biggest node (V45) SYNOPSIS result = AVL_FindLastNode( root ) struct AVLNode *AVL_FindLastNode(const struct AVLNode *root) FUNCTION This functions will return the pointer to the last node in the given AVL tree. Using this function, you can start to walk the tree in a "linear" fashion. INPUTS root - The pointer to the root of the AVL tree RESULT A pointer to the highest/biggest node in the tree or NULL for an empty tree. NOTES BUGS SEE ALSO AVL_FindPrevNodeByAddress(), AVL_RemNodeByAddress() exec.library/AVL_FindNextNodeByAddress exec.library/AVL_FindNextNodeByAddress NAME AVL_FindNextNodeByAddress -- Return the next node of a tree (V45) SYNOPSIS result = AVL_FindNextNodeByAddress( node ) struct AVLNode *AVL_FindNextNodeByAddress(const struct AVLNode *node) FUNCTION Given the pointer to a struct AVLNode, this function will return the logically next/higher/bigger entry in the tree Using this function, you can start to walk the tree in a "linear" fashion. INPUTS node - pointer to the current AVLNode RESULT A pointer to the logically next AVLNode or NULL if there is none. NOTES The node passed in *better*be* part of the tree or you lose big time! EXAMPLE avlnode = AVL_FindFirstNode(avlroot); while(avlnode) { nextavlnode = AVL_FindNextNodeByAddress(avlnode); /* look at, or remove avlnode */ /* walk the tree */ avlnode = nextavlnode; } /* while */ BUGS SEE ALSO AVL_FindFirstNode(), AVL_RemNodeByAddress() exec.library/AVL_FindNextNodeByKey exec.library/AVL_FindNextNodeByKey NAME AVL_FindNextNodeByKey -- Find node identified by a key (V45) SYNOPSIS result = AVL_FindNextNodeByKey( root, key, func ) struct AVLNode *AVL_FindNextNodeByKey(const struct AVLNode *, AVLKey, AVLKEYCOMP); FUNCTION The function will search for a node or the next higher node based on the key given and return a pointer to it. Note that the compare function works like strcmp() by returning <0, 0, >0 results to define a less/equal/greater relationship. INPUTS root - pointer to the root of the AVL tree key - An abstract key to match a node by the given compare function func - The compare function to check if a struct AVLNode matches the given key RESULT A pointer to the node with the given key or the next higher node if no exact match was found. NOTES BUGS SEE ALSO AVL_FindLastNode(), AVL_FindFirstNode(), AVL_AddNode(), AVL_RemNodeByAddress(), AVL_FindNextNodeByAddress() exec.library/AVL_FindNode exec.library/AVL_FindNode NAME AVL_FindNode -- Find a node identified by its key (V45) SYNOPSIS result = AVL_FindNode( root, key, func ) struct AVLNode *AVL_FindNode(const struct AVLNode *, AVLKey, AVLKEYCOMP); FUNCTION The function will search for the node with the given key and return a pointer to it. Note that the compare function works like strcmp() by returning <0, 0, >0 results to define a less/equal/greater relationship. INPUTS root - pointer to the root of the AVL tree key - An abstract key to match a node by the given compare function func - The compare function to check if a struct AVLNode matches the given key RESULT A pointer to the node or NULL if the node could not be found. NOTES BUGS SEE ALSO AVL_FindLastNode(), AVL_FindFirstNode(), AVL_AddNode(), AVL_RemNodeByAddress() exec.library/AVL_FindPrevNodeByAddress exec.library/AVL_FindPrevNodeByAddress NAME AVL_FindPrevNodeByAddress -- Return previous node of a tree (V45) SYNOPSIS result = AVL_FindPrevNodeByAddress( node ) struct AVLNode *AVL_FindPrevNodeByAddress(const struct AVLNode *node) FUNCTION Given the pointer to a struct AVLNode, this function will return the logically previous/lower/smaller entry in the tree Using this function, you can start to walk the tree in a "linear" fashion. INPUTS node - pointer to the current AVLNode RESULT A pointer to the logically previous AVLNode or NULL if there is none. NOTES The node passed in *better*be* part of the tree or you lose big time! EXAMPLE avlnode = AVL_FindLastNode(avlroot); while(avlnode) { prevavlnode = AVL_FindPrevNodeByAddress(avlnode); /* look at, or remove avlnode */ /* walk the tree */ avlnode = prevavlnode; } /* while */ BUGS SEE ALSO AVL_FindLastNode(), AVL_RemNodeByAddress() exec.library/AVL_FindPrevNodeByKey exec.library/AVL_FindPrevNodeByKey NAME AVL_FindPrevNodeByKey -- Find node identified by a key (V45) SYNOPSIS result = AVL_FindPrevNodeByKey( root, key, func ) struct AVLNode *AVL_FindPrevNodeByKey(const struct AVLNode *, AVLKey, AVLKEYCOMP); FUNCTION The function will search for a node or the next lower node based on the key given and return a pointer to it. Note that the compare function works like strcmp() by returning <0, 0, >0 results to define a less/equal/greater relationship. INPUTS root - pointer to the root of the AVL tree key - An abstract key to match a node by the given compare function func - The compare function to check if a struct AVLNode matches the given key RESULT A pointer to the node with the given key or the next lower node if no exact match was found. NOTES BUGS SEE ALSO AVL_FindLastNode(), AVL_FindFirstNode(), AVL_AddNode(), AVL_RemNodeByAddress(), AVL_FindPrevNodeByAddress() exec.library/AVL_RemNodeByAddress exec.library/AVL_RemNodeByAddress NAME AVL_RemNodeByAddress - Remove a given node (V45) SYNOPSIS result = AVL_RemNodeByAddress( root, node ) struct AVLNode *AVL_RemNodeByAddress(struct AVLNode **, struct AVLNode *); FUNCTION The function will remove the given node from the tree. Note that there is no arbitration for access to the tree. You should use a SignalSemaphore if arbitration is required. INPUTS root - Address of(!) the root pointer(!) of the AVL tree node - pointer to the struct AVLNode that should be removed RESULT A pointer to the removed node. NOTES The node to be removed *better*be* part of the tree or you lose big time! BUGS SEE ALSO AVL_FindLastNode(), AVL_FindNode(), AVL_FindFirstNode(), AVL_RemNodeByAddress(), AVL_AddNode() exec.library/AVL_RemNodeByKey exec.library/AVL_RemNodeByKey NAME AVL_RemNodeByKey -- Remove a node identified by its key (V45) SYNOPSIS result = AVL_RemNodeByKey( root, key, func ) struct AVLNode *AVL_RemNodeByKey(struct AVLNode **, AVLKey, AVLKEYCOMP); FUNCTION The function will search for the node with the given key and remove it from the tree. Note that there is no arbitration for access to the tree. You should use a SignalSemaphore if arbitration is required. INPUTS root - Address of(!) the root pointer(!) of the AVL tree key - An abstract key to match a node by the given compare function func - The compare function to check if a struct AVLNode matches the given key RESULT A pointer to the removed node or NULL if the node could not be found. NOTES BUGS SEE ALSO AVL_FindLastNode(), AVL_FindNode(), AVL_FindFirstNode(), AVL_RemNodeByAddress(), AVL_AddNode() exec.library/BeginIO exec.library/BeginIO NAME BeginIO -- initiate asynchronous device I/O (V50) SYNOPSIS BeginIO(ioReq) VOID BeginIO(struct IORequest *); FUNCTION This function takes an IORequest, and passes it directly to the "BeginIO" vector of the proper device. This is equivalent to SendIO(), except that io_Flags is not cleared. A good understanding of Exec device I/O is required to properly use this function. This function does not wait for the I/O to complete. NOTE You must not call BeginIO() on an IORequest that has never been successfully used with OpenDevice() and that is not a duplicate of an IORequest which was successfully used with OpenDevice(). If you use it on an IORequest that was just created with CreateIORequest() or which was just used with the CloseDevice() function, you will either cause your task to hang, or you may crash the operating system. Prior to exec.library V50, the BeginIO() function used to be part of a link library (amiga.lib) and was not an integral part of the exec.library API. INPUTS ioReq - an initialized and opened IORequest structure with the io_Flags field set to a reasonable value (set to 0 if you do not require io_Flags). SEE ALSO AbortIO(), DoIO(), SendIO(), WaitIO() exec.library/CacheClearE exec.library/CacheClearE NAME CacheClearE - Cache clearing with extended control (V37) SYNOPSIS CacheClearE(address,length,caches) void CacheClearE(APTR,ULONG,ULONG); FUNCTION Flush out the contents of the CPU instruction and/or data caches. If dirty data cache lines are present, push them to memory first. Motorola CPUs have separate instruction and data caches. A data write does not update the instruction cache. If an instruction is written to memory or modified, the old instruction may still exist in the cache. Before attempting to execute the code, a flush of the instruction cache is required. For most systems, the data cache is not updated by Direct Memory Access (DMA), or if some external factor changes shared memory. Caches must be cleared after *any* operation that could cause invalid or stale data. The most common cases are DMA and modifying instructions using the processor. Some examples: Self modifying code Building Jump tables Run-time code patches Relocating code for use at different addresses. Loading code from disk INPUTS address - Address to start the operation. This may be rounded due to hardware granularity. length - Length of area to be cleared, or $FFFFFFFF to indicate all addresses should be cleared. caches - Bit flags to indicate what caches to affect. The current supported flags are: CACRF_ClearI Clear instruction cache CACRF_ClearD Flush (write back) data cache CACRF_InvalidateD Discard data cache All other bits are reserved for future definition. NOTES On systems with a copyback mode cache, any dirty data is pushed to memory as a part of this operation. Regardless of the length given, the function will determine the most efficient way to implement the operation. For some cache systems, including the 68030, the overhead partially clearing a cache is often too great. The entire cache may be cleared. For all current Amiga models, Chip memory is set with Instruction caching enabled, data caching disabled. This prevents coherency conflicts with the blitter or other custom chip DMA. Custom chip registers are marked as non-cacheable by the hardware. The system takes care of appropriately flushing the caches for normal operations. The instruction cache is cleared by all calls that modify instructions, including LoadSeg(), MakeLibrary() and SetFunction(). SEE ALSO exec/execbase.i, CacheControl, CacheClearU exec.library/CacheClearU exec.library/CacheClearU NAME CacheClearU - User callable simple cache clearing (V37) SYNOPSIS CacheClearU() void CacheClearU(void); FUNCTION Flush out the contents of any CPU instruction and data caches. If dirty data cache lines are present, push them to memory first. Caches must be cleared after *any* operation that could cause invalid or stale data. The most common cases are DMA and modifying instructions using the processor. See the CacheClearE() autodoc for a more complete description. Some examples of when the cache needs clearing: Self modifying code Building Jump tables Run-time code patches Relocating code for use at different addresses. Loading code from disk NOTE If possible, prefer CacheClearE with a tight bound to flush caches. Flushing all caches will generally result in a performance loss. SEE ALSO CacheControl, CacheClearE exec.library/CacheControl exec.library/CacheControl NAME CacheControl - Instruction & data cache control SYNOPSIS oldBits = CacheControl(cacheBits,cacheMask) ULONG CacheControl(ULONG,ULONG); FUNCTION This function provides global control of any instruction or data caches that may be connected to the system. All settings are global -- per task control is not provided. The action taken by this function will depend on the type of CPU installed. This function may be patched to support external caches, or different cache architectures. In all cases the function will attempt to best emulate the provided settings. Use of this function may save state specific to the caches involved. The list of supported settings is provided in the exec/execbase.i include file. The bits currently defined map directly to the Motorola 68030 CPU CACR register. Alternate cache solutions may patch into the Exec cache functions. Where possible, bits will be interpreted to have the same meaning on the installed cache. INPUTS cacheBits - new values for the bits specified in cacheMask. CACRF_EnableI - Enable instruction cache CACRF_FreezeI - Freeze instruction cache CACRF_EnableD - Enable data cache CACRF_FreezeD - Freeze data cache cacheMask - a mask with ones for all bits to be changed. RESULT oldBits - the complete prior values for all settings. NOTE As a side effect, this function clears all caches. SEE ALSO exec/execbase.i, CacheClearU, CacheClearE exec.library/CachePostDMA exec.library/CachePostDMA NAME CachePostDMA - Take actions after to hardware DMA (V37) SYNOPSIS CachePostDMA(vaddress,&length,flags) CachePostDMA(APTR,ULONG *,ULONG); FUNCTION Take all appropriate steps after Direct Memory Access (DMA). This function is primarily intended for writers of DMA device drivers. The action will depend on the CPU type installed, caching modes, and the state of any Memory Management Unit (MMU) activity. INPUTS address - Same as initially passed to CachePreDMA length - Same as initially passed to CachePreDMA flags - Values: DMA_NoModify - If the area was not modified (and thus there is no reason to flush the cache) set this bit. DMA_ReadFromRAM - Indicates that this DMA is a read from RAM to the DMA device (ie - a write to the hard drive) This flag is not required but if used must match in both the PreDMA and PostDMA calls. This flag *should* be used to help the system provide the best performance. This flag is safe in all versions of CachePostDMA() NOTE Every call to CachePreDMA must be paired with an appropriate call to CachePostDMA. Contrary to earlier documentation, the length parameter is an ULONG, not a LONG pointer. SEE ALSO exec/execbase.i, CachePreDMA, CacheClearU, CacheClearE exec.library/CachePreDMA exec.library/CachePreDMA NAME CachePreDMA - Take actions prior to hardware DMA (V37) SYNOPSIS paddress = CachePreDMA(vaddress,&length,flags) APTR CachePreDMA(APTR,LONG *,ULONG); FUNCTION Take all appropriate steps before Direct Memory Access (DMA). This function is primarily intended for writers of DMA device drivers. The action will depend on the CPU type installed, caching modes, and the state of any Memory Management Unit (MMU) activity. This function supports advanced cache architectures that have "copyback" modes. With copyback, write data may be cached, but not actually flushed out to memory. If the CPU has unflushed data at the time of DMA, data may be lost. INPUTS address - Base address to start the action. length - Pointer to a longword with a length. flags - Values: DMA_Continue - Indicates this call is to complete a prior request that was broken up. DMA_ReadFromRAM - Indicates that this DMA is a read from RAM to the DMA device (ie - a write to the hard drive) This flag is not required but if used must match in both the PreDMA and PostDMA calls. This flag *should* be used to help the system provide the best performance. This flag is safe in all versions of CachePreDMA() RESULTS paddress- Physical address that corresponds to the input virtual address. Note that this value is only valid if the returned length is not 0... &length - This length value will be updated to reflect the contiguous length of physical memory present at paddress. This may be smaller than the requested length. To get the mapping for the next chunk of memory, call the function again with a new address, length, and the DMA_Continue flag. NOTE Due to processor granularity, areas outside of the address range may be affected by the cache flushing actions. Care has been taken to ensure that no harm is done outside the range, and that activities on overlapping cache lines won't harm data. With release 50, CachePreDMA/CachePostDMA is considered obsolete. Instead, StartDMA/EndDMA should be used. Due to the virtualized address space of AmigaOS 4, device drivers doing DMA *MUST* use either CachePreDMA/CachePostDMA or StartDMA/EndDMA, *and* be prepared for segmented transfers. Contrary to earlier documentation, the length parameter is an ULONG, not a LONG pointer. SEE ALSO exec/execbase.i, CachePostDMA, CacheClearU, CacheClearE StartDMA, EndDMA exec.library/Cause exec.library/Cause NAME Cause -- cause a software interrupt SYNOPSIS Cause(interrupt) void Cause(struct Interrupt *); FUNCTION This function causes a software interrupt to occur. If it is called from user mode (and processor level 0), the software interrupt will preempt the current task. This call is often used by high-level hardware interrupts to defer medium-length processing down to a lower interrupt level. Note that a software interrupt is still a real interrupt, and must obey the same restrictions on what system function it may call. Currently only 5 software interrupt priorities are implemented: -32, -16, 0, +16, and +32. Priorities in between are truncated, values outside the -32/+32 range are not allowed. INPUTS interrupt - pointer to a properly initialized interrupt node BUGS Unlike other Interrupts, SoftInts must preserve the value of A6 (on legacy interrupts) exec.library/CheckIO exec.library/CheckIO NAME CheckIO -- get the status of an IORequest SYNOPSIS result = CheckIO(iORequest) struct IORequest *CheckIO(struct IORequest *); FUNCTION This function determines the current state of an I/O request and returns NULL if the I/O has not yet completed. This function effectively hides the internals of the I/O completion mechanism. CheckIO() will NOT remove the returned IORequest from the reply port. This is best performed with WaitIO(). If the I/O request has already completed, WaitIO() will return quickly. Use of the Remove() function is dangerous, since other tasks may still be adding things to your message port; a Disable()/Enable() pair would be required. This function should NOT be used to busy loop (looping until I/O is complete). WaitIO() is provided for that purpose. INPUTS iORequest - pointer to an I/O request block RESULTS result - NULL if I/O is still in progress. Otherwise the result is a pointer to the IORequest block. NOTE CheckIO() will only produce a meaningful result if called on an IORequest which has been started with SendIO() or BeginIO(). If the IORequest was not previously started with either SendIO() or BeginIO(), CheckIO() will falsely report that I/O is still in progress. This means that you cannot rely only on CheckIO() to tell you if an IORequest is still in progress. You must also keep track of whether the IORequest was started first. BUGS Previously, CheckIO() used to be documented to return a BOOL result. This was incorrect. It always returned either a NULL pointer or a pointer to the IORequest in progress. Older documentation suggested that CheckIO() could hang if the IORequest had never been used. This was never the case. Under these circumstances CheckIO() could never hang, it would "only" falsely report that I/O was still in progress. SEE ALSO DoIO(), SendIO(), WaitIO(), AbortIO() exec.library/CloseDevice exec.library/CloseDevice NAME CloseDevice -- conclude access to a device SYNOPSIS CloseDevice(iORequest) void CloseDevice(struct IORequest *); FUNCTION This function informs the device that access to a device/unit previously opened has been concluded. The device may perform certain house-cleaning operations. The user must ensure that all outstanding IORequests have been returned before closing the device. The AbortIO function can kill any stragglers. After a close, the I/O request structure is free to be reused. Starting with V36 exec it is safe to CloseDevice() with an IORequest that is either cleared to zeros, or failed to open. INPUTS iORequest - pointer to an I/O request structure SEE ALSO OpenDevice exec.library/CloseLibrary exec.library/CloseLibrary NAME CloseLibrary -- conclude access to a library SYNOPSIS CloseLibrary(library) void CloseLibrary(struct Library *); FUNCTION This function informs the system that access to the given library has been concluded. The user must not reference the library or any function in the library after this close. Starting with V36, it is safe to pass a NULL instead of a library pointer. INPUTS library - pointer to a library node NOTE Library writers must pass a SegList pointer or NULL back from their open point. This value is used by the system, and not visible as a return code from CloseLibrary. SEE ALSO OpenLibrary exec.library/ColdReboot exec.library/ColdReboot NAME ColdReboot - reboot the Amiga (V36) SYNOPSIS ColdReboot() void ColdReboot(void); FUNCTION Reboot the machine. All external memory and periperals will be RESET, and the machine will start its power up diagnostics. This function never returns. INPUT A chaotic pile of disoriented bits. RESULTS An altogether totally integrated living system. exec.library/CopyMem exec.library/CopyMem NAME CopyMem - general purpose memory copy function SYNOPSIS void CopyMem(APTR source, APTR dest, uint32 size); FUNCTION CopyMem is a general purpose, fast memory copy function. It can deal with arbitrary lengths, with its pointers on arbitrary alignments. It attempts to optimize larger copies with more efficient copies, it uses byte copies for small moves, parts of larger copies, or the entire copy if the source and destination are misaligned with respect to each other. Arbitrary overlapping copies are not supported. The internal implementation of this function will change from system to system and may be implemented via hardware DMA. INPUTS source - a pointer to the source data region dest - a pointer to the destination data region size - the size (in bytes) of the memory area. Zero copies zero bytes SEE ALSO CopyMemQuick exec.library/CopyMemQuick exec.library/CopyMemQuick NAME CopyMemQuick - optimized memory copy function SYNOPSIS void CopyMemQuick(uint32 *source, uint32 *dest, uint32 size); FUNCTION CopyMemQuick is a highly optimized memory copy function, with restrictions on the size and alignment of its arguments. Both the source and destination pointers must be longword aligned. In addition, the size must be an integral number of longwords (e.g. the size must be evenly divisible by four). Arbitrary overlapping copies are not supported. The internal implementation of this function will change from system to system, and may be implemented via hardware DMA. On 440ep/460ex systems the best performance is obtained when both source and destination are 32 bytes (256 bits) aligned and the size is at least 96 bytes (V53.40 or higher required). INPUTS source - a pointer to the source data region, long aligned dest - a pointer to the destination data region, long aligned size - the size (in bytes) of the memory area. Zero copies zero bytes. SEE ALSO CopyMem exec.library/CreateIORequest exec.library/CreateIORequest NAME CreateIORequest() -- create an IORequest structure (V36) SYNOPSIS ioReq = CreateIORequest( ioReplyPort, size ); struct IORequest *CreateIORequest(struct MsgPort *, ULONG); FUNCTION Allocates memory for and initializes a new IO request block of a user-specified number of bytes. The number of bytes must be at least as large as a "struct Message". INPUTS ioReplyPort - Pointer to a port for replies (an initialized message port, as created by CreateMsgPort() ). If NULL, this function fails. size - the size of the IO request to be created. RESULT ioReq - A pointer to the new IORequest block, or NULL. SEE ALSO DeleteIORequest, CreateMsgPort(), amiga.lib/CreateExtIO() exec.library/CreateLibrary exec.library/CreateLibrary NAME CreateLibrary -- Construct a library (V50) CreateLibraryTags -- Vararg version (V50) SYNOPSIS library = CreateLibrary(taglist); struct Library *CreateLibrary(struct TagItem *); library = CreateLibraryTags(tag1, ...); struct Library *CreateLibraryTags(Tag, ...); FUNCTION This function is used for constructing a new-style library. The same call is used to make devices. Space for the library is allocated from the system's free memory pool. INPUTS taglist - Pointer to a tag list that contains additional data. Possible tagitems include: CLT_Vector68K: Pointer to a 68k (i.e. old-style) compatible vector table (see MakeFunctions). This pointer is passed directly to MakeFunctions(). If no pointer ot NULL is given, no 68k compatible jump table is generated, except for the default vectors Open, Close, Expunged, and the Reserved vector. Note: If this is NULL, the library can't be used from 68k code. It's generally discouraged to still support 68k code, however, it might be desirable to keep an old 68k interface around, for backward compatibility. Default: NULL. CLT_Legacy: This specifies the name of the interface that should be used when legacy programs cross-call this library from 68K. Default: "main". CLT_NoLegacyIFace: This boolean tag will determine weather a legacy interface will be used or not. This is useful for libraries without a backward compatible jump table. Default: FALSE. CLT_InitData: Pointer to a data area containing InitData()-style initialization data. This is used to initialize the library's data part. If NULL, no initialization takes place. Default: NULL. CLT_InitFunc: If non-NULL, Pointer to a function that is called before returning from CreateLibrary. The prototype is defined as follows: library = init(base, seglist, exec); struct Library * init(struct Library, APTR, struct Interface *); The function is called at the end of the library creation process, and it's result is returned from CreateLibrary. 'base' will point to the library base just created, seglist is a pointer to the libraries seglist. You must store this pointer somewhere and return it when expunge is called. Finally, 'exec' will be pointed to an Exec interface, for convenience. Default: NULL. CLT_Seglist: Pointer to a seglist. This information is passed to the library's CLT_InitFunc and should be recorded there to remove the library from memory when it's expunged. Default: NULL. CLT_Interfaces: A pointer to a 0-terminated array of pointers to taglists for creation of interfaces. The interfaces will be generated one after another and added to the tail of the library's list of interfaces. Note that a value of 0, or a pointer to an array without entries will still result in a "valid" library, however, there will be no functional interface for native programs (68k might exist). Generally, it's not advised to only supply a 68k interface. Default: No default. This tag is mandatory. At least one interface (the library management interface) _MUST_ be given. CLT_DataSize: The data size of the library, including the standard library node. Default: sizeof(struct Library) RESULT library - the fully initialized library, or NULL if the initialization failed. EXAMPLE See the SDK for a complete example of a new-style library. NOTE This is aboslutely VITAL: In V50 and higher, no other method for library creation except for CreateLibrary/DeleteLibrary will be supported anymore. Note that library creation through resident structures will use CreateLibrary. The older MakeLibrary mechanism is still available for backward compatibility, but it's use is strictly limited to old libraries. SEE ALSO MakeLibrary, MakeInterface, AddLibrary, DeleteLibrary exec.library/CreateMsgPort exec.library/CreateMsgPort NAME CreateMsgPort - Allocate and initialize a new message port (V36) SYNOPSIS CreateMsgPort() struct MsgPort * CreateMsgPort(void); FUNCTION Allocates and initializes a new message port. The message list of the new port will be prepared for use (via NewList). A signal bit will be allocated, and the port will be set to signal your task when a message arrives (PA_SIGNAL). You *must* use DeleteMsgPort() to delete ports created with CreateMsgPort()! RESULT MsgPort - A new MsgPort structure ready for use, or NULL if out of memory or signals. If you wish to add this port to the public port list, fill in the ln_Name and ln_Pri fields, then call AddPort(). Don't forget RemPort()! SEE ALSO DeleteMsgPort(), exec/AddPort(), exec/ports.h exec.library/CreatePool exec.library/CreatePool NAME CreatePool -- Generate a private memory pool header (V39) SYNOPSIS newPool=CreatePool(memFlags,puddleSize,threshSize) void *CreatePool(ULONG,ULONG,ULONG); FUNCTION Allocate and prepare a new memory pool header. Each pool is a separate tracking system for memory of a specific type. Any number of pools may exist in the system. Pools automatically expand and shrink based on demand. Fixed sized "puddles" are allocated by the pool manager when more total memory is needed. Many small allocations can fit in a single puddle. Allocations larger than the threshSize are allocation in their own puddles. At any time individual allocations may be freed. Or, the entire pool may be removed in a single step. INPUTS memFlags - a memory flags specifier, as taken by AllocMem. puddleSize - the size of Puddles... threshSize - the largest allocation that goes into normal puddles This *MUST* be less than or equal to puddleSize (CreatePool() will fail if it is not) RESULT The address of a new pool header, or NULL for error. NOTE This function is somewhat obsolete. Use AllocSysObject for creating memory pools. SEE ALSO DeletePool(), AllocPooled(), FreePooled(), AllocVecPooled(), FreeVecPooled(), AllocSysObject(), exec/memory.i exec.library/CreatePort exec.library/CreatePort NAME CreatePort - Allocate and initialize a new message port (V50) SYNOPSIS port = CreatePort(name, priority) struct MsgPort * CreatePort(STRPTR, BYTE); FUNCTION Allocates and initializes a new message port. The message list of the new port will be prepared for use (via NewList). A signal bit will be allocated, and the port will be set to signal your task when a message arrives (PA_SIGNAL). If a name is given, the port is made public with the given name and priority (through AddPort). You *must* use DeletePort() to delete ports created with CreatePort()! INPUTS name - Name for the port to make it public. Can be NULL, in which case the port is not added to the public list. The name string is not duplicated. priority - Priority for the port if it's added to the system list. RESULT MsgPort - A new MsgPort structure ready for use, or NULL if out of memory or signals. SEE ALSO DeletePort(), exec/AddPort(), exec/ports.h exec.library/CreateTask exec.library/CreateTask NAME CreateTask -- Create task with given name, priority, stacksize (V50) CreateTaskTags -- Vararg stub SYNOPSIS struct Task *task = CreateTask(CONST_STRPTR name, int32 pri, CONST_APTR initPC, uint32 stackSize, CONST struct TagItem *tagList); struct Task *task = CreateTaskTags(CONST_STRPTR name, int32 pri, CONST_APTR initPC, uint32 stackSize, Tag tag1, ...); FUNCTION This function simplifies program creation of sub-tasks by dynamically allocating and initializing required structures and stack space, and adding the task to Exec's task list with the given name and priority. A tc_MemEntry list is provided so that all stack and structure memory allocated by CreateTask() is automatically deallocated when the task is removed. An Exec task may not call dos.library functions or any function which might cause the loading of a disk-resident library, device, or file (since such functions are indirectly calls to dos.library). Only AmigaDOS Processes may call AmigaDOS; see the dos.library/CreateProc() or the dos.library/CreateNewProc() functions for more information. If other tasks or processes will need to find this task by name, provide a complex and unique name to avoid conflicts. INPUTS name - a null-terminated name string pri - an Exec task priority between -128 and 127, normally 0 funcEntry - the address of the first executable instruction of the subtask code stackSize - size in bytes of stack for the subtask. Don't cut it too close - system function stack usage may change. tagList - Pointer to a taglist. Currently, the following tags are defined: AT_Param1.. AT_Param8 Define a parameter to be passed to the newly created task. See the example below CT_LockStack The newly created stack is also locked in memory to prevent it from being paged to disk (Default: FALSE) RESULT task - a pointer to the newly created task, or NULL if there was not enough memory. NOTE This function replaces amiga.lib/CreateTask() USE THIS FUNCTION instead of AddTask: It will make use of more of the newer features, like automatic stack enlargement. EXAMPLE /* Task entry point */ void myTask(uint32 x, uint32 y) { printf("x = %d, y = %d\n", x, y); while (1); } /* Create the task*/ IExec->CreateTaskTags("test.task", 0, myTask, 16384, AT_Param1, 100, AT_Param2, 200, TAG_DONE); Output will look like this: x = 100, y = 200 BUGS Under exec.library V37 or beyond, the AddTask() function used internally by CreateTask() can fail whereas it couldn't fail in previous versions of Exec. Prior to amiga.lib V37.14, this function did not check for failure of AddTask() and thus might return a pointer to a task structure even though the task was not actually added to the system. Prior to amiga.lib V40.20 low memory conditions could cause CreateTask() to malfunction. The implementation checked whether the initial AllocTaskEntryEntry() call would fail, but would use an inappropriate test condition. SEE ALSO DeleteTask(), FindTask() exec.library/debug/AddDebugHook exec.library/debug/AddDebugHook NAME AddDebugHook -- Define a callback for debugger facilities SYNOPSIS BOOL AddDebugHook(struct Task *task, struct Hook *hookFunc); FUNCTION This functions sets the debugger callback for the given task. A debugger might require notification and/or control over certain events in the system, like an exception, removal of a task, or opening of a shared library. When such an event takes place, the debug hook is invoked (if present). The hook's object pointer will always point to the task that matches the event (such events are always synchronous). The message depends on the actual event. The event is identified by an uint32 passed as first item in the message. The rest of the message depends on the type of the message. The return value and the action taken will depend on the event (documented below). Currently, the following message types are defined. Note that in the following discussion, "message content" refers to the data following the message type: DBHMT_EXCEPTION: This message is sent whenever any exception occurs. The message content is a pointer to the exception's context (of type struct ExceptionContext, see exec/interrupts.h). If the hook returns 0, the exception processing continues as normal. If non-null, the excepting task is suspended for further inspection by the debugger. DBHMT_REMTASK: This message is sent when a task terminates (i.e. RemTask is called). The message does not have any content, and the return value of the hook is ignored. DBHMT_OPENLIB: This message is sent when a library or device is opened. The message content is a pointer to the newly opened library base. If the hook returns non-null, the task opening the library is suspened. Note: The library pointer might be NULL. DBHMT_CLOSELIB: This message is sent when a library or device is closed. The message content is a pointer to the library about to be closed. If the hook returns non-null, the task closing the library is supended. Note: The library pointer might be NULL. Tasks created by a task with a debugger hook set will automatically "inherit" the hook, i.e. if a task with a non-NULL debugger hook creates another task, the new task will have the same dbuggger hook set. This can be used to pass on the hook from the debugger to tasks created under the debugger's control. The debugger hook may be removed at any time by calling this function with a NULL hook pointer. Note that only one hook may be added to a task at any time. Setting a new hook removes the previous one. INPUTS task - The task to control by a debugger. hookFunc - A utility.library CallHookPkt compatible hook. The hook structure can be used across multiple tasks. RESULT A boolean value is returned. TRUE means the hook has been installed, while FALSE indicates an error. exec.library/debug/Disassemble68k exec.library/debug/Disassemble68k NAME Disassemble68k -- Disassembles a 68k opcode on a given address SYNOPSIS nextaddress = Disassemble68k(targetAddress, opcodeName, operands); ULONG Disassemble68k(APTR, STRPTR, STRPTR); FUNCTION This function disassembles a 68k opcode on a given address, returns the string representation of the opcode and operands and the next address after the opcode. INPUTS targetAddress - address of the targeted opcode opcodeName - pointer to string buffer which is at least LEN_DISASSEMBLE_OPCODE_STRING in size to receive the disassembled opcode name operands - pointer to string buffer which is at least LEN_DISASSEMBLE_OPERANDS_STRING in size to receive the disassembled opcode operands RESULT Returns the address right after the disassembled opcode. NOTE LEN_DISASSEMBLE_OPCODE_STRING and LEN_DISASSEMBLE_OPERANDS_STRING constants were added in V53.44. exec.library/debug/DisassembleNative exec.library/debug/DisassembleNative NAME DisassembleNative -- Disassembles a native opcode on a given address SYNOPSIS nextaddress = DisassembleNative(targetAddress, opcodeName, operands); ULONG DisassembleNative(APTR, STRPTR, STRPTR); FUNCTION This function disassembles a native opcode on a given address, returns the string representation of the opcode and operands and the next address after the opcode. INPUTS targetAddress - address of the targeted opcode opcodeName - pointer to string buffer which is at least LEN_DISASSEMBLE_OPCODE_STRING in size to receive the disassembled opcode name operands - pointer to string buffer which is at least LEN_DISASSEMBLE_OPERANDS_STRING in size to receive the disassembled opcode operands RESULT Returns the address right after the disassembled opcode. NOTE LEN_DISASSEMBLE_OPCODE_STRING and LEN_DISASSEMBLE_OPERANDS_STRING constants were added in V53.44. exec.library/debug/GetDebugLevel exec.library/debug/GetDebugLevel NAME GetDebugLevel -- Retreive the kernel's current debug level SYNOPSIS uint32 GetDebugLevel(void); FUNCTION The function returns the currently set kernel debug level. The debug level can be set in the kernel command line with the keyword "debuglevel=". Debug levels range between 0 to 20 (higher levels are possible, but will produce too much output), with 0 being no debug, 5 moderate output (all warnings are 5 or lower), 10 being lots of output, and 15 being an insane amount of output (fault conditions from kernel functions are displayed), and 20 being a ludicrous amount of output (entry and exit to functions will be logged). RESULT The current kernel debug level. exec.library/debug/IsIn68kEmulator exec.library/debug/IsIn68kEmulator NAME IsIn68kEmulator -- Is the Task in the 68k emulator. (V53.59) SYNOPSIS BOOL IsIn68kEmulator(const struct Task *task); FUNCTION This function determines whether the Task is executing inside the 68k emulator not. It must only be used on a Task that has been suspended or crashed. INPUTS task -- Pointer to struct Task. Passing NULL is safe and returns FALSE. RESULT Returns TRUE if the instruction pointer is in the emulator or FALSE if not. SEE ALSO Disassemble68k() exec.library/debug/ObtainDebugSymbol exec.library/debug/ObtainDebugSymbol NAME ObtainDebugSymbol -- Obtain debug symbol from memory address. (V53.41) SYNOPSIS struct DebugSymbol *symbol = ObtainDebugSymbol(CONST_APTR address, struct TagItem *tagList); struct DebugSymbol *symbol = ObtainDebugSymbolTags(CONST_APTR address, Tag tag1, ...); FUNCTION This function will attempt to obtain debug symbol information when provided with a tracked memory address. Tracked memory addresses are registered via IDOS->TrackAddressList() or IDOS->TrackSegmentList(). The debug symbol information obtained has many optional fields and the structure looks like the following: struct DebugSymbol { uint32 StructSize; uint32 Type; CONST_STRPTR Name; uint32 Offset; uint32 SegmentNumber; uint32 SegmentOffset; CONST_STRPTR SourceFileName; uint32 SourceLineNumber; CONST_STRPTR SourceFunctionName; CONST_STRPTR SourceBaseName; } The structure members have the following meanings: StructSize Size of this data structure in bytes. This may continue to grow in future releases as new members are added at the end of the structure. Type The Type field indicates which of the following types of debug symbols has been found at the provided memory address: DEBUG_SYMBOL_68K_MODULE -- 68K kernel module DEBUG_SYMBOL_NATIVE_MODULE -- Kernel data module DEBUG_SYMBOL_KERNEL_MODULE -- Kernel module DEBUG_SYMBOL_MODULE -- Module DEBUG_SYMBOL_MODULE_STABS -- Module with stabs debug Name The module name or NULL if not available. The name may include file path information as well. Offset Number of bytes which precede the address. The offset is not used (set to zero) for DEBUG_SYMBOL_KERNEL_MODULE and DEBUG_SYMBOL_MODULE types. SegmentNumber If this address range consists of multiple entries, this is the number of the entry which contains the address. For a 68K hunk segment list, this would be the 'hunk number'. (Starting at 0) The segment number is available for DEBUG_SYMBOL_MODULE and DEBUG_SYMBOL_MODULE_STABS types only. SegmentOffset Number of bytes which precede the address. The offset is available for DEBUG_SYMBOL_MODULE and DEBUG_SYMBOL_MODULE_STABS types only. The following fields are only available for DEBUG_SYMBOL_MODULE_STABS types. Such modules are compiled with stabs debugging information (-gstabs option of GCC). SourceFileName Source code file name containing the address or NULL if not available. SourceLineNumber Source code line number containing the address or zero if not available. SourceFunctionName Source code function name containing the address or NULL if not available. SourceBaseName Source module base name containing the address or NULL if not available. When finished with the debug symbol it must be freed using the ReleaseDebugSymbol() function. INPUTS address -- The memory address to obtain debug symbol information for. tagList -- A struct TagItem array of options. (May be NULL) TAGS No tags are currently defined. RESULT symbol -- Pointer to a struct DebugSymbol or NULL if not found. NOTES This function re-opens the associated Elf handle when obtaining debug symbol information. If the GrimReaper or some other debugging tool is activated while this function is being called there could be a conflict which results in one of the tools closing the associated file handle twice. DOS will warn the user if this situation arrises. SEE ALSO ReleaseDebugSymbol, StackTrace exec.library/debug/ReadTaskContext exec.library/debug/ReadTaskContext NAME ReadTaskContext -- Extract information from a task's context (V53.25) SYNOPSIS uint32 ReadTaskContext(struct Task *targetTask, struct ExceptionContext *contextStorage, uint32 flags); FUNCTION ReadTaskContext extracts information (depending on the given flags) from a task's context and copies it into the storage pointed to by contextStorage. The flags parameter can be used to only copy some information (like, only general purpose registers) for efficiency. INPUT targetTask - The task to read from. This can be any task or process, although you have to make sure the task is still valid while the access is made and will remain valid until the function finishes. contextStorage - A client-provided storage that will be filled with appropriate information from the targetTask's context (usually a pointer to a struct ExceptionContext) flags - a flag word indicating what is copied from the targetTask's context. Valid flags are: RTCF_INFO Copy informational fields (Flags, Traptype) RTCF_SPECIAL Copy only the special registers (cr, xer, ctr, lr, dsisr, dar) RTCF_STATE Copy vital state registers (msr, ip) RTCF_GENERAL Copy general purpose registers (r0-r31) RTCF_FPU Copy registers related to FPU (fpscr, f0-f31) RTCF_VECTOR Copy registers related to vector units (vscr, vrsave, v0-v31) Combinations are possible by or'ing certain flags, for example, to read a task's special registers and general purpose registers, pass RTCF_SPECIAL|RTCF_GENERAL as flags. Note that some fields in the context are dependent on whether the task had an exception, and the type of exception (dsisr and dar are only set correctly on DSI exceptions). The function will copy those, even though they might not be valid. RESULT The number of bytes copied is returned SEE ALSO WriteTaskContext exec.library/debug/ReleaseDebugSymbol exec.library/debug/ReleaseDebugSymbol NAME ReleaseDebugSymbol -- Release debug symbol resources. (V53.41) SYNOPSIS void ReleaseDebugSymbol(struct DebugSymbol *symbol); FUNCTION This function frees all the resources allocated by the ObtainDebugSymbol() function. INPUTS symbol -- Pointer to struct DebugSymbol. Passing NULL does nothing. SEE ALSO ObtainDebugSymbol exec.library/debug/StackTrace exec.library/debug/StackTrace NAME StackTrace -- Trace a task's stack (V53.41) SYNOPSIS uint32 StackTrace(struct Task *task, struct Hook *hook); FUNCTION This function will scan through the stack of a task and invoke the hook function for each address encountered or until the scanning is discontinued intentionally. The task being traced must remain valid while its stack is being scanned. Use SuspendTask() and RestartTask() for this purpose. INPUTS task -- The task to read from. This can be any task or process although you must be sure the task is still valid while its stack is being traced. hook -- Pointer to a struct hook. The hook function will be called for every stack frame. You must initialise the hook struct h_Entry field to the function address to call before invoking this routine. The hook should have the following prototype: int32 hookFunc(struct Hook *hook, struct Task *task, struct StackFrameMsg *msg); The hook will be called as follows: result = hook_function(hook, task, msg) The task argument is a pointer to the task. The msg argument is the following structure: struct StackFrameMsg { uint32 StructSize; uint32 State; CONST_APTR MemoryAddress; const uint32 *StackPointer; } The structure members have the following meanings: StructSize Size of this data structure in bytes. This may continue to grow in future releases as new members are added at the end of the structure. State The State field must always be checked first and may may be any of the following values: STACK_FRAME_DECODED Decoded stack frame STACK_FRAME_INVALID_BACKCHAIN_PTR Invalid backchain pointer STACK_FRAME_TRASHED_MEMORY_LOOP Memory loop caused by trashed memory STACK_FRAME_BACKCHAIN_PTR_LOOP Backchain pointer loops MemoryAddress Address of the memory location on the stack. Optional debug information may be obtained by calling ObtainDebugSymbol() on this address. StackPointer The value of the stack pointer. If your hook function returns 0, the trace will continue. If your hook function returns a non-zero value, this indicates that the trace should be aborted (e.g. when the item in question has been found and the result extracted). This non-zero return value will also be passed on and returned as the result of the StackTrace() function. RESULT result -- Zero indicates that you never returned a non-zero result from your hook before you ran out of stack to trace. -- A -1 value indicates the stack trace failed to begin and your hook function was never called. -- All other values indicate success and will actually be the value that you returned from your hook function. EXAMPLE Scan the stack of the "Workbench" process. struct Task *task = IExec->FindTask("Workbench"); if (task != NULL) { struct Hook *hook = IExec->AllocSysObject(ASOT_HOOK, ASOHOOK_Entry, printStack, TAG_END); if (hook != NULL) { IExec->SuspendTask(task, 0); uint32 result = IDebug->StackTrace(task, hook); IExec->RestartTask(task, 0); IExec->FreeSysObject(ASOT_HOOK, hook); } } This is your hook function which will be called for each stack frame. Always check the State field before processing any stack frame. int32 printStack(struct Hook *hook, struct Task *task, struct StackFrameMsg *frame) { switch (frame->State) { case STACK_FRAME_DECODED: IDOS->Printf("(%p) -> %p\n", frame->StackPointer, frame->MemoryAddress); break; case STACK_FRAME_INVALID_BACKCHAIN_PTR: IDOS->Printf("(%p) invalid backchain pointer\n", frame->StackPointer); break; case STACK_FRAME_TRASHED_MEMORY_LOOP: IDOS->Printf("(%p) trashed memory loop\n", frame->StackPointer); break; case STACK_FRAME_BACKCHAIN_PTR_LOOP: IDOS->Printf("(%p) backchain pointer loop\n", frame->StackPointer); break; default: IDOS->Printf("Unknown state=%lu\n", frame->State); } return 0; // Continue tracing. } SEE ALSO SuspendTask, RestartTask, ObtainDebugSymbol exec.library/debug/WriteTaskContext exec.library/debug/WriteTaskContext NAME WriteTaskContext -- Modify an existing task context (V53.25) SYNOPSIS uint32 WriteTaskContext(struct Task *targetTask, struct ExceptionContext *contextStorage, uint32 flags); FUNCTION WriteTaskContext is used to modify an existing task's context by overwriting parts of the context with information provided by the client. INPUT targetTask - The task to write to. This can be any task or process, although you have to make sure the task is still valid while the access is made and will remain valid until the function finishes. contextStorage - Pointer to a (partially) filled ExceptionContext. Data from this context will overwrite parts of the targetTask's context subject to flags given in flags. flags - a flag word indicating what is copied Valid flags are: RTCF_SPECIAL Copy only the special registers (cr, xer, ctr, lr, dsisr, dar) RTCF_STATE Copy vital state registers (msr, ip) RTCF_GENERAL Copy general purpose registers (r0-r31) RTCF_FPU Copy registers related to FPU (fpscr, f0-f31) RTCF_VECTOR Copy registers related to vector units (vscr, vrsave, v0-v31) Combinations are possible by or'ing certain flags, for example, to read a task's special registers and general purpose registers, pass RTCF_SPECIAL|RTCF_GENERAL as flags. Note that some fields in the context are dependent on whether the task had an exception, and the type of exception (dsisr and dar are only set correctly on DSI exceptions). The function will copy those, even though they might not be valid. RESULT The number of bytes copied is returned SEE ALSO ReadTaskContext exec.library/DebugPrintF exec.library/DebugPrintF NAME DebugPrintF -- output a string to the debug console (V50) SYNOPSIS DebugPrintF(format, ...); VOID DebugPrintF(STRPTR, ...); FUNCTION Outputs a string to the debug log, which can be either a serial terminal, a debug screen, a file on disk, or any other device that is currently active. INPUTS format - A format string containing standard printf()-style formatting rules. NOTES Depending on the speed of the output device, this call may take considerable time to complete. Take this into account when using from an interrupt. BUGS SEE ALSO C library/printf exec.library/DeleteInterface exec.library/DeleteInterface NAME DeleteInterface -- Delete an interface SYNOPSIS DeleteInterface(interface); void DeleteInterface(interface); FUNCTION This function deletes an interface created with MakeInterface. It is called internally by DeleteLibrary and should not be called by Applications. Use DropInterface or interface->Release to get rid of interfaces acquired with GetInterface of interface->Obtain. INPUTS interface - interface to be deleted. NOTES This is an internal function and generally not useful for applications. Library implementation may call this in Expunge operations if the interface was cloned with MakeInterface. Do NOT call this on an interface that's still in use, or still part of a library. SEE ALSO MakeInterface exec.library/DeleteIORequest exec.library/DeleteIORequest NAME DeleteIORequest() - Free a request made by CreateIORequest() (V36) SYNOPSIS DeleteIORequest( ioReq ); void DeleteIORequest(struct IORequest *); FUNCTION Frees up an IO request as allocated by CreateIORequest(). INPUTS ioReq - A pointer to the IORequest block to be freed, or NULL. This function uses the mn_Length field to determine how much memory to free. SEE ALSO CreateIORequest(), amiga.lib/DeleteExtIO() exec.library/DeleteLibrary exec.library/DeleteLibrary NAME DeleteLibrary -- Free up library resources SYNOPSIS DeleteLibrary(library); void DeleteLibrary(struct Library *); FUNCTION This function deletes all resources allocated in CreateLibrary. It will also delete all interfaces in the library's interface list. Note that the library must not be in use anymore, nor available to the public (i.e. it must have been RemLibrary'd from the system list). This function will only delete memory allocated by CreateLibrary and the interfaces, nothing more. It should be called as one of the last measures in the library expunge code. INPUTS library - pointer to the library to be deleted SEE ALSO CreateLibrary, RemLibrary exec.library/DeleteMsgPort exec.library/DeleteMsgPort NAME DeleteMsgPort - Free a message port created by CreateMsgPort (V36) SYNOPSIS DeleteMsgPort(msgPort) void DeleteMsgPort(struct MsgPort *); FUNCTION Frees a message port created by CreateMsgPort(). All messages that may have been attached to this port must have already been replied to. INPUTS msgPort - A message port. NULL for no action. SEE ALSO CreateMsgPort(), amiga.lib/DeletePort() exec.library/DeletePool exec.library/DeletePool NAME DeletePool -- Drain an entire memory pool (V39) SYNOPSIS DeletePool(poolHeader) void DeletePool(void *); FUNCTION Frees all memory in all pudles of the specified pool header, then deletes the pool header. Individual free calls are not needed. INPUTS poolHeader - as returned by CreatePool(). SEE ALSO CreatePool(), AllocPooled(), FreePooled(), AllocVecPooled(), FreeVecPooled() exec.library/DeletePort exec.library/DeletePort NAME DeletePort - Free a message port created by CreatePort (V50) SYNOPSIS DeletePort(msgPort) void DeletePort(struct MsgPort *); FUNCTION Frees a message port created by CreatePort(). All messages that may have been attached to this port must have already been replied to. If the port was public, it's removed with RemPort. INPUTS msgPort - A message port. NULL for no action. SEE ALSO CreatePort() exec.library/DeleteTask exec.library/DeleteTask NAME DeleteTask -- delete a task created with CreateTask() (V50) SYNOPSIS DeleteTask(task) VOID DeleteTask(struct Task *); FUNCTION This function simply calls exec.library/RemTask(), deleting a task from the Exec task lists and automatically freeing any stack and structure memory allocated for it by CreateTask(). Before deleting a task, you must first make sure that the task is not currently executing any system code which might try to signal the task after it is gone. This can be accomplished by stopping all sources that might reference the doomed task, then causing the subtask to execute a Wait(0L). Another option is to have the task call DeleteTask()/RemTask() on itself. INPUTS task - task to remove from the system NOTE This function replaces amiga.lib/DeleteTask() SEE ALSO CreateTask(), exec.library/RemTask() exec.library/DeleteTrackable exec.library/DeleteTrackable NAME DeleteTrackable -- Free up object and trackable structure (V50) SYNOPSIS DeleteTrackable(trackable); void DeleteTrackable(struct Trackable *trackable); FUNCTION This function deletes the tracked object by calling the destructor and disposing of the control structure. INPUTS trackable - The trackable object to be deleted. NOTES This function is manly used internally by the system, and is probably of no use for application programmers. SEE ALSO FindTrackable, RemTrackable, FindTrackable, AllocSysObject exec.library/Dellocate exec.library/Dellocate NAME Deallocate -- deallocate a block of memory SYNOPSIS Deallocate(memHeader, memoryBlock, byteSize) void Deallocate(struct MemHeader *,APTR,ULONG); FUNCTION This function deallocates memory by returning it to the appropriate private free memory pool. This function can be used to free an entire block allocated with the above function. If memoryBlock is not on a block boundary (MEM_BLOCKSIZE) then it will be rounded down in a manner compatible with Allocate(). Note that this will work correctly with all the memory allocation functions, but may cause surprises if one is freeing only part of a region. The size of the block will be rounded up, so the freed block will fill to an even memory block boundary. INPUTS memHeader - points to the memory header this block is part of. memoryBlock - address of memory block to free. byteSize - the size of the block in bytes. If NULL, nothing happens. NOTES Alternatively, Deallocate can be used to free a sub-block of a previously allocated block. Sub-blocks must be an even multiple of the memory chunk size (currently 8 bytes). This function can even be used to add a new free region to an existing MemHeader, however the extent pointers in the MemHeader will no longer be valid. However, this might not be supported in future versions of the memory system, so use of this feature is discouraged, and only present for backwards compatibility. SEE ALSO Allocate, exec/memory.h exec.library/Disable exec.library/Disable NAME Disable -- disable interrupt processing. SYNOPSIS Disable(); void Disable(void); FUNCTION Prevents interrupts from being handled by the system, until a matching Enable() is executed. Disable() implies Forbid(). DO NOT USE THIS CALL WITHOUT GOOD JUSTIFICATION. THIS CALL IS VERY DANGEROUS! RESULTS All interrupt processing is deferred until the task executing makes a call to Enable() or is placed in a wait state. Normal task rescheduling does not occur while interrupts are disabled. In order to restore normal interrupt processing, the programmer must execute exactly one call to Enable() for every call to Disable(). IMPORTANT REMINDER: It is important to remember that there is a danger in using disabled sections. Disabling interrupts for more than ~250 microseconds will prevent vital system functions (especially serial I/0) from operating in a normal fashion. Think twice before using Disable(), then think once more. After all that, think again. With enough thought, the need for a Disable() can often be eliminated. For the user of many device drivers, a write to disable *only* the particular interrupt of interest can replace a Disable(). For example: MOVE.W #INTF_PORTS,_intena Do not use a macro for Disable(), insist on the real thing. This call may be made from interrupts, it will have the effect of locking out all higher-level interrupts (lower-level interrupts are automatically disabled by the CPU). Note: In the event of a task entering a Wait() after disabling interrupts, the system "breaks" the disabled state and runs normally until the task which called Disable() is rescheduled. NOTE This call is guaranteed to preserve all registers. SEE ALSO Forbid, Permit, Enable exec.library/DoIO exec.library/DoIO NAME DoIO -- perform an I/O command and wait for completion SYNOPSIS error = DoIO(iORequest) BYTE DoIO(struct IORequest *); FUNCTION This function requests a device driver to perform the I/O command specified in the I/O request. This function will always wait until the I/O request is fully complete. DoIO() handles all the details, including Quick I/O, waiting for the request, and removing the reply message, etc.. NOTE This function first tries to complete the IO via the "Quick I/O" mechanism. The IORequest->io_Flags field is always set to IOF_QUICK (0x01) before the internal device call. Some device drivers require that certain bits in io_Flags are set for proper operations and will not work correctly if an IORequest is used with DoIO() because it sets io_Flags to IOF_QUICK before the request is sent. The audio.device is such a kind of device driver. For such device drivers BeginIO() and WaitIO() must be used in place of DoIO(). The IORequest->io_Message.mn_Node.ln_Type field is used internally to flag I/O completion. Active requests have type NT_MESSAGE. IORequests that have been completed, and thus replied, have type NT_REPLYMSG. It is illegal to start I/O using a still active IORequest, or a request with type NT_REPLYMSG. You must not call DoIO() on an IORequest that has never been successfully used with OpenDevice() and that is not a duplicate of an IORequest which was successfully used with OpenDevice(). If you use it on an IORequest that was just created with CreateIORequest() or which was just used with the CloseDevice() function, you will either cause your task to hang, or you may crash the operating system. INPUTS iORequest - pointer to an IORequest initialized by OpenDevice() RESULTS error - a sign-extended copy of the io_Error field of the IORequest. Most device commands require that the error return be checked. SEE ALSO SendIO(), CheckIO(), WaitIO(), AbortIO(), BeginIO() exec.library/DropInterface exec.library/DropInterface NAME DropInterface -- Release an interface from use (V50) SYNOPSIS DropInterface(interface); void DropInterface(struct Interface *); FUNCTION Release an interface that was obtained with GetInterface. You may not use the interface anymore after DropInterface, as you don't have any guarantee that the interface will actually remain active or in memory. DropInterface also automatically calls Release() on the interface. Cloned interfaces (IFLF_CLONED) will also have their Expunge() vector called if the reference count has reached zero and the IFLF_CLONE_EXPUNGE flag is set. (V53.31) INPUTS interface - The interface to drop. It is safe to pass a NULL pointer here. NOTES This function complements GetInterface. If you have aquired the interface with the interface method Obtain(), you must release it by calling the interface method Release(). SEE ALSO GetInterface exec.library/Emulate exec.library/Emulate NAME Emulate -- Run classic 68k Code through emulation (V50) SYNOPSIS result = Emulate(initPC, taglist); ULONG Emulate(APTR, struct TagItem *); result = EmulateTags( initPC, ... ); ULONG EmulateTags(APTR, ... ); FUNCTION Run a piece of classic 68k code through one of the integrated 68k emulators. The system will pick the most appropriate/ available emulator (either the interpreter or the JIT emulator) unless specifically told not to run through the JIT compiler. The code is run via a "jsr" instruction, and continues to run until the matching 'rts' instruction is encountered. The initial mapping of the registers is obtained through the tag list. Any register specified is loaded with the value passed in the tag list, leaving any register not listed undefined. Floating point registers cannot be passed via the tag list because of the restriction to 32 bits. Therefore, floating point registers must be passed via a memory based structure. INPUTS InitPC - the code address of the first 68k instruction to be executed taglist - a tag list which describes the initial contents of the registers. All tag items are optional. Currently, the following tag items are available: ET_RegisterD0 ER_RegisterD1 ... ET_RegisterA0 ... ET_RegisterA6 Specifies the initial contents of the 68k data and address registers. Note that register A7 will automatically be loaded with the current stack pointer. ET_FPRegisters ET_FPRegisterMask Since passing 64 bit values via the tag list is not possible, the ET_FPRegisters tag item should point to an array of double values in memory that contains the initial values for some or all 68k floating point registers. These values are written to the register FP0 - FP7 based on the bit mask passed in via ET_FPRegisterMask. For each bit set in the mask, a single value is read from the array. Flags are checked in ascending order from EFPF_FP0 to EFPF_FP7. The number of doubles in the array must be greater or equal to the number of bits in the mask. See the example for more info. ET_SuperState A boolean flag that, if set to true, executes the code with supervisor privilege, identical to calling IExec::Supervisor. If set to false, supervisor state will be explicitly disabled. If unspecified, supervisor state will be unaffected. Default: FALSE ET_StackPtr Specifies the initial stack pointer for the 68k code. If this tag is unspecified, the normal task stack is used. Note: The original stack will be restored when returning from this function. Default: Not specified, use current stack ET_Offset The value of this flag is added to the InitPC, and the result is used as an entry point into the emulated code. This tag is useful for emulating old-style libraries: Pass the library base as InitPC, and ET_Offset with the offset of the appropriate function. Default: 0 ET_SaveRegs If TRUE, save d2-d7/a2-a6, and restore them before returning from this function. This corresponds to storing all non-volatile registers. Note: This tag is mutually exclusive to ET_SaveParamRegs, and supersedes the latter. Default: FALSE ET_SaveParamRegs If TRUE, registers that hold parameters are stored before emulating the function code, and restored to their original values afterwards. Note: - This only affects registers that are considered non-volatile in the 68k's calling convention, i.e. d2-d7 and a2-a6. - This tag is mutually exclusive to ET_SaveRegs, and superseded by the latter. Default: FALSE. Note that the use of this flag is advisable in native code that might be called from emulated code. RESULT result - the value of D0 after execution of the function. EXAMPLE This example calls a 68k function, passing a value in D0 and two values in FP0 and FP5: extern APTR 68kfunc; double fp_regs[2] = {3.1415, 1.2345}; ULONG result = EmulateTags(68kfunc, ET_RegisterD0, 0x12345678, ET_FPRegisters, fp_regs, ET_FPRegisterMask, EFPF_FP0|EFPF_FP5, TAG_DONE); BUGS Passing of floating parameters is currently not implemented. SEE ALSO exec.library/Enable exec.library/Enable NAME Enable -- permit system interrupts to resume. SYNOPSIS Enable(); void Enable(void); FUNCTION Allow system interrupts to again occur normally, after a matching Disable() has been executed. RESULT Interrupt processing is restored to normal operation. The programmer must execute exactly one call to Enable() for every call to Disable(). NOTES This call is guaranteed to preserve all registers. SEE ALSO Forbid, Permit, Disable exec.library/EndDMA exec.library/EndDMA NAME EndDMA -- End hardware DMA access (V50) SYNOPSIS EndDMA(startAddr, blockSize, flags); void EndDMA(APTR, ULONG, ULONG); FUNCTION This function reverts the measures taken with StartDMA. See the AutoDoc for StartDMA for a description of the new DMA system. INPUTS startAddr - Virtual start address of the block where DMA took place This *must* be the same value that was passed to StartDMA. blockSize - Size of the block. This *must* be the same value that was passed to StartDMA. flags - Various flags. These must at least contain the flags given to StartDMA. Currently, the following flags are defined: DMAF_ReadFromRAM - Initiate a DMA operation that will be a read access, i.e. the data flow will go from RAM to the DMA device. DMAF_NoModify - Indicates that the DMA operation didn't modify the region. This can be used to enhance performance after aborting a DMA transfer. NOTE Every _succesful_ call to StartDMA *must* be paired with a call to EndDMA with the same address and size. Additionally, all flags given to StartDMA must also be given to EndDMA. SEE ALSO StartDMA, GetDMAList, CachePreDMA, CachePostDMA exec.library/Enqueue exec.library/Enqueue NAME Enqueue -- insert or append node to a system queue SYNOPSIS Enqueue(list, node) void Enqueue(struct List *, struct Node *); FUNCTION Insert or append a node into a system queue. The insert is performed based on the node priority -- it will keep the list properly sorted. New nodes will be inserted in front of the first node with a lower priority. Hence a FIFO queue for nodes of equal priority WARNING This function does not arbitrate for access to the list. The calling task must be the owner of the involved list. INPUTS list - a pointer to the system queue header node - the node to enqueue. This must be a full featured node with type, priority and name fields. SEE ALSO AddHead, AddTail, Insert, Remove, RemHead, RemTail exec.library/FindIName exec.library/FindIName NAME FindIName -- find a list node by name case insensitive (V50) SYNOPSIS node = FindIName(start, name) struct Node *FindIName(struct List *, STRPTR); FUNCTION Traverse a system list until a node with the given name is found. Names are compared without considering the case. To find multiple occurrences of a string, this function may be called with a node starting point. No arbitration is done for access to the list! If multiple tasks access the same list, an arbitration mechanism such as SignalSemaphores must be used. INPUTS start - a list header or a list node to start the search (if node, this one is skipped) name - a pointer to a name string terminated with NULL RESULTS node - a pointer to the node with the same name else zero to indicate that the string was not found. exec.library/FindName exec.library/FindName NAME FindName -- find a system list node with a given name SYNOPSIS node = FindName(start, name) struct Node *FindName(struct List *, STRPTR); FUNCTION Traverse a system list until a node with the given name is found. To find multiple occurrences of a string, this function may be called with a node starting point. No arbitration is done for access to the list! If multiple tasks access the same list, an arbitration mechanism such as SignalSemaphores must be used. INPUTS start - a list header or a list node to start the search (if node, this one is skipped) name - a pointer to a name string terminated with NULL RESULTS node - a pointer to the node with the same name else zero to indicate that the string was not found. exec.library/FindNamedMemory exec.library/FindNamedMemory NAME FindNamedMemory -- Search for a named memory block (V51) SYNOPSIS void *FindNamedMemory(STRPTR space, STRPTR name); FUNCTION This function will search through the named memory blocks known in the namespace given by space and return a pointer to the block if it exists. INPUTS space - Namespace to search name - Name to search for RESULT A pointer to a block with name previously allocated by AllocNamedMemory, or NULL if no such block exists. NOTES For an example, see AllocNamedMemory. SEE ALSO AllocNamedMemory, FreeNamedMemory, UpdateNamedMemory exec.library/FindPort exec.library/FindPort NAME FindPort -- find a given system message port SYNOPSIS port = FindPort(name) struct MsgPort *FindPort(STRPTR); FUNCTION This function will search the system message port list for a port with the given name. The first port matching this name will be returned. No arbitration of the port list is done. This function MUST be protected with A Forbid()/Permit() pair! EXAMPLE /* Pre V50 */ #include struct MsgPort *FindPort(); ULONG SafePutToPort(message, portname) struct Message *message; STRPTR portname; { struct MsgPort *port; Forbid(); port = FindPort(portname); if (port) PutMsg(port,message); Permit(); return((ULONG)port); /* If zero, the port has gone away */ } INPUT name - name of the port to find RETURN port - a pointer to the message port, or zero if not found. exec.library/FindResident exec.library/FindResident NAME FindResident - find a resident module by name SYNOPSIS resident = FindResident(name) struct Resident *FindResident(STRPTR); FUNCTION Search the system resident tag list for a resident tag ("ROMTag") with the given name. If found return a pointer to the resident tag structure, else return zero. Resident modules are used by the system to pull all its parts together at startup. Resident tags are also found in disk based devices and libraries. INPUTS name - pointer to name string RESULT resident - pointer to the resident tag structure or zero if none found. SEE ALSO exec/resident.h, InitResident exec.library/FindSemaphore exec.library/FindSemaphore NAME FindSemaphore -- find a given system signal semaphore SYNOPSIS signalSemaphore = FindSemaphore(name) struct SignalSemaphore *FindSemaphore(STRPTR); FUNCTION This function will search the system signal semaphore list for a semaphore with the given name. The first semaphore matching this name will be returned. This function does not arbitrate for access to the semaphore list, surround the call with a Forbid()/Permit() pair. INPUT name - name of the semaphore to find RESULT semaphore - a pointer to the signal semaphore, or zero if not found. exec.library/FindTask exec.library/FindTask NAME FindTask -- find a task with the given name or find oneself SYNOPSIS task = FindTask(name) struct Task *FindTask(STRPTR); FUNCTION This function will check all task queues for a task with the given name, and return a pointer to its task control block. If a NULL name pointer is given a pointer to the current task will be returned. Finding oneself with a NULL for the name is very quick. Finding a task by name is very system expensive, and will disable interrupts for a long time. Since a task may remove itself at any time, a Forbid()/Permit() pair may be needed to ensure the pointer returned by FindTask() is still valid when used. INPUTS name - pointer to a name string RESULT task - pointer to the task (or Process) exec.library/FindTrackable exec.library/FindTrackable NAME FindTrackable -- Find the trackable structure for an object (V50) SYNOPSIS trackable = FindTrackable(task, object); struct Trackable *FindTrackable(struct Task *, APTR); FUNCTION This function tries to locate the trackable strucutre for a given object within a given tasks's context. If the object is tracked by the task, the appropriate control structure is returned. INPUTS task - The task wich should be searched. object - The object to be found. It's safe to pass 0, in which case no search operation is done. RESULT The struct Trackable responsible for the object is returned, or 0 if the object is not currently tracked by the task. NOTES This function is manly used internally by the system, and is probably of no use for application programmers. SEE ALSO AddTrackable, RemTrackable, DeleteTrackable, AllocSysObject exec.library/Forbid exec.library/Forbid NAME Forbid -- forbid task rescheduling. SYNOPSIS Forbid() void Forbid(void); FUNCTION Prevents other tasks from being scheduled to run by the dispatcher, until a matching Permit() is executed, or this task is scheduled to Wait(). Interrupts are NOT disabled. DO NOT USE THIS CALL WITHOUT GOOD JUSTIFICATION. THIS CALL IS DANGEROUS! RESULTS The current task will not be rescheduled as long as it is ready to run. In the event that the current task enters a wait state, other tasks may be scheduled. Upon return from the wait state, the original task will continue to run without disturbing the Forbid(). Calls to Forbid() nest. In order to restore normal task rescheduling, the programmer must execute exactly one call to Permit() for every call to Forbid(). WARNING In the event of a task entering a Wait() after a Forbid(), the system "breaks" the forbidden state and runs normally until the task which called Forbid() is rescheduled. If caution is not taken, this can cause subtle bugs, since any device or DOS call will (in effect) cause your task to wait. Forbid() is not useful or safe from within interrupt code (All interrupts are always higher priority than tasks, and interrupts are allowed to break a Forbid()). NOTE This call is guaranteed to preserve all registers. SEE ALSO Permit, Disable, ObtainSemaphore, ObtainSemaphoreShared exec.library/FreeEntry exec.library/FreeEntry NAME FreeEntry -- free many regions of memory. SYNOPSIS FreeEntry(memList) void FreeEntry(struct MemList *); FUNCTION This function takes a memList structure (as returned by AllocEntry) and frees all the entries. INPUTS memList -- pointer to structure filled in with MemEntry structures EXAMPLE Free all the memory added to the current tasks memlist. VOID freeTaskMemEntries(void) { struct Task *me = IExec->FindTask(0); APTR memlist; while( (memlist = IExec->RemHead( &(task->tc_MemEntry) ))) { IExec->FreeEntry(memlist); } } SEE ALSO AllocTaskMemEntry(), exec/memory.h, AllocEntry()[obsolete] exec.library/FreeMem exec.library/FreeMem NAME FreeMem -- deallocate memory SYNOPSIS FreeMem(memoryBlock, byteSize) void FreeMem(void *,ULONG); FUNCTION Free a region of memory, returning it to the system pool from which it came. As of V50, freeing partial blocks back into the system pool is prohibited. NOTE If a block of memory is freed twice, the system will Guru. The Alert is AN_FreeTwice ($01000009). If you pass the wrong pointer, you will probably see AN_MemCorrupt $01000005. Future versions may add more sanity checks to the memory lists. INPUTS memoryBlock - pointer to the memory block to free byteSize - the size of the desired block in bytes. (The operating system will automatically round this number to a multiple of the system memory chunk size) SEE ALSO AllocMem exec.library/FreeNamedMemory exec.library/FreeNamedMemory NAME FreeNamedMemory -- Free a named memory object (V51) SYNOPSIS BOOL FreeNamedMemory(STRPTR space, STRPTR name); FUNCTION Free up the memory and other resources occupied by a memory block previously allocated via AllocNamedMemory. INPUTS space - Name space of the block to be freed. name - Name of the block to be freed. Passing NULL or a nonexistant name will have no effect. RESULT A boolean value is returned, indicating whether the operation was successful or not. NOTES For an example, see AllocNamedMemory. SEE ALSO AllocNamedMemory, FindNamedMemory, UpdateNamedMemory exec.library/FreePooled exec.library/FreePooled NAME FreePooled -- Free pooled memory (V39) SYNOPSIS FreePooled(poolHeader,memory,memSize) void FreePooled(void *,void *,ULONG); FUNCTION Deallocates memory allocated by AllocPooled(). The size of the allocation *MUST* match the size given to AllocPooled(). The reason the pool functions do not track individual allocation sizes is because many of the uses of pools have small allocation sizes and the tracking of the size would be a large overhead. Only memory allocated by AllocPooled() may be freed with this function! Doing a DeletePool() on the pool will free all of the puddles and thus all of the allocations done with AllocPooled() in that pool. (No need to FreePooled() each allocation) INPUTS memory - pointer to memory allocated by AllocPooled. poolHeader - a specific private pool header. NOTES The pool function do not protect an individual pool from multiple accesses. The reason is that in most cases the pools will be used by a single task. If your pool is going to be used by more than one task you must Semaphore protect the pool from having more than one task trying to allocate within the same pool at the same time. Warning: Forbid() protection *will not work* in the future. *Do NOT* assume that we will be able to make it work in the future. FreePooled() may well break a Forbid() and as such can only be protected by a semaphore. SEE ALSO AllocPooled(), CreatePool(), DeletePool(), AllocVecPooled(), FreeVecPooled() exec.library/FreeSignal exec.library/FreeSignal NAME FreeSignal -- free a signal bit SYNOPSIS FreeSignal(signalNum) void FreeSignal(BYTE); FUNCTION This function frees a previously allocated signal bit for reuse. This call must be performed while running in the same task in which the signal was allocated. WARNING Signals may not be allocated or freed from exception handling code. NOTE Starting with V37, an attempt to free signal -1 is harmless. INPUTS signalNum - the signal number to free {0..31}. exec.library/FreeSysObject exec.library/FreeSysObject NAME FreeSysObject -- Delete an object created with AllocSysObject (V50) SYNOPSIS FreeSysObject(type, object); void FreeSysObject(ULONG, APTR); FUNCTION This function will delete an object that has ben previously allocated with AllocSysObject. If the object is tracked by the current task, the tracking is removed. WARNING: Always call FreeSysObject in the same task where you called AllocSysObject in. INPUTS type - type of object to be freed (see exec/exectags.h for a list) object - Pointer to the object to be freed. If NULL, nothing happens. NOTES ALWAYS FREE YOUR RESOURCES!! Even though the resources will be tracked and deleted, this is *only* a method to get rid of the program's resources when the program crashes or exits unexpectedly. DO NOT RELY ON THIS MECHANISM. It might also not always work. SEE ALSO AllocSysObject exec.library/FreeTrap exec.library/FreeTrap NAME FreeTrap -- free a processor trap (Obsolete) SYNOPSIS FreeTrap(trapNum) void FreeTrap(ULONG); FUNCTION This function frees a previously allocated trap number for reuse. This call must be performed while running in the same task in which the trap was allocated. WARNING Traps may not be allocated or freed from exception handling code. INPUTS trapNum - the trap number to free {of 0..15} NOTES This function is obsolete from V50 upwards exec.library/FreeVec exec.library/FreeVec NAME FreeVec -- return AllocVec() memory to the system (V36) SYNOPSIS FreeVec(memoryBlock) void FreeVec(void *); FUNCTION Free an allocation made by the AllocVec() call. The memory will be returned to the system pool from which it came. NOTE If a block of memory is freed twice, the system will Guru. The Alert is AN_FreeTwice ($01000009). If you pass the wrong pointer, you will probably see AN_MemCorrupt $01000005. Future versions may add more sanity checks to the memory lists. INPUTS memoryBlock - pointer to the memory block to free, or NULL. SEE ALSO AllocVec exec.library/FreeVecPooled exec.library/FreeVecPooled NAME FreeVecPooled -- Free pooled memory allocated with AllocVecPooled (V50) SYNOPSIS FreeVecPooled(poolHeader,memory) void FreeVecPooled(void *,void *); FUNCTION Deallocates memory allocated by AllocVecPooled(). The function operates exactly like FreePooled(), but tracks the size. INPUTS memory - pointer to memory allocated by AllocPooled. poolHeader - a specific private pool header. NOTES The pool function do not protect an individual pool from multiple accesses. The reason is that in most cases the pools will be used by a single task. If your pool is going to be used by more than one task you must Semaphore protect the pool from having more than one task trying to allocate within the same pool at the same time. Warning: Forbid() protection *will not work* in the future. *Do NOT* assume that we will be able to make it work in the future. FreePooled() may well break a Forbid() and as such can only be protected by a semaphore. SEE ALSO AllocPooled(), CreatePool(), DeletePool(), AllocVecPooled(), FreePooled() exec.library/GetCC exec.library/GetCC NAME GetCC -- get condition codes in a 68010 compatible way. (Obsolete) SYNOPSIS conditions = GetCC() UWORD GetCC(void); FUNCTION The 68000 processor has a "MOVE SR," instruction which gets a copy of the processor condition codes. On the 68010,20 and 30 CPUs, "MOVE SR," is privileged. User code will trap if it is attempted. These processors need to use the "MOVE CCR," instruction instead. This function provides a means of obtaining the CPU condition codes in a manner that will make upgrades transparent. This function is VERY short and quick. RESULTS conditions - the 680XX condition codes NOTE This call is guaranteed to preserve all registers. This function may be implemented as code right in the jump table. From V50 on, this function is considered obsolete in native programs. It will always return 0, and alert. exec.library/GetCPUInfo exec.library/GetCPUInfo NAME GetCPUInfo -- Get information about the current CPU (V50) SYNOPSIS void GetCPUInfo(struct TagItem *tagList); void GetCPUInfoTags(ULONG tag1, ...); FUNCTION This function is used to retrieve information about the CPU(s) installed. This function replaces the ExecBase attention flag mechanism. INPUTS Input to this function is a tag list containing the items to be queried. Each tag item's data must point to a sufficiently large storage where the result is copied to. The list of tag items below lists the size of the required storage in brackets. For example, GCIT_NumberOfCPUs requires a pointer to an uint32, GCIT_ProcessorSpeed requires a pointer to a variable which is of type uint64. Currently, the following items are available: GCIT_NumberOfCPUs (uint32 *) Number of CPUs available in the system. This is likely to be 1 at the moment. GCIT_Family (uint32 *) CPU family as a symbolic constant. Currently, these are defined: CPUFAMILY_UNKNOWN - Unknown CPU CPUFAMILY_60X - All PowerPC 60x, like 603 and 604 CPUFAMILY_7X0 - All G3 PowerPC 7X0, like 740, 750, 750CXe, 750FX CPUFAMILY_74xx - All G4 PowerPC 74xx, like 7400, 7410, 7441 GCIT_Model (uint32 *) CPU model as a symbolic constant. Currently, these are defined: CPUTYPE_UNKNOWN - Unknown CPU CPUTYPE_PPC603E - PowerPC 603e CPUTYPE_PPC604E - PowerPC 604e CPUTYPE_PPC750CXE - PowerPC 750CXe CPUTYPE_PPC750FX - PowerPC 750FX CPUTYPE_PPC750GX - PowerPC 750GX CPUTYPE_PPC7410 - PowerPC 7410 CPUTYPE_PPC74XX_VGER - PowerPC 7440, 7441, 7450, 7451 (Vger types) CPUTYPE_PPC74XX_APOLLO - PowerPC 7445, 7447, 7455, 7457 (Apollo 6/7 types) GCIT_ModelString (CONST_STRPTR *) CPU model as a read-only string. For example, the 604e would be returned as "PowerPC 604e". GCIT_Version (uint32 *) CPU version and revision. The major and minor numbers are returned as a number with the lower 16 bit as 0xVV.R, where VV is the version number, and R is the revision. For example, on a PPC750FX DD2, the result would be 0x0201, depicting a PowerPC 750FX V2.1. Note: If a version is not available, the value returned is 0. GCIT_VersionString (CONST_STRPTR *) CPU version and revision as a read-only string, in the form "major.minor". GCIT_FrontsideSpeed (uint64 *) CPU frontside bus speed. Note: This is actually a 64 bit number. GCIT_ProcessorSpeed (uint64 *) CPU internal frequency. Note: This is actually a 64 bit number. GCIT_L1CacheSize (uint32 *) GCIT_L2CacheSize (uint32 *) GCIT_L3CacheSize (uint32 *) Size of the appropriate cache, if available, otherwise 0. GCIT_CacheLineSize (uint32 *) Size of a cache line. Note that this is also the alignment used by CacheClearE/CacheClearU. GCIT_VectorUnit (uint32 *) CPU's vector unit, as a symbolic constant. Currently defined are: VECTORTYPE_NONE - No vector unit VECTORTYPE_ALTIVEC - Motorola AltiVec (tm) Unit (VECTORTYPE_VMX - IBM VMX Unit) GCIT_Extensions (CONST_STRPTR *) CPU feature string. The result is a read-only string that describes nonstandard features of the CPU. GCIT_CPUPageSize (uint32 *) GCIT_ExecPageSize (uint32 *) Physical and logical page sizes. CPUPageSize determines the supported sizes of the CPU, while ExecPageSize determines the supported Exec (i.e. "virtual" page sizes).The latter is the size supported by Exec API functions. In general, these tags return a bit mask. If bit n is set, a page size of 2^n is supported. For example, GCIT_CPUPageSize might return 0x1000, i.e. bit 12 is set, hence the CPU supports hardware pages of 4096 bytes. GCIT_TimeBaseSpeed (uint64 *) Speed of the CPU timer. Note: This is actually a 64 bit number. EXAMPLE /* Query model and version */ CONST_STRPTR Model; CONST_STRPTR Version; IExec->GetCPUInfoTags( GCIT_ModelString, &Model, GCIT_VersionString, &Version, TAG_DONE); printf("CPU: %s V%s\n", Model, Version); exec.library/GetDMAList exec.library/GetDMAList NAME GetDMAList -- Retrieve information for DMA transfer (V50) SYNOPSIS GetDMAList(startAddr, blockSize, flags, dmaList); void GetDMAList(APTR, ULONG, ULONG, struct DMAEntry *); FUNCTION In Exec V50, addresses used by applications and real (physical) memory addresses might be different. Moreover, a block of linear virtual addresses might not be one single block in physical memory. Hardware that directly accesses memory will not see the same image of memory that the CPU will see. Therefore, DMA hardware needs information about the real layout of memory. This information is provided by the DMAEntry array: Each entry in the array is of type 'struct DMAEntry', and dsescribes a continous block of phyiscal memory: struct DMAEntry { APTR PhysicalAddress; ULONG BlockLength; } Entries are sorted with ascending virtual address. This means the first entry's PhysicalAddress is the address startAddr maps to. The second entry's PhysicalAddress field corresponds to startAddr+BlockLength of the previous entry, and so on. All BlockLengths in all entries add up to the blockSize parameter, therefore spanning the complete DMA area. This function retrieves the information necessary for a segmented DMA transfer into an array provided by the client. The size of the array is determined by the return value of a previous StartDMA call. The array must be allocated by the client with a size of at least sizeof(struct DMAEntry) multiplied by the return value of StartDMA (see exec.library/StartDMA for an example). INPUTS startAddr - Virtual start address of the block where DMA is to take place This *must* be the same value that was passed to StartDMA. blockSize - Size of the block. This *must* be the same value that was passed to StartDMA. flags - Various flags. These must at least contain the flags given to StartDMA. Currently, the following flags are defined: DMAF_ReadFromRAM - Initiate a DMA operation that will be a read access, i.e. the data flow will go from RAM to the DMA device. DMAF_NoModify - Indicates that the DMA operation didn't modify the region. This can be used to enhance performance after aborting a DMA transfer. dmaList - Pointer to an area of memory previously allocated. This memory area is filled with the DMAEntries, and must be large enough to take up all entries necessary. NOTE GetDMAList must not be called without a prior, corresponding StartDMA. It must also be called before calling EndDMA. However, it is safe not to call it at all if the DMA can't take place for some reason. SEE ALSO EndDMA, StartDMA, CachePreDMA, CachePostDMA exec.library/GetHead exec.library/GetHead NAME GetHead -- Obtain the first Node of a List (V51) SYNOPSIS first_node = GetHead(list) struct Node *GetHead(struct List *list) FUNCTION Obtain the first node of a list, or NULL if the list is empty. Only the node address is returned; other than RemHead() the node itself is not removed from the list INPUTS list - a pointer to the list whose first node should be retrieved; this can be NULL in which case this function will return NULL. WARNING This function does not arbitrate for access to the list. The calling task must be the owner of the involved list. RESULTS first_node -- The first node of the list or NULL. NOTES See the autodoc of GetSucc for an example on how to use there functions to traverse a list. EXAMPLE /* Traversing 'list' with GetHead/GetSucc only when * *NOT* removing any nodes. * Note when using these functions, don't check for * currentNode->ln_Succ, just check currentNode != NULL. */ struct Node *currentNode; for (currentNode = IExec->GetHead(list); currentNode != NULL; currentNode = IExec->GetSucc(currentNode) { /* Do something with currentNode (except removal) */ ... } /* If traversing 'list' with GetHead/GetSucc and nodes may at * some point be Remove()ed, it is not permitted to read any of * the node linkage fields after it has left the list, as removing * the node invalidates the list pointers, therefore, it is * necessary to determine the successor before removal. * Remember, when using these functions, don't check the * currentNode->ln_Succ, just for currentNode != NULL. */ struct Node *currentNode, *nextNode; for (currNode=IExec->GetHead(list); currentNode != NULL; currentNode = nextNode) { nextNode = IExec->GetSucc(currentNode); /* Do something with currentNode. */ /* This may include node removal from list. EG:- */ if( some_condition ) { IExec->Remove(currentNode); } } SEE ALSO GetTail, GetSucc, GetPred, Remove. exec.library/GetInterface exec.library/GetInterface NAME GetInterface -- Retrieve an interface from a library (V50) GetInterfaceTags -- Varargs version SYNOPSIS if = GetInterface(library, name, version, taglist); struct Interface *GetInterface(struct Library *, STRPTR, ULONG, struct TagItem *); if = GetInterfaceTags(library, name, version, tag1, ...); struct Interface *GetInterface(struct Library *, STRPTR, ULONG, Tag, ...); FUNCTION This function retrieves an interface from a library and returns a pointer to it. If the interface is part of the given library, and certain other conditions are fulfilled (see below), a pointer to the interface is returned and the interface is ready to be used. GetInterface will also automatically call Obtain on the interface. INPUTS library - Pointer to the library the interface belongs to name - Name of the interface (note that interface names, like all system lists, are case sensitive) version - Version of the interface to retrieve. Note that the version must match the interface version, otherwise GetInterface will fail. taglist - Pointer to a taglist with additional parameters. Note that you may pass a NULL pointer here, which is treated as an empty (TAG_DONE) taglist. Currently, the following tags are defined: GIT_FLAGS: Flags to match with the flags of the interface. If the given flags are not set in the interface, GetInterface will fail. RESULT A pointer to the fully initialized, and Obtain()'ed interface, or NULL if the interface retrieval failed. NOTES If an interface acquired with GetInterface is to be shared among several threads, or "users", the interface needs to be re-aquired by everyone using it by calling the interface method Obtain(), and likewise be released by calling Release(). Example: Main Program Thread 1 Thread 2 if = GetInterface(); // pass on to threads if->Obtain(); if->Obtain(); ... ... ... ... if->Release(); ... DropInterface(if); ... ... ... ... if->Release(); In this example, the main program aquires the interface through GetInterface, and disposes of it through DropInterface. Note, though, that the threads call Obtain and Release, respectively. This example also shows that the interface is only deleted *after* Thread 2 released it. This allows applications more freedom and less bookkeeping, as this is done by the interface itself. More information is available in the NDK. SEE ALSO OpenLibrary, DropInterface exec.library/GetMsg exec.library/GetMsg NAME GetMsg -- get next message from a message port SYNOPSIS message = GetMsg(port) struct Message *GetMsg(struct MsgPort *); FUNCTION This function receives a message from a given message port. It provides a fast, non-copying message receiving mechanism. The received message is removed from the message port. This function will not wait. If a message is not present this function will return zero. If a program must wait for a message, it can Wait() on the signal specified for the port or use the WaitPort() function. There can only be one task waiting for any given port. Getting a message does not imply to the sender that the message is free to be reused by the sender. When the receiver is finished with the message, it may ReplyMsg() it back to the sender. Getting a signal does NOT always imply a message is ready. More than one message may arrive per signal, and signals may show up without messages. Typically you must loop to GetMsg() until it returns zero, then Wait() or WaitPort(). INPUT port - a pointer to the receiver message port RESULT message - a pointer to the first message available. If there are no messages, return zero. Callers must be prepared for zero at any time. SEE ALSO PutMsg, ReplyMsg, WaitPort, Wait, exec/ports.h exec.library/GetPred exec.library/GetPred NAME GetPred -- Obtain the previous node of a list (V51) SYNOPSIS previous_node = GetPred(node) struct Node *GetPred(struct Node *node) FUNCTION Obtain the address of the node which preceeds a list node, or NULL if the list node is already the first in the list. INPUTS node - a pointer to the node whose predecessor (the previous node in the list) should be retrieved; this can be NULL in which case this function will return NULL. WARNING This function does not arbitrate for access to the list. The calling task must be the owner of the involved list. RESULTS previous_node -- The previous node of the list or NULL. SEE ALSO GetHead, GetTail, GetSucc exec.library/GetSucc exec.library/GetSucc NAME GetSucc -- Obtain the next node of a list (V51) SYNOPSIS next_node = GetSucc(node) struct Node *GetSucc(struct Node *node) FUNCTION Obtain the address of the node which follows a list node, or NULL if the list node is already the last in the list. INPUTS node - a pointer to the node whose successor (the next node in the list) should be retrieved; this can be NULL in which case this function will return NULL. WARNING This function does not arbitrate for access to the list. The calling task must be the owner of the involved list. RESULTS next_node -- The next node of the list or NULL. EXAMPLE /* Traversing 'list' with GetHead/GetSucc only when * *NOT* removing any nodes. * Note when using these functions, don't check for * currentNode->ln_Succ, just check currentNode != NULL. */ struct Node *currentNode; for (currentNode = IExec->GetHead(list); currentNode != NULL; currentNode = IExec->GetSucc(currentNode) { /* Do something with currentNode (except removal) */ ... } /* If traversing 'list' with GetHead/GetSucc and nodes may at * some point be Remove()ed, it is not permitted to read any of * the node linkage fields after it has left the list, as removing * the node invalidates the list pointers, therefore, it is * necessary to determine the successor before removal. * Remember, when using these functions, don't check the * currentNode->ln_Succ, just for currentNode != NULL. */ struct Node *currentNode, *nextNode; for (currNode=IExec->GetHead(list); currentNode != NULL; currentNode = nextNode) { nextNode = IExec->GetSucc(currentNode); /* Do something with currentNode. */ /* This may include node removal from list. EG:- */ if( some_condition ) { IExec->Remove(currentNode); } } SEE ALSO GetHead, GetTail, GetPred, Remove. exec.library/GetTail exec.library/GetTail NAME GetTail -- Obtain the last Node of a List (V51) SYNOPSIS last_node = GetTail(list) struct Node *GetTail(struct List *list) FUNCTION Obtain the last node of a list, or NULL if the list is empty. Only the node address is returned; other than RemTail() the node itself is not removed from the list INPUTS list - a pointer to the list whose last node should be retrieved; this can be NULL in which case this function will return NULL. WARNING This function does not arbitrate for access to the list. The calling task must be the owner of the involved list. RESULTS last_node -- The last node of the list or NULL. SEE ALSO GetHead exec.library/IceColdReboot exec.library/IceColdReboot NAME IceColdReboot -- Reboot to power-on state SYNOPSIS void IceColdReboot(void); FUNCTION Try to reboot the machine to a state the machine would have at power-on. Reset callbacks will also be called before reboot. NOTE This function will never return. If it does, contact your dealer. SEE ALSO ColdReboot, AddResetCallback exec.library/InitCode exec.library/InitCode NAME InitCode - initialize resident code modules (internal function) SYNOPSIS InitCode(startClass, version) void InitCode(ULONG,ULONG); FUNCTION (This function may be ignored by application programmers) Call InitResident() for all resident modules in the ResModules array with the given startClass and with versions equal or greater than that specified. The segList parameter is passed as zero. Resident modules are used by the system to pull all its parts together at startup. Modules are initialized in a prioritized order. Modules that do not have a startclass should be of priority -120. RTF_AFTERDOS modules should start at -100 (working down). INPUTS startClass - the class of code to be initialized: BITDEF RT,COLDSTART,0 BITDEF RT,SINGLETASK,1 ;ExecBase->ThisTask==0 (V36 only) BITDEF RT,AFTERDOS,2 ;(V36 only) version - a major version number SEE ALSO ResidentTag (RT) structure definition (resident.h) exec.library/InitData exec.library/InitData NAME InitData -- Initialize a data structure (V50) SYNOPSIS InitData(initTable, memory, size) void InitData(APTR, APTR, ULONG); FUNCTION This function clears a memory area of the given size, then initializes fields in this area based on the command codes given in the initTable. The initTable points to an array of command words that specify how to initialize the memory. The command words always start on a longword address, so padding may be required The layout of these commands is as follows: ULONG command; The fields contains data that is depending on the actual command. The command record is always longword-aligned, so that padding after the optional data might be required. An important concept is the "cursor". The cursor is the place in the structure where commands affect the memory. The cursor is initially at the beginning of the structure, and can be moved with appropriate commands, and moves automatically when data is being written to the structure. The following commands are available. The argument must be 16 bits large. IDATA_QUIT Stop processing. This ends this function. IDATA_CMOVE(n) Move the cursor by n bytes forward (that is, towards high memory). IDATA_CSET(n) Set the cursor to the specified offset. The offset is measured in bytes from the beginning of the structure. IDATA_COPY(n) Copy the next n bytes of to the cursor. The cursor moves n bytes forward during this operation, and points to the first byte after the copied data in the structure. IDATA_RPL(n) Copy the longword in the field times into the destination structure. The cursor moves accordingly to the first free byte after the copied data. IDATA_RPW(n) Copy the word in the optional data field times into the destination structure. The cursor moves accordingly to the first free byte after the copied data. IDATA_RPB(n) Copy the byte in the optional data field times into the destination structure. The cursor moves to the first free byte after the copied data. IDATA_OFFS(n) Calculate the address of the beginning of the structure being initalized plus the offset given in the command and write the result as a longword to the cursor location. This essentially calculates the absolute address of a field in the structure being initialized. INPUTS initTabble - A pointer to a list of commands to init the structure memory - pointer to the structure to initialize size - size of the structure for clearing to zero. If the size is 0, then no clearing is done. RESULT This function doesn't return a value. As a side effect, the structure pointed to by memory is initialized. EXAMPLE /* The following example initializes a list header structure */ struct List list; ULONG initTab[] = { IDATA_OFFS(sizeof(struct Node *)), IDATA_COPY(sizeof(struct Node *)), 0x000000, IDATA_OFFS(0), IDATA_COPY(1), IDATA_B1(NT_LIBRARY), IDATA_QUIT }; exec->InitData((APTR)initTab, (APTR)&list, sizeof(struct List)); NOTES There is a potential problem with different endian CPU's in this function, most notably when using a method like shown in the example section above. Initializing bytes or words in a structure essentially depends on the CPU's endian mode. For big endian, the first byte needs to be shifted into the upper bits of a longword while in a little-endian CPU this does not apply. For portability reasons Exec offers six macros that address these issues and aid in source code portability: IDATA_B1(A) IDATA_B2(A,B) IDATA_B3(A,B,C) IDATA_B4(A,B,C,D) These macros poke one, two, three or four bytes in the correct order into a longword. IDATA_W1(A) IDATA_W2(A,B) These macros poke one or two words in the correct order into a longword. SEE ALSO exex/initializers.h exec.library/InitResident exec.library/InitResident NAME InitResident - initialize resident module SYNOPSIS object = InitResident(resident, segList) APTR InitResident(struct Resident *,ULONG); FUNCTION Initialize a ROMTag. ROMTags are used to link system modules together. Each disk based device or library must contain a ROMTag structure in the first code hunk. Once the validity of the ROMTag is verified, the RT_INIT pointer is jumped to depending on the flag RTF_NATIVE. For 68k (RTF_NATIVE cleared) resident modules, the RT_INIT pointer is emulated with the following registers: D0 = 0 A0 = segList A6 = ExecBase If RTF_NATIVE is set, the call is a standard ABI-compliant call with the following prototype: APTR RT_INIT(void *Base, ULONG segList, struct Library *ExecBase); Note that Base is always 0 now. INPUTS resident - Pointer to a ROMTag segList - SegList of the loaded object, if loaded from disk. Libraries & Devices will cache this value for later return at close or expunge time. Pass NULL for ROM modules. RESULTS object - Return value from the init code, usually the library or device base. NULL for failure. AUTOINIT FEATURE An automatic method of library/device base and vector table initialization is also provided by InitResident(). Depending on the RTF_NATIVE flag, the new style or old style initialization method is used. AUTOINIT FEATURE (Old style - 68K) The initial code hunk of the library or device should contain "MOVEQ #-1,d0; RTS;". Following that must be an initialized Resident structure with RTF_AUTOINIT set in rt_Flags, and an rt_Init pointer which points to four longwords. These four longwords will be used in a call to MakeLibrary(); - The size of your library/device base structure including initial Library or Device structure. - A pointer to a longword table of standard, then library specific function offsets, terminated with -1L. (short format offsets are also acceptable) - Pointer to data table in exec/InitStruct format for initialization of Library or Device structure. - Pointer to library initialization function, or NULL. Calling sequence: D0 = library base A0 = segList A6 = ExecBase This function must return in D0 the library/device base to be linked into the library/device list. If the initialization function fails, the device memory must be manually deallocated, then NULL returned in D0. AUTOINIT FEATURE (New style) The new style initialisation is used when the RTF_AUTOINIT flag is combined with RTF_NATIVE. In this case, the rt_Init pointer points to a CreateLibrary-compatible tag list. The library is created by calling CreateLibrary with the rt_Init pointer. If the CLT_InitFunc tag is specified and the initialization function returns a non-NULL pointer, InitResident will add the library/device/resource to the respective system list. Which list the object will be appended to will be decided upon the rt_Type field in the Resident structure. SEE ALSO exec/resident.h, FindResident, CreateLibrary exec.library/InitSemaphore exec.library/InitSemaphore NAME InitSemaphore -- initialize a signal semaphore SYNOPSIS InitSemaphore(signalSemaphore) void InitSemaphore(struct SignalSemaphore *); FUNCTION This function initializes a signal semaphore and prepares it for use. It does not allocate anything, but does initialize list pointers and the semaphore counters. Semaphores are often used to protect critical data structures or hardware that can only be accessed by one task at a time. After initialization, the address of the SignalSemaphore may be made available to any number of tasks. Typically a task will try to ObtainSemaphore(), passing this address in. If no other task owns the semaphore, then the call will lock and return quickly. If more tasks try to ObtainSemaphore(), they will be put to sleep. When the owner of the semaphore releases it, the next waiter in turn will be woken up. Semaphores are often preferable to the old-style Forbid()/Permit() type arbitration. With Forbid()/Permit() *all* other tasks are prevented from running. With semaphores, only those tasks that need access to whatever the semaphore protects are subject to waiting. INPUT signalSemaphore -- a signal semaphore structure (with all fields set to zero before the call) SEE ALSO ObtainSemaphore, ObtainSemaphoreShared, AttemptSemaphore, ReleaseSemaphore, Procure, Vacate, exec/semaphores.h exec.library/InitStruct exec.library/InitStruct NAME InitStruct - initialize memory from a table SYNOPSIS InitStruct(initTable, memory, size); void InitStruct(APTR, APTR, ULONG); FUNCTION Clear a memory area, then set up default values according to the data and offset values in the initTable. Typically only assembly programs take advantage of this function, and only with the macros defined in "exec/initializers.i". The initialization table has byte commands to |a ||byte| |given||byte| |once | load |count||word| into |next ||rptr| offset, |repetitively | |long| Not all combinations are supported. The offset, when specified, is relative to the memory pointer provided (Memory), and is initially zero. The initialization data (InitTable) contains byte commands whose 8 bits are interpreted as follows: ddssnnnn dd the destination type (and size): 00 no offset, use next destination, nnnn is count 01 no offset, use next destination, nnnn is repeat 10 destination offset is in the next byte, nnnn is count 11 destination offset is in the next 24-bits, nnnn is count ss the size and location of the source: 00 long, from the next two aligned words 01 word, from the next aligned word 10 byte, from the next byte 11 ERROR - will cause an ALERT (see below) nnnn the count or repeat: count the (number+1) of source items to copy repeat the source is copied (number+1) times. initTable commands are always read from the next even byte. Given destination offsets are always relative to the memory pointer (A2). The command %00000000 ends the InitTable stream: use %00010001 if you really want to copy one longword without a new offset. 24 bit APTR not supported for 68020 compatibility -- use long. INPUTS initTable - the beginning of the commands and data to init Memory with. Must be on an even boundary unless only byte initialization is done. End table with "dc.b 0" or "dc.w 0". memory - the beginning of the memory to initialize. Must be on an even boundary if size is specified. size - the size of memory, which is used to clear it before initializing it via the initTable. If Size is zero, memory is not cleared before initializing. size must be an even number. SEE ALSO exec/initializers.i exec.library/Insert exec.library/Insert NAME Insert -- insert a node into a list SYNOPSIS Insert(list, node, listNode) void Insert(struct List *, struct Node *, struct Node *); FUNCTION Insert a node into a doubly linked list AFTER a given node position. Insertion at the head of a list is possible by passing a zero value for listNode, though the AddHead function is slightly faster for that special case. WARNING This function does not arbitrate for access to the list. The calling task must be the owner of the involved list. INPUTS list - a pointer to the target list header node - the node to insert listNode - the node after which to insert SEE ALSO AddHead, AddTail, Enqueue, RemHead, Remove, RemTail exec.library/IsNative exec.library/IsNative NAME IsNative -- Check if a code pointer is native (V50) SYNOPSIS native = IsNative(code); BOOL IsNative(APTR); FUNCTION This function checks the given pointer and returns TRUE if the address pointed to is native code that can be directly jumped to, or FALSE when the code is legacy 68k code that needs to be emulated. INPUTS code - the pointer to the code to check RESULT native - TRUE if the code is native code, FALSE otherwise BUGS SEE ALSO exec.library/Emulate exec.library/ItemPoolAlloc exec.library/ItemPoolAlloc NAME ItemPoolAlloc -- Allocate an item from a pool (V50) SYNOPSIS APTR ItemPoolAlloc(APTR pool); FUNCTION Allocates a new item from the given item pool. If a constructor hook is defined for the pool, it is invoked before this function returns. INPUTS pool - the item pool from which to allocate this item RESULT The function returns a pointer to the newly allocated item, or NULL. If the return value is NULL, then either the constructor hook indicated failure, the upper limit of items was hit, or there was no more free memory to allocate a new batch of items SEE ALSO ASOT_ITEMPOOL, ItemPoolFree(), ItemPoolGC(), ItemPoolControl() exec.library/ItemPoolControl exec.library/ItemPoolControl NAME ItemPoolControl -- Control attributes in an item pool (V50) ItemPoolControlTags -- vararg stub SYNOPSIS uint32 ItemPoolControl(APTR pool, struct TagItem *tags); uint32 ItemPoolControlTags(APTR pool, ...); FUNCTION This function performs control functions on the given pool. Most notably, it can be used to change attributes and behaviours of the pool. INPUTS pool - a pointer to the pool to control tags - a taglist array. Currently, the following tag items from AllocSysObject can be used on this function, with the same meaning as for ASOT_ITEMPOOL: ASOITEM_GCPolicy, ASOITEM_GCParam, ASOITEM_Constructor, ASOITEM_Destructor RESULT The function returns the number of successfully set attributes NOTES Setting the ASOITEM_MaxSize to something smaller than the currently used size has no effect, and will fail. It may be dangerous to set the Constructor or Destructor to something different when there is still items allocated BUGS SEE ALSO ASOT_ITEMPOOL, ItemPoolAlloc(), ItemPoolFree(), ItemPoolGC() exec.library/ItemPoolFlush exec.library/ItemPoolFlush NAME ItemPoolFlush -- Delete all items in an item pool (V51) SYNOPSIS VOID ItemPoolFlush(APTR pool); FUNCTION This function will delete all items in an item pool, returning them to the system. This is the same as freeing every individual item in the pool INPUTS pool - the item pool from which the item was allocated SEE ALSO ASOT_ITEMPOOL, ItemPoolAlloc(), ItemPoolGC(), ItemPoolControl() exec.library/ItemPoolFree exec.library/ItemPoolFree NAME ItemPoolFree -- Return an item to its item pool (V50) SYNOPSIS VOID ItemPoolFree(APTR pool, APTR item); FUNCTION Return the item previously allocated with ItemPoolAlloc to its pool, freeing it up for reuse. Any stored data in the item may be overwritten by this call - reallocating the item does not necessarily leave the item content intact. INPUTS pool - the item pool from which the item was allocated item - a pointer to the item RESULT This function does not return a result. SEE ALSO ASOT_ITEMPOOL, ItemPoolAlloc(), ItemPoolGC(), ItemPoolControl() exec.library/ItemPoolGC exec.library/ItemPoolGC NAME ItemPoolGC -- Perform garbage collection (V50) SYNOPSIS VOID ItemPoolGC(APTR pool); FUNCTION This call performs explicit garbage collection on the given pool, freeing up unused chunks of memory. INPUTS pool - the item pool to garbage-collect RESULT No result is returned; however, the pool given is cleaned up and has all unused chunks freed. SEE ALSO ASOT_ITEMPOOL, ItemPoolAlloc(), ItemPoolFree(), ItemPoolControl() exec.library/LockMem exec.library/LockMem NAME LockMem -- Lock an address range into physical memory (V50) SYNOPSIS success = LockMem(baseAddress, size); BOOL LockMem(APTR, ULONG); FUNCTION This function will make sure that the given range of addresses is actually addressable and that the memory will not be unmapped, swapped out, or somehow made unaccesible. In other words, after successfuly execution of these functions, the memory associated with these addresses is guaranteed to stay in memory. INPUTS baseAddress - Base address of the memory region to lock size - Size of the region to lock RESULT The function returns TRUE if the lock was successful (i.e. all associated memory is now accesible), or FALSE if the lock did not succeed. NOTES Memory locking is nested. This means that for each time you lock memory, it must be unlocked. It's not necessary to unlock all in one go, but you must make sure that all addresses that have been locked are unlocked (don't assume that you know the granularity of this operation... you don't). SEE ALSO UnlockMem exec.library/LockNamedMemory exec.library/LockNamedMemory NAME LockNamedMemory -- Arbitrate access of shared named memory block (V51) SYNOPSIS void *LockNamedMemory(STRPTR space, STRPTR name); FUNCTION Calling this function will lock the named memory block for exclusive access by the caller. If successful, the pointer to the block is returned. If the block does not exist, NULL is returned. If the block is locked by another entity, the call will block. INPUTS space - Namespace to search for the block. name - Name of the block to update. RESULT If successful, the pointer to the memory block is returned. If the block does not exist, NULL is returned. SEE ALSO AllocNamedMemory, FreeNamedMemory, FindNamedMemory, UnlockNamedMemory, AttemptNamedMemory exec.library/MakeFunctions exec.library/MakeFunctions NAME MakeFunctions -- construct a function jump table SYNOPSIS tableSize = MakeFunctions(target, functionArray, funcDispBase) ULONG MakeFunctions(APTR,APTR,APTR); FUNCTION A low level function used by MakeLibrary to build jump tables of the type used by libraries, devices and resources. It allows the table to be built anywhere in memory, and can be used both for initialization and replacement. This function also supports function pointer compression by expanding relative displacements into absolute pointers. The processor instruction cache is cleared after the table building. INPUT destination - the target address for the high memory end of the function jump table. Typically this will be the library base pointer. functionArray - pointer to an array of function pointers or function displacements. If funcDispBase is zero, the array is assumed to contain absolute pointers to functions. If funcDispBase is not zero, then the array is assumed to contain word displacements to functions. In both cases, the array is terminated by a -1 (of the same size as the actual entry. funcDispBase - pointer to the base about which all function displacements are relative. If zero, then the function array contains absolute pointers. RESULT tableSize - size of the new table in bytes (for LIB_NEGSIZE). SEE ALSO exec/MakeLibrary exec.library/MakeInterface exec.library/MakeInterface NAME MakeInterface -- Construct an Interface (V50) MakeInterfaceTags - Vararg version SYNOPSIS interface = MakeInterface(library, taglist); struct Interface *MakeInterface(struct Library *, struct TagItem *); interface = MakeInterfaceTags(library, tag1, ...); struct Interface *MakeInterfaceTags(struct Library *, ULONG, ...); FUNCTION This function is used to construct an interface for a library or a device. The library must have been created earlier with a call to MakeLibrary. Nonswappable memory space for the new interface is allocated from the system pool. This function can also initialize a data part for the interface. INPUTS library - Pointer to a struct Library that represents the library for which this interface is created. Note that this pointer is not used by this function, other than passing it to a given init function. tagitem - Pointer to a tag list with information on how to generate the interface. The following tagitems are defined: MIT_VectorTable: Pointer to an array of function pointers which will form the interface methods. There must be at least two vectors given (Obtain and Release). The array is terminated by a -1 entry. Note that NULL entries in the table are allowed, but these must be filled in subsequently and the interface must be resummed (use of the exec.library/SetMethod() is strictly recommended) before the interface is published. If the first entry of this array is -1, then all addresses are relative to the beginning of the table pointed to by vectors. Otherwise all entries are interpreted as absolute addresses. This tag MUST be present. MIT_InitData: Optional pointer to an initstruct, that wil be passed unmodified to exec.library/InitData(), with the base address of the data area as the memory pointer, so offsets are non-negative. The initialization must not write into the interface's system parts! The default value is NULL. MIT_InitFunc: Pointer to a function to be invoked, if not NULL. The IFACEINITFUNC typedef is defined in the file exec/interfaces.h. The initfunc must have the following prototype: struct Interface *initfunc( struct Library *libbase, struct Interface *new_iface, struct interface *exec); The new_iface pointer points to the interface being constructed. When this function is called, the complete initialization is already done, so you can find the data area of your interface by using (char *)new_iface - new_iface->NegativeSize The last parameter is a pointer to the main exec interface for convenience. This function must return the interface address if successful, otherwise it must return NULL. Note that unlike the classic MakeLibrary the function must not free the interface memory if the initialization failed. The tag item's default value is NULL. This function is rarely necessary. MIT_DataSize: The size of this interface's instance data area. The default for this tag is 0. MIT_Flags: The flags for this interface, as defined in exec/interfaces.h (IFLF_#?). Default is IFLF_NONE. MIT_Version: The version number of the interface being created. This tag must be given. MIT_Name: A name for the interface. If a name is given, the interface can be retrieved from the library's interface list by name later. The name string is not copied. RESULT interface - the reference address of the interface. This address is used to reference the library. If the function returns NULL, then something went wrong and the interface has not been created. EXAMPLE See the SDK for a complete example of a multi-interface library. SEE ALSO InitData(), MakeLibrary(), NewMakeLibrary(), DeleteInterface(), exec/initializers.h, exec/interfaces.h exec.library/MakeLibrary exec.library/MakeLibrary NAME MakeLibrary -- construct a library (OBSOLETE!) SYNOPSIS library = MakeLibrary(vectors, structure, init, dataSize, segList) struct Library *MakeLibrary(APTR, APTR, APTR, ULONG, APTR); FUNCTION This function is used for constructing a library vector and data area. Space for the library is allocated from the system's free memory pool. The size fields of the library are filled. The data portion of the library is initialized. A library specific entrypoint is called (init) if present. INPUTS vectors - pointer to an array of function pointers or function displacements. If the first word of the array is -1, then the array contains relative word displacements (based off of vectors); otherwise, the array contains absolute function pointers. The vector list is terminated by a -1 (of the same size as the pointers). structure - points to an "InitStruct" data region. If null, then it will not be called. init - an entry point that will be called before adding the library to the system. If null, it will not be called. When it is called, it will be called with: d0 = libAddr ;Your Library Address a0 = segList ;Your AmigaDOS segment list a6 = ExecBase ;Address of exec.library The result of the init function will be the result returned by MakeLibrary. MakeLibrary will always emulate this function, assuming it's m68k code. dSize - the size of the library data area, including the standard library node data. segList - pointer to a memory segment list (used by DOS) This is passed to a library's init code. RESULT library - the reference address of the library. This is the address used in references to the library, not the beginning of the memory area allocated. NOTE WARNING: This function is obsolete with release 50. Only m68k libraries can still be created with it. All new libraries *MUST* be created with CreateLibrary. EXCEPTION If the library vector table require more system memory than is available, this function will cause a system panic. SEE ALSO InitStruct, CreateLibrary exec.library/MMU/GetMemoryAttrs exec.library/MMU/GetMemoryAttrs NAME GetMemoryAttrs -- Get attributes of a memory address SYNOPSIS attrs = GetMemoryAttrs(virtual, flags); ULONG GetMemoryAttrs(APTR, ULONG); FUNCTION Use this function to query the memory attributes for a given memory cell. The information returned is true for the hardware-dependant page the memory cell is contained in. This function must be called in supervisor mode INPUTS virtual - address to query flags - Flags to control the operation GMAF_REPORT_CR Report changed and referenced flags. This will clear these flags, which might interfere with virtual memory. USE WITH CARE! RESULT attrs - attributes of the memory area MEMATTRF_WRITETHROUGH Store operations in this area update cache and memory MEMATTRF_CACHEINHIBIT Caches are inhibited in this area MEMATTRF_COHERENT Coherency required, stores to same address will be serialized MEMATTRF_GUARDED Ensure in-order execute of memory accesses MEMATTRF_SUPER_RW The area is readable and writeable in supervisor mode, but no access is allowed for user mode MEMATTRF_SUPER_RW_USER_RO The area is readable and writeable in supervisor mode, and readable in user mode MEMATTRF_SUPER_RW_USER_RW MEMATTRF_READ_WRITE The area is readable and writeable for both user and supervisor mode MEMATTRF_SUPER_RO_USER_RO MEMATTRF_READ_ONLY The area is only readable in both user and supervisor mode MEMATTRF_NOT_MAPPED The area is not mapped MEMATTRF_REFERENCED The page has been accessed before MEMATTRF_CHANGED The page has been written to NOTES This function is extremely dangerous to use if you don't know what you're doing. And since the virtual addressing architecture is not publically documented, you do *NOT* know what you're doing. If in doubt, don't use this function, and rely on ExecSG to do the job. SEE ALSO SetMemoryAttrs exec.library/MMU/GetPhysicalAddress exec.library/MMU/GetPhysicalAddress NAME GetPhysicalAddress -- Compute physical address for given virtual address SYNOPSIS addr = GetPhysicalAddress(virtual); APTR GetPhysicalAddress(APTR); FUNCTION For a given virtual address, this function will compute the corresponding physical address, based on the current address environemnt. This function must be called in supervisor mode INPUTS virtual - address to query RESULT The physical address the virtual address maps to. If the virtual address is not mapped, 0 is returned. Please note that this address is normally not accesible from your program, but may serve as a base address for DMA operations. NOTES This function is extremely dangerous to use if you don't know what you're doing. And since the virtual addressing architecture is not publically documented, you do *NOT* know what you're doing. If in doubt, don't use this function, and rely on ExecSG to do the job. exec.library/MMU/MapMemory exec.library/MMU/MapMemory NAME MapMemory -- Map virtual addresses to physical ones SYNOPSIS success = MapMemory(virtual, physical, length, attrs); BOOL MapMemory(APTR, APTR, ULONG, ULONG); FUNCTION This functions creates a mapping in the current address environemnt that will map access to the block from virtual to virtual+length-1 to be rerouted to the range phyiscal to pyhsical+length-1. Both physical and virtual, as well as length may be aligned to a hardware-imposed limit. This function must be called in supervisor mode INPUTS virtual - virtual base address for the mapping physical - target of the mapping in physical memory length - length of the memory range to be mapped. attrs - Protection/Attributes for this range. Available attributes: MEMATTRF_WRITETHROUGH Store operations in this area update cache and memory MEMATTRF_CACHEINHIBIT Caches are inhibited in this area MEMATTRF_COHERENT Coherency required, stores to same address will be serialized MEMATTRF_GUARDED Ensure in-order execute of memory accesses MEMATTRF_SUPER_RW The area is readable and writeable in supervisor mode, but no access is allowed for user mode MEMATTRF_SUPER_RW_USER_RO The area is readable and writeable in supervisor mode, and readable in user mode MEMATTRF_SUPER_RW_USER_RW MEMATTRF_READ_WRITE The area is readable and writeable for both user and supervisor mode MEMATTRF_SUPER_RO_USER_RO MEMATTRF_READ_ONLY The area is only readable in both user and supervisor mode RESULT If the mapping was successfully inserted into the page table, TRUE is resturned. FALSE indicates that the mapping failed for some reason. In this case, no mapping will be done (no partial mappings will be left). NOTES This function is extremely dangerous to use if you don't know what you're doing. And since the virtual addressing architecture is not publically documented, you do *NOT* know what you're doing. If in doubt, don't use this function, and rely on ExecSG to do the job. SEE ALSO UnmapMemory, RemapMemory exec.library/MMU/RemapMemory exec.library/MMU/RemapMemory NAME RemapMemory -- Change mapping of a memory range SYNOPSIS RemapMemory(virtual, physical, length, attrs); void RemapMemory(APTR, APTR, ULONG, ULONG); FUNCTION This functions changes a mapping in the current address environemnt that will map access to the block from virtual to virtual+length-1 to be rerouted to the range phyiscal to pyhsical+length-1. Both physical and virtual, as well as length may be aligned to a hardware-imposed limit. This function must be called in supervisor mode INPUTS virtual - virtual base address for the mapping physical - target of the mapping in physical memory length - length of the memory range to be mapped. attrs - Protection/Attributes for this range. Available attributes: MEMATTRF_WRITETHROUGH Store operations in this area update cache and memory MEMATTRF_CACHEINHIBIT Caches are inhibited in this area MEMATTRF_COHERENT Coherency required, stores to same address will be serialized MEMATTRF_GUARDED Ensure in-order execute of memory accesses MEMATTRF_SUPER_RW The area is readable and writeable in supervisor mode, but no access is allowed for user mode MEMATTRF_SUPER_RW_USER_RO The area is readable and writeable in supervisor mode, and readable in user mode MEMATTRF_SUPER_RW_USER_RW MEMATTRF_READ_WRITE The area is readable and writeable for both user and supervisor mode MEMATTRF_SUPER_RO_USER_RO MEMATTRF_READ_ONLY The area is only readable in both user and supervisor mode NOTES This function is extremely dangerous to use if you don't know what you're doing. And since the virtual addressing architecture is not publically documented, you do *NOT* know what you're doing. If in doubt, don't use this function, and rely on ExecSG to do the job. SEE ALSO UnmapMemory, MapMemory exec.library/MMU/SetMemoryAttrs exec.library/MMU/SetMemoryAttrs NAME SetMemoryAttrs -- Change attributes of a memory range SYNOPSIS SetMemoryAttrs(virtual, length, attrs); void SetMemoryAttrs(APTR, ULONG, ULONG); FUNCTION This function will change existing memory attributes of a memory range. Note that a mapping must exist for the range. If no mapping exists, no attributes are set for the unmapped portions. This function must be called in supervisor mode INPUTS virtual - virtual base address for the mapping length - length of the memory range to be mapped. attrs - Protection/Attributes for this range. Available attributes: MEMATTRF_WRITETHROUGH Store operations in this area update cache and memory MEMATTRF_CACHEINHIBIT Caches are inhibited in this area MEMATTRF_COHERENT Coherency required, stores to same address will be serialized MEMATTRF_GUARDED Ensure in-order execute of memory accesses MEMATTRF_SUPER_RW The area is readable and writeable in supervisor mode, but no access is allowed for user mode MEMATTRF_SUPER_RW_USER_RO The area is readable and writeable in supervisor mode, and readable in user mode MEMATTRF_SUPER_RW_USER_RW MEMATTRF_READ_WRITE The area is readable and writeable for both user and supervisor mode MEMATTRF_SUPER_RO_USER_RO MEMATTRF_READ_ONLY The area is only readable in both user and supervisor mode NOTES This function is extremely dangerous to use if you don't know what you're doing. And as the virtual addressing architecture is not publically documented, you do *NOT* know what you're doing. If in doubt, don't use this function, and rely on ExecSG to do the job. BUGS Before version 53.42 this function could leave the final underlying memory page attributes unchanged. SEE ALSO UnmapMemory, MapMemory, RemapMemory exec.library/MMU/UnmapMemory exec.library/MMU/UnmapMemory NAME UnmapMemory -- Remove an address remapping SYNOPSIS UnmapMemory(virtual, length); void UnmapMemory(APTR, ULONG); FUNCTION This function unmaps the memory area from virtual to virtual+length-1. If any mapping exists in that area, it is remove. In other words, this functions ensures that the given range is unmapped. Both virtual and length may be aligned to a hardware-imposed limit. UnmapMemory will *NOT* touch the caches. When unmapping a memory region, you should make sure that the caches must be flushed for this region before unmapping. Otherwiese, subsequent implicit or explicit cache flushes might cause access violation. This function must be called in supervisor mode INPUTS virtual - virtual base address for the mapping length - length of the memory range to be mapped. NOTES This function is extremely dangerous to use if you don't know what you're doing. And since the virtual addressing architecture is not publically documented, you do *NOT* know what you're doing. If in doubt, don't use this function, and rely on ExecSG to do the job. SEE ALSO RemapMemory, MapMemory exec.library/MoveList exec.library/MoveList NAME MoveList -- Remove all nodes from one list and append them to a different list. (V50) SYNOPSIS MoveList(destination,source); void MoveList(struct List *, struct List *); FUNCTION MoveList() is a convenient shortcut to transferring all nodes from one list to another in an efficient manner. The transfer will be performed in one single step. All nodes from the source list will be added to the end of the destination list. INPUTS destination - Pointer to the list to add the nodes to which will be removed from the source list. source - Pointer to the list whose contents should be removed and added to the destination list. It is safe to submit an empty list, in which case no work will be done. RESULT When this routine returns, the source list will be empty. NOTES The MoveList() routine is functionally equivalent to the following code fragment, except that it performs the same task in one single step which involves no looping: struct List * source_list; struct List * destination_list; struct Node * node; while((node = RemHead(source_list)) != NULL) AddTail(destination_list,node); SEE ALSO AddTail, RemHead, NewMinList exec.library/MutexAttempt exec.library/MutexAttempt NAME MutexAttempt -- Try to lock a mutex (V52) SYNOPSIS BOOL MutexAttempt(APTR mx); FUNCTION This function attempts to lock the mutex mx. This function will never block on an already locked mutex. Note, though, that the attempt might fail if the mutex is not recursive (see ASOT_MUTEX) and is locked, even if it's already owned by the caller. The Mutex mx must be allocated with a call to AllocSysObject. If the mutex is recursive, each successful lock must be unlocked via a paired MutexRelease call. INPUTS mx - A pointer to a previously allocated mutex. RESULT A boolean value, indicating success or failure SEE ALSO AllocSysObject, MutexRelease, MutexObtain exec.library/MutexAttemptWithSignal exec.library/MutexAttemptWithSignal NAME MutexAttemptWithSignal -- Attempt to lock mutex with signal mask (V52) SYNOPSIS uint32 MutexAttemptWithSignal(APTR mx, uint32 SigMask); FUNCTION Mutexes are similar to the SignalSemaphore, although the protocol defined on them is simpler. They can not be obtained shared or in an asynchronous fashion. However, if the mutex isn't locked when this function is called on it, it will acquire the lock without the use of Forbid/Permit locking. This function will try to lock the mutex mx. It will block until the mutex is either free, or the task is signaled with one of the signal bits defined in SigMask. The Mutex mx must be allocated with a call to AllocSysObject. INPUTS mx - A pointer to a previously allocated mutex. If the mutex is recursive, each successful lock must be unlocked via a paired MutexRelease call. SigSet - A signal mask. The task will block until the mutex is available, or one of the signals in this set is received. RESULT The signal mask that preempted the lock, or 0 if successful SEE ALSO AllocSysObject, MutexRelease, MutexAttempt exec.library/MutexObtain exec.library/MutexObtain NAME MutexObtain -- Lock a mutex (V52) SYNOPSIS MutexObtain(APTR mx); FUNCTION Mutexes are similar to the SignalSemaphore, although the protocol defined on them is simpler. They can not be obtained shared or in an asynchronous fashion. However, if the mutex isn't locked when this function is called on it, it will acquire the lock without the use of Forbid/Permit locking. This function locks the mutex mx. The function will block if the mutex is currently held by another task, or if it's not recursive and locked (no matter by what task). The Mutex mx must be allocated with a call to AllocSysObject. INPUTS mx - A pointer to a previously allocated mutex. If the mutex is recursive, each successful lock must be unlocked via a paired MutexRelease call. SEE ALSO AllocSysObject, MutexRelease, MutexAttempt exec.library/MutexRelease exec.library/MutexRelease NAME MutexRelease -- Unlock a previously locked mutex (V52) SYNOPSIS MutexRelease(APTR mx); FUNCTION This function unlocks the mutex mx. Note that no ownership test is made. Releasing a mutex might result in a reschedule to take place if task switching is allowed. INPUTS mx - A pointer to a previously locked mutex. SEE ALSO AllocSysObject, MutexObtain, MutexAttempt exec.library/Named exec.library/Named NAME Named memory background (V51) FUNCTION In a multi-tasking environment, it is often desireable to be able to share resources between different task/applications/threads. This can be done by passing memory pointers, but this is difficult since there is no defined "protocol" for this. Exec V51 introduces a new concept called named memory. Instead of having to pass a pointer around, you decide on a name for your memory and have others (or yourself) access this memory by it's name. In addition, named memory can be organized into different namespaces, i.e. the same name can exist in different namespaces. On the other hand, all names in one namespace must be unique. One namespace is predefined with a special functionality: The namespace "resident". This namespace and it's objects will be restored after reboot throught ColdStart(). To ensure data integrity, it is possible to have the memory block automatically checksummed. The checksum is validated after reboot. If checksumming is enabled and the stored checksum and newly computed checksums match, the block is available to subsequent FindNamedMemory calls. Otherwise, the block is discarded. If no checksumming is enabled for the block, the application mus ensure data integrity itself. ISSUES - Should named memory be shareable between address spaces later on ? Proposal: Yes. For this purpose, memory shared among address spaces should not have a fixed address, i.e. the address is not the same in each address space. - Should resident memory be mapped to the same address after reboot ? Proposal: No. Mapping to the same address is difficult to achieve cleanly. HISTORY 19.9.2005 - First draft 20.9.2005 - Removed the type parameter in favor of namespaces - Added an additional flag to AllocNamedMemory to make a block resident - Added a namespace parameter to each function - Added lock/unlock/attempt calls for access arbitration 23.9.2005 - Removed the resident flag in favor of a new "resident" namespace - Added ScanNamedMemory - Fixed example (Thanks, Davy) exec.library/NewList exec.library/NewList NAME NewList -- prepare a list structure for use (V50) SYNOPSIS NewList(list) VOID NewList(struct List *); FUNCTION Perform the magic needed to prepare a List header structure for use; the list will be empty and ready to use. (If the list is the full featured type, you may need to initialize lh_Type afterwards) Assembly programmers may want to use the NEWLIST macro instead. INPUTS list - pointer to a List or MinList. SEE ALSO exec.library/NewMinList exec.library/NewMinList NAME NewList -- prepare a minimal list structure for use (V50) SYNOPSIS NewMinList(list) VOID NewMinList(struct MinList *); FUNCTION Perform the magic needed to prepare a List header structure for use; the list will be empty and ready to use. INPUTS list - pointer to a MinList. SEE ALSO exec.library/NewStackRun exec.library/NewStackRun NAME NewStackRun -- Run a function with its own stack frame. (V52.6) SYNOPSIS int32 errorcode = NewStackRun(APTR initPC, const struct TagItem *) int32 errorcode = NewStackRunTags(APTR initPC, uint32, ...) FUNCTION This function allocates a new stack frame for the function and runs it under the same task/process context as the caller. The initial size of the stackframe, any required function parameters and other options are specified via tags. This routine is called by various kickstart modules (including DOS) to launch all processes or tasks with their own stack frame. The new stack frame will be deallocated when the function returns. INPUTS initPC - (int32 (*)()) -- Address of the function to run. The function pointer may point to 68K or PPC executable code. Type determination is automatic. tags - a pointer to a TagItem array; see below. The following tags are defined: NSR_StackSize (uint32) -- The chosen stack size (in bytes) that the function should allocate to begin running. Incase of a memory shortage, this value may be adjusted down to fit the available memory, unless the tag; NSR_MinStackSize is specified to limit the amount of adjustment. (Default; 8K bytes) NB: If you call this function with an NSR_StackSize of 0, a new stack frame will NOT be allocated for the function call, instead, it will run using the stack frame of the calling process/task. NSR_MinStackSize (uint32) -- The absolute minimum stack size allowed to run the function. If there is insufficient memory available to comply with NSR_StackSize, this specification will be used to determine how far down it is permitted to adjust the request. (Default; system page size) The function will fail if this lower limit cannot be supplied, the errorcode of -1 will be returned and a secondary error code (processes only) of; ERROR_NO_FREE_STORE will be returned by calling the dos/IoErr() function. NSR_LockStack (BOOL) -- If TRUE, the stack will be locked in memory thus preventing it from being swapped out. (Default; FALSE, allow stack to be swapped out) Arguments - For calling a PPC native function. NSR_Arg1 (int32) -- The first parameter to a native function. NSR_Arg2 (int32) -- The second parameter. NSR_Arg3 (int32) -- The third parameter. NSR_Arg4 (int32) -- The fourth parameter. NSR_Arg5 (int32) -- The fifth parameter. NSR_Arg6 (int32) -- The sixth parameter. Arguments - For calling a legacy 68K function, the exec/Emulate() routine is called internally, therefore use the relevant tags for that function here, when handling 68K function calls. (see; exec/emulation.h) ET_RegisterD0 ... ET_RegisterD7 ET_RegisterA0 ... ET_RegisterA6 ... NB: Both 68K and PPC native type arguments may be specified together, if the type of function is unknown when invoking this routine. Only the relevant tags will be used after type determination. RESULT errorcode - The ERROR value returned by the function that was run. A value of -1 can be returned by this routine on failure. The function being run should always return positive error codes. Negative error codes are reserved by the operating system. Returning 0 indicates "no error" therefore it was successful. NOTES SEE ALSO exec/Emulate(), exec.library/ObtainQuickVector exec.library/ObtainQuickVector NAME Function to obtain an install a Quick Interrupt vector (V39) SYNOPSIS vector = ObtainQuickVector(interruptCode) ULONG ObtainQuickVector(APTR); FUNCTION This function will install the code pointer into the quick interrupt vector it allocates and returns to you the interrupt vector that your Quick Interrupt system needs to use. This function may also return 0 if no vectors are available. Your hardware should be able to then fall back to using the shared interrupt server chain should this happen. The interrupt code is a direct connect to the physical interrupt. This means that it is the responsibility of your code to do all of the context saving/restoring required by interrupt code. Also, due to the performance of the interrupt controller, you may need to also watch for "false" interrupts. These are interrupts that come in just after a DISABLE. The reason this happens is because the interrupt may have been posted before the DISABLE hardware access is completed. For example: myInt: move.l d0,-(sp) ; Save d0... move.w _intenar,d0 ; Get interrupt enable state btst.l #INTB_INTEN,d0 ; Check if pending disable bne.s realInt ; If not, do real one... exitInt: move.l (sp)+,d0 ; Restore d0 rte ; Return from int... ; realInt: ; Now do your int code... d0 is already saved ; ALL other registers need to be saved if needed ; This includes a0/a1/d0/d1 as this is an interrupt ; and not a function call... ; bra.s exitInt ; Exit interrupt... If your interrupt will not play with system (OS) structures and your own structures are safe to play with you do not need to check for the disable. It is only needed for when the system is in disable but that "one last interrupt" still got through. NOTE This function was not implemented fully until V39. Due to a mis-cue it is not safe to call in V37 EXEC. (Sorry) This function will always return 0 from V50 upward. INPUTS A pointer to your interrupt code. This code is not an EXEC interrupt but is dirrectly connected to the hardware interrupt. Thus, the interrupt code must not modify any registers and must return via an RTE. RESULTS The 8-bit vector number used for Zorro-III Quick Interrupts If it returns 0, no quick interrupt was allocatable. The device should at this point switch to using the shared interrupt server method. exec.library/ObtainSemaphore exec.library/ObtainSemaphore NAME ObtainSemaphore -- gain exclusive access to a semaphore SYNOPSIS ObtainSemaphore(signalSemaphore) void ObtainSemaphore(struct SignalSemaphore *); FUNCTION Signal semaphores are used to gain exclusive access to an object. ObtainSemaphore is the call used to gain this access. If another user currently has the semaphore locked the call will block until the object is available. If the current task already has locked the semaphore and attempts to lock it again the call will still succeed. A "nesting count" is incremented each time the current owning task of the semaphore calls ObtainSemaphore(). This counter is decremented each time ReleaseSemaphore() is called. When the counter returns to zero the semaphore is actually released, and the next waiting task is called. A queue of waiting tasks is maintained on the stacks of the waiting tasks. Each will be called in turn as soon as the current task releases the semaphore. Signal Semaphores are different than Procure()/Vacate() semaphores. The former requires less CPU time, especially if the semaphore is not currently locked. They require very little set up and user thought. The latter flavor of semaphore make no assumptions about how they are used -- they are completely general. Unfortunately they are not as efficient as signal semaphores, and require the locker to have done some setup before doing the call. INPUT signalSemaphore -- an initialized signal semaphore structure NOTE This function preserves all registers (see BUGS). BUGS Until V37, this function could destroy A0. SEE ALSO ObtainSemaphoreShared(), InitSemaphore(), ReleaseSemaphore(), AttemptSemaphore(), ObtainSemaphoreList(), Procure(), Vacate() exec.library/ObtainSemaphoreList exec.library/ObtainSemaphoreList NAME ObtainSemaphoreList -- get a list of semaphores. SYNOPSIS ObtainSemaphoreList(list) void ObtainSemaphoreList(struct List *); FUNCTION Signal semaphores may be linked together into a list. This function takes a list of these semaphores and attempts to lock all of them at once. This call is preferable to applying ObtainSemaphore() to each element in the list because it attempts to lock all the elements simultaneously, and won't deadlock if someone is attempting to lock in some other order. This function assumes that only one task at a time will attempt to lock the entire list of semaphores. In other words, there needs to be a higher level lock (perhaps another signal semaphore...) that is used before someone attempts to lock the semaphore list via ObtainSemaphoreList(). Note that deadlocks may result if this call is used AND someone attempts to use ObtainSemaphore() to lock more than one semaphore on the list. If you wish to lock more than semaphore (but not all of them) then you should obtain the higher level lock (see above) INPUT list -- a list of signal semaphores SEE ALSO ObtainSemaphoreShared(), InitSemaphore(), ReleaseSemaphore(), AttemptSemaphore(), ObtainSemaphoreShared(), Procure(), Vacate() exec.library/ObtainSemaphoreShared exec.library/ObtainSemaphoreShared NAME ObtainSemaphoreShared -- gain shared access to a semaphore (V36) SYNOPSIS ObtainSemaphoreShared(signalSemaphore) void ObtainSemaphoreShared(struct SignalSemaphore *); FUNCTION A lock on a signal semaphore may either be exclusive, or shared. Exclusive locks are granted by the ObtainSemaphore() and AttemptSemaphore() functions. Shared locks are granted by ObtainSemaphoreShared(). Calls may be nested. Any number of tasks may simultaneously hold a shared lock on a semaphore. Only one task may hold an exclusive lock. A typical application is a list that is often read, but only occasionally written to. Any exlusive locker will be held off until all shared lockers release the semaphore. Likewise, if an exlusive lock is held, all potential shared lockers will block until the exclusive lock is released. All shared lockers are restarted at the same time. EXAMPLE IExec->ObtainSemaphoreShared(ss); /* read data */ IExec->ReleaseSemaphore(ss); IExec->ObtainSemaphore(ss); /* modify data */ IExec->ReleaseSemaphore(ss); NOTES While this function was added for V36, the feature magically works with all older semaphore structures. A task owning a shared lock must not attempt to get an exclusive lock on the same semaphore. Starting in V39, if the caller already has an exclusive lock on the semaphore it will return with another nesting of the lock. Pre-V39 this would cause a deadlock. For pre-V39 use, you can use the following workaround: /* Try to get the shared semaphore */ if (!AttemptSemaphoreShared(ss)) { /* Check if we can get the exclusive version */ if (!AttemptSemaphore(ss)) { /* Oh well, wait for the shared lock */ ObtainSemaphoreShared(ss)); } } : : ReleaseSemaphore(ss); INPUT signalSemaphore -- an initialized signal semaphore structure NOTE This call is guaranteed to preserve all registers, starting with V37 exec. SEE ALSO ObtainSemaphore(), InitSemaphore(), ReleaseSemaphore(), AttemptSemaphore(), ObtainSemaphoreList(), Procure(), Vacate() exec.library/OpenDevice exec.library/OpenDevice NAME OpenDevice -- gain access to a device SYNOPSIS error = OpenDevice(devName, unitNumber, iORequest, flags) BYTE OpenDevice(STRPTR,ULONG,struct IORequest *,ULONG); FUNCTION This function opens the named device/unit and initializes the given I/O request block. Specific documentation on opening procedures may come with certain devices. The device may exist in memory, or on disk; this is transparent to the OpenDevice caller. A full path name for the device name is legitimate. For example "test:devs/fred.device". This allows the use of custom devices without requiring the user to copy the device into the system's DEVS: directory. NOTES All calls to OpenDevice should have matching calls to CloseDevice! Devices on disk cannot be opened until after DOS has been started. As of V36 tasks can safely call OpenDevice, though DOS may open system requesters (e.g., asking the user to insert the Workbench disk if DEVS: is not online). You must call this function from a DOS Process if you want to turn off DOS requesters. When the I/O request block was not created with a system function like AllocSysObject, CreateIORequest or CreateExtIO, you should initialize the io_Message.mn_Length field to the size of the I/O request block which will allow some devices to verify the size. New devices should always check the mn_Length field and refuse to open when its smaller than the minimum required I/O request block size. When opening an unknown device, e.g. to send it an NSCMD_DEVICEQUERY command, keep in mind that some devices need a larger I/O request block size than a struct IORequest or a struct IOStdReq, that they will initialize the I/O request block, and that they dont check the io_Message.mn_Length field. To avoid accessing unallocated memory in such situations, use an I/O request block size of at least sizeof(struct IOStdRequest)+128 as suggested in the NewStyleDevice documentation. INPUTS devName - requested device name unitNumber - the unit number to open on that device. The format of the unit number is device specific. If the device does not have separate units, send a zero. iORequest - the I/O request block to be returned with appropriate fields initialized. flags - additional driver specific information. This is sometimes used to request opening a device with exclusive access. RESULTS error - Returns a sign-extended copy of the io_Error field of the IORequest. Zero if successful, else an error code is returned. BUGS AmigaDOS file names are not case sensitive, but Exec lists are. If the library name is specified in a different case than it exists on disk, unexpected results may occur. Prior to V36, tasks could not make OpenDevice calls requiring disk access (since tasks are not allowed to make dos.library calls). Now OpenDevice is protected from tasks. SEE ALSO CloseDevice, DoIO, SendIO, CheckIO, AbortIO, WaitIO exec.library/OpenLibrary exec.library/OpenLibrary NAME OpenLibrary -- gain access to a library SYNOPSIS library = OpenLibrary(libName, version) struct Library *OpenLibrary(STRPTR, ULONG); FUNCTION This function returns a pointer to a library that was previously installed into the system. If the requested library is exists, and if the library version is greater than or equal to the requested version, then the open will succeed. The library may exist in memory, or on disk; this is transparent to the OpenLibrary caller. Only Processes are allowed to call OpenLibrary (since OpenLibrary may in turn call dos.library). A full path name for the library name is legitimate. For example "wp:libs/wp.library". This allows the use of custom libraries without requiring the user to copy the library into the system's LIBS: directory. NOTES All calls to OpenLibrary should have matching calls to CloseLibrary! Libraries on disk cannot be opened until after DOS has been started. As of V36 tasks can safely call OpenLibrary, though DOS may open system requesters (e.g., asking the user to insert the Workbench disk if LIBS: is not online). You must call this function from a DOS Process if you want to turn off DOS requesters. INPUTS libName - the name of the library to open version - the version of the library required. RESULTS library - a library pointer for a successful open, else zero BUGS AmigaDOS file names are not case sensitive, but Exec lists are. If the library name is specified in a different case than it exists on disk, unexpected results may occur. Prior to V36, tasks could not make OpenLibrary calls requiring disk access (since tasks are not allowed to make dos.library calls). Now OpenLibrary is protected from tasks. The version number of the resident tag in disk based library must match the version number of the library, or V36 may fail to load it. SEE ALSO CloseLibrary exec.library/OpenResource exec.library/OpenResource NAME OpenResource -- gain access to a resource SYNOPSIS resource = OpenResource(resName) APTR OpenResource(STRPTR); FUNCTION This function returns a pointer to a resource that was previously installed into the system. There is no CloseResource() function. INPUTS resName - the name of the resource requested. RESULTS resource - if successful, a resource pointer, else NULL exec.library/Permit exec.library/Permit NAME Permit -- permit task rescheduling. SYNOPSIS Permit() void Permit(void); FUNCTION Allow other tasks to be scheduled to run by the dispatcher, after a matching Forbid() has been executed. RESULTS Other tasks will be rescheduled as they are ready to run. In order to restore normal task rescheduling, the programmer must execute exactly one call to Permit() for every call to Forbid(). NOTES This call is guaranteed to preserve all registers. SEE ALSO Forbid, Disable, Enable exec.library/Procure exec.library/Procure NAME Procure -- bid for a semaphore (V39) SYNOPSIS Procure(semaphore, bidMessage) VOID Procure(struct SignalSemaphore *, struct SemaphoreMessage *); FUNCTION This function is used to obtain a semaphore in an async manner. Like ObtainSemaphore(), it will obtain a SignalSemaphore for you but unlike ObtainSemaphore(), you will not block until you get the semaphore. Procure() will just post a request for the semaphore and will return. When the semaphore is available (which could be at any time) the bidMessage will ReplyMsg() and you will own the semaphore. This lets you wait on multiple semaphores at once and to continue processing while waiting for the semaphore. NOTE: Pre-V39, Procure() and Vacate() did not work correctly. They also did not operate on SignalSemaphore semaphores. Old (and broken) MessageSemaphore use as of V39 will no longer work. INPUT semaphore - The SignalSemaphore that you wish to Procure() bidMessage- The SemaphoreMessage that you wish replied when you obtain access to the semaphore. The message's ssm_Semaphore field will point at the semaphore that was obtained. If the ssm_Semaphore field is NULL, the Procure() was aborted via Vacate(). The mn_ReplyPort field of the message must point to a valid message port. To obtain a shared semaphore, the ln_Name field must be set to 1. For an exclusive lock, the ln_Name field must be 0. No other values are valid. BUGS Before V39, Procure() and Vacate() used a different semaphore system that was very broken. This new system is only available as of V39 even though the LVOs are the same. SEE ALSO ObtainSemaphoreShared(), InitSemaphore(), ReleaseSemaphore(), AttemptSemaphore(), ObtainSemaphoreList(), Vacate(), ObtainSemaphore() exec.library/PutMsg exec.library/PutMsg NAME PutMsg -- put a message to a message port SYNOPSIS PutMsg(port, message) void PutMsg(struct MsgPort *, struct Message *); FUNCTION This function attaches a message to the end of a given message port. It provides a fast, non-copying message sending mechanism. Messages can be attached to only one port at a time. The message body can be of any size or form. Because messages are not copied, cooperating tasks share the same message memory. The sender task must not recycle the message until it has been replied by the receiver. Of course this depends on the message handling conventions setup by the involved tasks. If the ReplyPort field is non-zero, when the message is replied by the receiver, it will be sent back to that port. Any one of the following actions can be set to occur when a message is put: 1. no special action 2. signal a given task (specified by MP_SIGTASK) 3. cause a software interrupt (specified by MP_SIGTASK) The action is selected depending on the value found in the MP_FLAGS of the destination port. INPUT port - pointer to a message port message - pointer to a message SEE ALSO GetMsg, ReplyMsg, exec/ports.h exec.library/RawDoFmt exec.library/RawDoFmt NAME RawDoFmt -- format data into a character stream. SYNOPSIS NextData = RawDoFmt(FormatString, DataStream, PutChProc, PutChData); APTR RawDoFmt(STRPTR,APTR,void (*)(),APTR); FUNCTION perform "C"-language-like formatting of a data stream, outputting the result a character at a time. Where % formatting commands are found in the FormatString, they will be replaced with the corresponding element in the DataStream. %% must be used in the string if a % is desired in the output. INPUTS FormatString - a "C"-language-like NULL terminated format string, with the following supported % options: %[flags][width.limit][length]type flags - only one allowed. '-' specifies left justification. width - field width. If the first character is a '0', the field will be padded with leading 0's. . - must follow the field width, if specified limit - maximum number of characters to output from a string. (only valid for %s). length - size of input data defaults to WORD for types d, x, and c, 'l' changes this to long (32-bit), while 'h' means short (the default, included for compatibiliy) type - supported types are: b - BSTR, data is 32-bit BPTR to byte count followed by a byte string, or NULL terminated byte string. A NULL BPTR is treated as an empty string. (Added in V36 exec) d - decimal u - unsigned decimal (Added in V37 exec) x - hexadecimal s - string, a 32-bit pointer to a NULL terminated byte string. In V36, a NULL pointer is treated as an empty string c - character p - pointer, written as if the format was 0x%08x DataStream - a stream of data that is interpreted according to the format string. Often this is a pointer into the task's stack. Character data must be passed as shorts (or longs when %lc is used). The function will take care not to throw alignment exceptions, however, it is advised not to use shorts anymore. The ability is just retained for backward compatibility. PutChProc - the procedure to call with each character to be output, called as: PutChProc(Char, PutChData); the procedure is called with a NULL Char at the end of the format string. Starting with V45.1, this pointer may be NULL. In that case, the default "stuffChar" procedure is used. This function will place any incoming character into a buffer pointer to by PutChData. PutChData - a value that is passed through to the PutChProc procedure. This is untouched by RawDoFmt, and may be modified by the PutChProc. RESULT Under V36, RawDoFmt() returns a pointer to the end of the DataStream (The next argument that would have been processed). This allows multiple formatting passes to be made using the same data. WARNING This Amiga ROM function formats word values in the data stream. If your compiler defaults to longs, you must add an "l" to your % specifications. This can get strange for characters, which might look like "%lc". The result of RawDoFmt() is *ONLY* valid in V36 and later releases of EXEC. Pre-V36 versions of EXEC have "random" return values. NOTE After locale.library is installed in the system, RawDoFmt() is in fact replaced by locale.library/FormatString(). Then the putChProc pointer will be handled as follows: - If it points to 68K code, this code will be called with putChData in A3 and the character to output in D0, the code has to return the modified putChData pointer in A3. Simplest function is "move.b d0,(a3)+" followed by "rts". - If it points to PPC code, this code will be called with "(*putChProc)(character, putChData)", the code does not have to modify putChData (no return code). - If it points to NULL, a default routine will be used. SEE ALSO Documentation on the C language "printf" call in any C language reference book. exec.library/ReallocVec exec.library/ReallocVec NAME ReallocVec -- change the size of previously allocated memory (V50) SYNOPSIS realSize = ReallocVec(memBlock, newSize, flags); ULONG ReallocVec(APTR, ULONG, ULONG); FUNCTION This function will try to re-allocate a given memory block that must have been allocated with AllocVec before. It will try to resize the block without moving it to another address. This may or may not be possible. If reallocation failed, the memory block is not de-allocated. The memory block must still be freed using FreeVec, regardless of the success or failure of the function. When enlarging the block, the contents of the additional memory is undefined. Don't assume that there's anything sensible. Also, don't assume that first shortening, then enlarging the block again will leave the additional memory intact. INPUTS memBlock - Pointer to the memory area to be resized. THIS BLOCK MUST BE ALLOCATED WITH AllocVec. AllocMem WILL NOT WORK. newSize - The new size for the memory block. Note that it can be larger or smaller than the original block. flags - Flags to change the mode of operation (Set to 0 for no flags): MEMF_LARGEST: When enlarging, try to allocate the largest possible block, even if it's not the size requested. RESULT The new size of the block is returned, or 0 if the re-allocation didn't work, EXAMPLE /* Allocate some memory */ APTR mem = IExec->AllocVec(10000, MEMF_ANY); ... /* Try reallocating it */ if (200000 == IExec->ReallocVec(mem, 200000, 0)) printf("mem is now 200000 bytes\n"); else printf("couldn't resize memory block\n"); SEE ALSO AllocVec, FreeVec exec.library/ReleaseSemaphore exec.library/ReleaseSemaphore NAME ReleaseSemaphore -- make signal semaphore available to others SYNOPSIS ReleaseSemaphore(signalSemaphore) void ReleaseSemaphore(struct SignalSemaphore *); FUNCTION ReleaseSemaphore() is the inverse of ObtainSemaphore(). It makes the semaphore lockable to other users. If tasks are waiting for the semaphore and this this task is done with the semaphore then the next waiting task is signalled. Each ObtainSemaphore() call must be balanced by exactly one ReleaseSemaphore() call. This is because there is a nesting count maintained in the semaphore of the number of times that the current task has locked the semaphore. The semaphore is not released to other tasks until the number of releases matches the number of obtains. Needless to say, havoc breaks out if the task releases more times than it has obtained. INPUT signalSemaphore -- an initialized signal semaphore structure BUGS In V39 and V40 Kickstart, there is an error condition that bumps ss_NestCount twice, if multiple Procure() SemaphoreMessages and a ObtainSemaphore() are pending for the same task. NOTE This call is guaranteed to preserve all registers. SEE ALSO InitSemaphore(), ObtainSemaphore(), ObtainSemaphoreShared() exec.library/ReleaseSemaphoreList exec.library/ReleaseSemaphoreList NAME ReleaseSemaphoreList -- make a list of semaphores available SYNOPSIS ReleaseSemaphoreList(list) void ReleaseSemaphoreList(struct List *); FUNCTION ReleaseSemaphoreList() is the inverse of ObtainSemaphoreList(). It releases each element in the semaphore list. Needless to say, havoc breaks out if the task releases more times than it has obtained. INPUT list -- a list of signal semaphores SEE ALSO ObtainSemaphoreList() exec.library/RemDevice exec.library/RemDevice NAME RemDevice -- remove a device from the system SYNOPSIS RemDevice(device) void RemDevice(struct Device *); FUNCTION This function calls the device's EXPUNGE vector, which requests that a device delete itself. The device may refuse to do this if it is busy or currently open. This is not typically called by user code. There are certain, limited circumstances where it may be appropriate to attempt to specifically flush a certain device. Example: /* Attempts to flush the named device out of memory. */ #include #include void FlushDevice(name) STRPTR name; { struct Device *result; Forbid(); if(result=(struct Device *)FindName(&SysBase->DeviceList,name)) RemDevice(result); Permit(); } INPUTS device - pointer to a device node SEE ALSO AddLibrary exec.library/RemHead exec.library/RemHead NAME RemHead -- remove the head node from a list SYNOPSIS node = RemHead(list) struct Node *RemHead(struct List *); FUNCTION Get a pointer to the head node and remove it from the list. Assembly programmers may prefer to use the REMHEAD macro from "exec/lists.i". WARNING This function does not arbitrate for access to the list. The calling task must be the owner of the involved list. INPUTS list - a pointer to the target list header RESULT node - the node removed or zero when empty list SEE ALSO AddHead, AddTail, Enqueue, Insert, Remove, RemTail exec.library/RemInterface exec.library/RemInterface NAME RemInterface -- Remove an interface from it's library (V50) SYNOPSIS RemInterface(interface); void RemInterface(struct Interface *); FUNCTION Remove an interface from whatever library it belongs to. INPUTS interface - the interface to be remove SEE ALSO CreateLibrary, MakeInterface, AddInterface exec.library/RemIntServer exec.library/RemIntServer NAME RemIntServer -- remove an interrupt server from a server chain SYNOPSIS RemIntServer(intNum, interrupt) void RemIntServer(ULONG,struct Interrupt *); FUNCTION This function removes an interrupt server node from the given server chain. If this server was the last one on this chain, interrupts for this chain are disabled. INPUTS intNum - the Paula interrupt bit (0..14) interrupt - pointer to an interrupt server node BUGS Before V36 Kickstart, the feature that disables the interrupt would not function. For most server chains this does not cause a problem. SEE ALSO AddIntServer, hardware/intbits.h exec.library/RemLibrary exec.library/RemLibrary NAME RemLibrary -- remove a library from the system SYNOPSIS RemLibrary(library) void RemLibrary(struct Library *); FUNCTION This function calls the library's EXPUNGE vector, which requests that a library delete itself. The library may refuse to do this if it is busy or currently open. This is not typically called by user code. There are certain, limited circumstances where it may be appropriate to attempt to specifically flush a certain Library. Example: /* Attempts to flush the named library out of memory. */ #include #include void FlushLibrary(name) STRPTR name; { struct Library *result; Forbid(); if(result=(struct Library *)FindName(&SysBase->LibList,name)) RemLibrary(result); Permit(); } INPUTS library - pointer to a library node structure exec.library/RemMemHandler exec.library/RemMemHandler NAME RemMemHandler - Remove low memory handler from exec (V39) SYNOPSIS RemMemHandler(memHandler) VOID RemMemHandler(struct Interrupt *); FUNCTION This function removes the low memory handler from the system. This function can be called from within a handler. If removing oneself, it is important that the handler returns MEM_ALL_DONE. NOTE When removing a handler, the handler may be called until this function returns. Thus, the handler must still be valid until then. INPUTS memHandler - Pointer to a handler added with AddMemHandler() SEE ALSO AddMemHandler, exec/interrupts.h exec.library/Remove exec.library/Remove NAME Remove -- remove a node from a list SYNOPSIS Remove(node) void Remove(struct Node *); FUNCTION Unlink a node from whatever list it is in. Nodes that are not part of a list must not be passed to this function! Assembly programmers may prefer to use the REMOVE macro from "exec/lists.i". WARNING This function does not arbitrate for access to the list. The calling task must be the owner of the involved list. INPUTS node - the node to remove NOTES As of V50, this function modifies the ln_Succ and ln_Pred pointers to prevent disaster from Removing a node twice. EXAMPLE /* If traversing 'list' with GetHead/GetSucc and nodes may at * some point be Remove()ed, it is not permitted to read any of * the node linkage fields after it has left the list, as removing * the node invalidates the list pointers, therefore, it is * necessary to determine the successor before removal. * Note; when using these functions, don't check the * currentNode->ln_Succ, just for currentNode != NULL. */ struct Node *currentNode, *nextNode; for (currNode=IExec->GetHead(list); currentNode != NULL; currentNode = nextNode) { nextNode = IExec->GetSucc(currentNode); /* Now do something with currentNode. */ /* This may include node removal from list. EG:- */ if( some_condition ) { IExec->Remove(currentNode); } } SEE ALSO AddHead, AddTail, Enqueue, Insert, RemHead, RemTail, GetHead, GetTail, GetSucc, GetPred. exec.library/RemPort exec.library/RemPort NAME RemPort -- remove a message port from the system SYNOPSIS RemPort(port) void RemPort(struct MsgPort *); FUNCTION This function removes a message port structure from the system's message port list. Subsequent attempts to rendezvous by name with this port will fail. INPUTS port - pointer to a message port SEE ALSO AddPort, FindPort exec.library/RemResetCallback exec.library/RemResetCallback NAME RemResetCallback -- Remoce a reset handler from the system (V50) SYNOPSIS void RemResetCallback(struct Interrupt *resetCallback); FUNCTION The given resetCallback is removed from the system. INPUTS resetCallback - A pointer to a reset callback that has been previously added with AddResetCallback. SEE ALSO ColdReboot(), AddResetCallback() exec.library/RemResource exec.library/RemResource NAME RemResource -- remove a resource from the system SYNOPSIS RemResource(resource) void RemResource(APTR); FUNCTION This function removes an existing resource from the system resource list. There must be no outstanding users of the resource. INPUTS resource - pointer to a resource node SEE ALSO AddResource exec.library/RemSemaphore exec.library/RemSemaphore NAME RemSemaphore -- remove a signal semaphore from the system SYNOPSIS RemSemaphore(signalSemaphore) void RemSemaphore(struct SignalSemaphore *); FUNCTION This function removes a signal semaphore structure from the system's signal semaphore list. Subsequent attempts to rendezvous by name with this semaphore will fail. INPUTS signalSemaphore -- an initialized signal semaphore structure SEE ALSO AddSemaphore, FindSemaphore exec.library/RemTail exec.library/RemTail NAME RemTail -- remove the tail node from a list SYNOPSIS node = RemTail(list) struct Node *RemTail(struct List *); FUNCTION Remove the last node from a list, and return a pointer to it. If the list is empty, return zero. Assembly programmers may prefer to use the REMTAIL macro from "exec/lists.i". WARNING This function does not arbitrate for access to the list. The calling task must be the owner of the involved list. INPUTS list - a pointer to the target list header RESULT node - the node removed or zero when empty list SEE ALSO AddHead, AddTail, Enqueue, Insert, Remove, RemHead, RemTail exec.library/RemTask exec.library/RemTask NAME RemTask -- remove a task from the system SYNOPSIS RemTask(task) void RemTask(struct Task *); FUNCTION This function removes a task from the system. Deallocation of resources should have been performed prior to calling this function. Removing some other task is very dangerous. Generally is is best to arrange for tasks to call RemTask(0L) on themselves. RemTask will automagically free any memory lists attached to the task's TC_MEMENTRY list. INPUTS task - pointer to the task node representing the task to be removed. A zero value indicates self removal, and will cause the next ready task to begin execution. BUGS Before V36 if RemTask() was called on a task other than the current task, and that task was created with amiga.lib/CreateTask, there was a slight chance of a crash. The problem can be hidden by bracketing RemTask() with Forbid()/Permit(). SEE ALSO AddTask, exec/AllocEntry, amiga.lib/DeleteTask exec.library/RemTrackable exec.library/RemTrackable NAME RemTrackable -- Remove a trackable object from a task (V50) SYNOPSIS trackable = RemTrackable(task, trackable); struct Trackable *RemTrackable(struct Task *, struct Trackable *); FUNCTION This function removes a given trackable from the tasks's context. Neither the object nor the trackable is deleted, it's just taken out of the tasks's context. INPUTS task - The task to remove from. A value of 0 means current task. trackable - The trackable object to remove. It's safe to pass 0, making constructs like this possible: IExec->RemTrackable(task, IExec->FindTrackable(object)); RESULT A pointer to the removed trackable is returned, or 0 if the trackable parameter was 0, or the trackable doesn't belong to this task. NOTES This function is manly used internally by the system, and is probably of no use for application programmers. SEE ALSO AddTrackable, FindTrackable, DeleteTrackable, AllocSysObject exec.library/ReplyMsg exec.library/ReplyMsg NAME ReplyMsg -- put a message to its reply port SYNOPSIS ReplyMsg(message) void ReplyMsg(struct Message *); FUNCTION This function sends a message to its reply port. This is usually done when the receiver of a message has finished and wants to return it to the sender (so that it can be re-used or deallocated, whatever). This call may be made from interrupts. INPUT message - a pointer to the message SEE ALSO GetMsg, PutMsg, exec/ports.h exec.library/RestartTask exec.library/RestartTask NAME RestartTask -- Restart a task that has been suspended (V50) SYNOPSIS RestartTask(whichTask, flags); void RestartTask(struct Task *, ULONG); FUNCTION This function puts a task that has been suspended back into active duty. If the task was waiting when it was suspended, it's moved to the waiting task list, otherwise, it's put into the ready list (even if it was running at the time it was suspended). If the task wasn't suspended, or it crashed, nothing is done. INPUTS whichTask - The task that is to be restarted. flags - Flags (reserved, set to 0) SEE ALSO SuspendTask exec.library/RMapAlloc exec.library/RMapAlloc NAME RMapAlloc -- Allocate from a resource map (V51) SYNOPSIS void *RMapAlloc(void *resourceMap, uint32 size, uint32 flags); FUNCTION This functon tries to allocate a range from the given resource map that is at least size large. If found, the interval is marked as used inside the resource map, and it's base "address" is returned. INPUTS resourceMap: A resource map to allocate from. size: Amount of space to be allocated from map. flags: Currently not used. RESULT The base "address" of the allocation. SEE ALSO RMapFree, AllocSysObject exec.library/RMapExtAlloc exec.library/RMapExtAlloc NAME RMapExtAlloc -- Allocate from a resource map with alignment (V51) SYNOPSIS void *RMapExtAlloc(void *resourceMap, uint32 size, uint32 alignment, uint32 flags); FUNCTION This functon tries to allocate a range from the given resource map that is at least size large, aligned to a specified alignment. If found, the interval is marked as used inside the resource map, and it's base "address" is returned. INPUTS resourceMap: A resource map to allocate from. size: Amount of space to be allocated from map. alignment: The required alignment. Note that alignments less than the quantum specified when creating the resource map are automatically aligned to the quantum size. flags: Currently not used. RESULT The base "address" of the allocation. NOTE Resources allocated with RMapExtAlloc must be freed with RMapExtFree SEE ALSO RMapExtFree, AllocSysObject exec.library/RMapExtFree exec.library/RMapExtFree NAME RMapExtFree -- Return a segment allocated by RMapExtAlloc (V51) SYNOPSIS void RMapExtFree(void *resourceMap, void *address, uint32 size); FUNCTION This function returns a given resource range previously allocated by RMapAlloc to the given map. INPUTS resourceMap: The map to return to address: The base "address" of the segment to be returned size: The size of the segment NOTE This function does not allow returning partial allocations. Trying to do this is considered an error and will result in undefined behavior. SEE ALSO RMapExtAlloc, AllocSysObject exec.library/RMapFree exec.library/RMapFree NAME RMapFree -- Return a segment to a resource map (V51) SYNOPSIS void RMapFree(void *resourceMap, void *address, uint32 size); FUNCTION This function returns a given resource range previously allocated by RMapAlloc to the given map. INPUTS resourceMap: The map to return to address: The base "address" of the segment to be returned size: The size of the segment NOTE This function does not allow returning partial allocations. Trying to do this is considered an error and will result in undefined behavior. SEE ALSO RMapAlloc, AllocSysObject exec.library/ScanNamedMemory exec.library/ScanNamedMemory NAME ScanNamedMemory -- Scan through existing objects and namespaces (V51) SYNOPSIS uint32 ScanNamedMemory(struct Hook *scHook, uint32 flags, APTR user); FUNCTION This function enables the user to scan through all namespaces and objects, or just the namespaces, depending on the flags. INPUTS scHook - A hook that is invoked with every namespace/named object. The hook will be invoked following normal hook calling rules. The message consists of the following structure: struct SNMMessage { STRPTR Namespace; STRPTR Name; APTR Memory; uint32 Size; uint32 Flags; }; The fields have the following meaning: Namespace Pointer to the namespace name (READ-ONLY) Name Pointer to the named block's name (READ-ONLY) Memory Pointer to the named block's memory. Size Size of the block, in bytes Flags Flags for this block (see AllocNamedMemory) Returning 0 from the hook function will continue the scan, while a return value not equal to 0 will abort the scan. The non-null value will also be returned by the function. flags - Flags indicating how the scanning process should be carried out. Currently, the following flags are defined: SNMF_NAMESPACES_ONLY Only scan namespaces, not named objects. The Name and Memory parts of the SNMMessage are NULL in that case. user - A pointer that will be passed verbatim to the hook function. RESULT The result will be the first non-null return value of the hook function to indicate a successful scan, or 0 if the hook function never returned anything but 0. Note that wheather or not this is an errror depends on the actual context. EXAMPLE /* This example prints our all available named memory blocks with * their parent namespace and addresses */ /* Hook function */ uint32 myMemScanHook(struct Hook *hook, APTR userdata, APTR message) { struct SNMMessage *scanMsg = (struct SNMMessage *)message; printf("Object %s in namespace %s at address %p\n", scanMsg->Name, scanMsg->Namespace, scanMsg->Memory); return 0; } /* Somewhere else... */ struct Hook scanHook; uint32 result; scanHook.h_Entry = myMemScanHook; result = IExec->ScanNamedMemory(&scanHook, 0, NULL); exec.library/SendIO exec.library/SendIO NAME SendIO -- initiate an I/O command SYNOPSIS SendIO(iORequest) void SendIO(struct IORequest *); FUNCTION This function requests the device driver start processing the given I/O request. The SendIO() function will return without waiting for the I/O to complete. The io_Flags field of the IORequest will be set to zero before the request is sent. NOTE Some device drivers require that certain bits in io_Flags are set for proper operations and will not work correctly if an IORequest is used with SendIO() because it sets io_Flags to zero before the request is sent. The audio.device is such a kind of device driver. For such device drivers BeginIO() must be used in place of SendIO() or even DoIO(). You must not call SendIO() on an IORequest that has never been successfully used with OpenDevice() and that is not a duplicate of an IORequest which was successfully used with OpenDevice(). If you use it on an IORequest that was just created with CreateIORequest() or which was just used with the CloseDevice() function, you will either cause your task to hang, or you may crash the operating system. INPUTS iORequest - pointer to an I/O request, or a device specific extended IORequest. SEE ALSO DoIO(), CheckIO(), WaitIO(), AbortIO(), BeginIO() exec.library/SetExcept exec.library/SetExcept NAME SetExcept -- define certain signals to cause exceptions SYNOPSIS oldSignals = SetExcept(newSignals, signalMask) ULONG SetExcept(ULONG,ULONG); FUNCTION This function defines which of the task's signals will cause a private task exception. When any of the signals occurs the task's exception handler will be dispatched. If the signal occurred prior to calling SetExcept, the exception will happen immediately. The user function pointed to by the task's tc_ExceptCode gets called as: newExcptSet = (SysBase, signals, exceptData) signals - The set of signals that caused this exception. These Signals have been disabled from the current set of signals that can cause an exception. exceptData - A copy of the task structure tc_ExceptData field. newExcptSet - The set of signals in NewExceptSet will be re- enabled for exception generation. Usually this will be the same as the Signals that caused the exception. INPUTS newSignals - the new values for the signals specified in signalMask. signalMask - the set of signals to be effected RESULTS oldSignals - the prior exception signals EXAMPLE Get the current state of all exception signals: SetExcept(0,0) Change a few exception signals: SetExcept($1374,$1074) SEE ALSO Signal, SetSignal exec.library/SetFunction exec.library/SetFunction NAME SetFunction -- change a function vector in a library SYNOPSIS oldFunc = SetFunction(library, funcOffset, funcEntry) APTR SetFunction(struct Library *,LONG,APTR); FUNCTION SetFunction is a functional way of changing where vectors in a library point. They are changed in such a way that the checksumming process will never falsely declare a library to be invalid. WARNING If you use SetFunction on a function that can be called from interrupts, you are obligated to provide your own arbitration. NOTE SetFunction cannot be used on non-standard libraries like pre-V36 dos.library. Here you must manually Forbid(), preserve all 6 original bytes, set the new vector, SumLibrary(), then Permit(). INPUTS library - a pointer to the library to be changed funcOffset - the offset of the function to be replaced funcEntry - pointer to new function RESULTS oldFunc - pointer to the old function that was just replaced exec.library/SetIntVector exec.library/SetIntVector NAME SetIntVector -- set a new handler for a system interrupt vector SYNOPSIS oldInterrupt = SetIntVector(intNumber, interrupt) struct Interrupt *SetIntVector(ULONG, struct Interrupt *); FUNCTION This function provides a mechanism for setting the system interrupt vectors. These are non-sharable; setting a new interrupt handler disconnects the old one. Installed handlers are responsible for processing, enabling and clearing the interrupt. Note that interrupts may have been left in any state by the previous code. The IS_CODE and IS_DATA pointers of the Interrupt structure will be copied into a private place by Exec. A pointer to the previously installed Interrupt structure is returned. Interrupt handlers are called with a 'C' compatible environment, i.e. all volatile registers are preserved. The protoype for an interrupt vector looks like this: void interruptHandler(struct ExceptionContext *Context, struct ExecBase *SysBase, void *UserData); Context is a pointer to the register storage area. Under normal conditions, only volatile register will have been saved, and the appropriate flag will be clear to reflect this. Note, though, that you have to be prepared to handle all cases (if you need access to the interrupted task's registers, anyway). Additionally, userData is the pointer to the user data field taken from the Interrupt's data structure. Starting with V50, and additional set of "interrupts" is availabe, enumerated in exec/interrupts.h, enTrapNumbers. INPUTS intNum - the Paula interrupt bit number (0..14). Only non-chained interrupts should be set. Use AddIntServer() for server chains. Some additional interrupt numbers might be present. Refer to the documentation of expansion.library for more information. interrupt - a pointer to an Interrupt structure containing the handler's entry point and data segment pointer. A NULL interrupt pointer will remove the current interrupt and set illegal values for IS_CODE and IS_DATA. By convention, the LN_NAME of the interrupt structure must point a descriptive string so that other users may identify who currently has control of the interrupt. RESULT A pointer to the prior interrupt structure which had control of this interrupt. SEE ALSO AddIntServer(),exec/interrupts.i,hardware/intbits.i exec.library/SetMethod exec.library/SetMethod NAME SetMethod -- Modify a method in an interface SYNOPSIS old_func = SetMethod(interface, funcOffset, newFunc); APTR SetMethod(struct Interface *, LONG, APTR); FUNCTION This function will override a method in an interface with another method. It will fail if the interface is protected from SetMethod. INPUTS interface - Pointer to the interface to be modified funcOffset - Offset of the method to be modified, measured from the start of the interface newFunc - New method to be stored in this place RESULT The old value of the method is returned. This might be NULL. A value of NULL means that either the method was NULL, or the interface was protected from modification. EXAMPLE void new_foo_method(struct SomeInterface *if, ...); IExec->SetMethod(myInterface, offsetof(struct SomeInterface, foo), new_foo_method); NOTE THIS FUNCTION IS DANGEROUS. Don't use it. It's main purpose is to provide ways for debuggers to hook into interfaces. exec.library/SetSignal exec.library/SetSignal NAME SetSignal -- define the state of this task's signals SYNOPSIS oldSignals = SetSignal(newSignals, signalMask) ULONG SetSignal(ULONG,ULONG); FUNCTION This function can query or modify the state of the current task's received signal mask. Setting the state of signals is considered dangerous. Reading the state of signals is safe. INPUTS newSignals - the new values for the signals specified in signalSet. signalMask - the set of signals to be affected. RESULTS oldSignals - the prior values for all signals EXAMPLES Get the current state of all signals: SetSignal(0L,0L); Clear the CTRL-C signal: SetSignal(0L,SIGBREAKF_CTRL_C); Check if the CTRL-C signal was pressed: #include /* Check & clear CTRL_C signal */ if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { printf("CTRL-C pressed!\n"); } SEE ALSO Signal, Wait exec.library/SetSR exec.library/SetSR NAME SetSR -- get and/or set processor status register (Obsolete) SYNOPSIS oldSR = SetSR(newSR, mask) ULONG SetSR(ULONG, ULONG); FUNCTION This function provides a means of modifying the CPU status register in a "safe" way (well, how safe can a function like this be anyway?). This function will only affect the status register bits specified in the mask parameter. The prior content of the entire status register is returned. INPUTS newSR - new values for bits specified in the mask. All other bits are not effected. mask - bits to be changed RESULTS oldSR - the entire status register before new bits EXAMPLES To get the current SR: currentSR = SetSR(0,0); To change the processor interrupt level to 3: oldSR = SetSR($0300,$0700); Set processor interrupts back to prior level: SetSR(oldSR,$0700); NOTE From V50 upward, this function will do nothing except returning 0 an generating an Alert exec.library/SetTaskPri exec.library/SetTaskPri NAME SetTaskPri -- get and set the priority of a task SYNOPSIS oldPriority = SetTaskPri(task, priority) BYTE SetTaskPri(struct Task *, BYTE); FUNCTION This function changes the priority of a task regardless of its state. The old priority of the task is returned. A reschedule is performed, and a context switch may result. To change the priority of the currently running task, pass the result of FindTask(0); as the task pointer. INPUTS task - task to be affected priority - the new priority for the task RESULT oldPriority - the tasks previous priority exec.library/SetTaskTrap exec.library/SetTaskTrap NAME SetTaskTrap -- Set a task-local trap handler (V50) SYNOPSIS success = SetTaskTrap(trapNum, trapCode, trapData); BOOL SetTaskTrap(ULONG, APTR, APTR); FUNCTION Starting with Exec V50, trap handling is changed from one generic entry point (task->tc_TrapCode) to multiple entry points, which are called depending on the actual trap that occured. Task traps are a way of installing task-local exception handlers for seperate classes of trap conditions (for example, illegal instructions, trap instructions, or protection faults). A trap is called with the following prototype: ULONG trapCode(struct ExceptionContext *context, struct ExecBase *sb, APTR trapData); struct ExceptionContext contains the registers that are considered volatile in the ABI. If you modify these, their values are written back into the apropriate registers when returning from the trap. Directly modifying the registers will only work for non-volatile registers. This method allows trap handlers to be written in C. If the handler successfully handled the trap, return 1, otherwise, returning 0 will result in the program to be aborted. Note that the trap is executed in the same environment as an interrupt. Therefore, the amount of system functionality that can be called is limited. INPUTS trapNum - a trap number (see exec/interrupts.h, enum enTrapNumbers) trapCode - pointer to the code to be executed when the trap is encountered. Passing in NULL will fall back to the system default handler. trapData - pointer to the trap handler's private data. This will just be passed to your trapCode when the trap is encountered. RESULT If the trap handler was successfully installed, TRUE is returned, else FALSE exec.library/Signal exec.library/Signal NAME Signal -- signal a task SYNOPSIS Signal(task, signals) void Signal(struct Task *,ULONG); FUNCTION This function signals a task with the given signals. If the task is currently waiting for one or more of these signals, it will be made ready and a reschedule will occur. If the task is not waiting for any of these signals, the signals will be posted to the task for possible later use. A signal may be sent to a task regardless of whether it is running, ready, or waiting. This function is considered "low level". Its main purpose is to support multiple higher level functions like PutMsg. This function is safe to call from interrupts. INPUT task - the task to be signalled signals - the signals to be sent SEE ALSO Wait, SetSignal exec.library/StackSwap exec.library/StackSwap NAME StackSwap - EXEC supported method of replacing task's stack (V37) SYNOPSIS StackSwap(newStack) VOID StackSwap(struct StackSwapStruct *); FUNCTION This function will, in an EXEC supported manner, swap the stack of your task with the given values in StackSwap. The StackSwapStruct structure will then contain the values of the old stack such that the old stack can be restored. This function is new in V37. NOTES If you do a stack swap, only the new stack is set up. This function does not copy the stack or do anything else other than set up the new stack for the task. It is generally required that you restore your stack before exiting. INPUTS newStack - A structure that contains the values for the new upper and lower stack bounds and the new stack pointer. This structure will have its values replaced by those in you task such that you can restore the stack later. RESULT newStack - The structure will now contain the old stack. This means that StackSwap(foo); StackSwap(foo); will effectively do nothing. SEE ALSO AddTask, RemTask, exec/tasks.h exec.library/StartDMA exec.library/StartDMA NAME StartDMA -- Prepare for a hardware DMA access (V50) SYNOPSIS size = StartDMA(startAddr, blockSize, flags); ULONG StartDMA(APTR, ULONG, ULONG); FUNCTION This function takes appropriate actions so that DMA capable hardware can initiate a DMA transfer. The actual action taken depends on various factors, including CPU and memory type. The following conditions are guaranteed to be met: - The memory region given is guaranteed to be mapped to physical memory. - The mapping will not change as long as EndDMA is not called. - All cache entries in this region will be flushed out. However, adjacent virtual addresses might not be adjacent in pyhsical memory. Therefore, an array of struct DMAEntry is used: Each entry describes one block of continous memory. Addresses in this array are sorted with ascending virtual address. All addresses given in the array are physical (see example below). The array must be allocated by client code, and passed to the GetDMAList function. This function will fill the client-provided array with the appropriate data (see the AutoDoc of GetDMAList for further details). INPUTS startAddr - The virtual start address of the area to which DMA should take place. blockSize - The length of the block in virtual addressed bytes. flags - Flags. Currently allowed flags are: DMAF_ReadFromRAM - Initiate a DMA operation that will be a read access, i.e. the data flow will go from RAM to the DMA device. RESULT size - The number of entries the DMA block list will have. The actual size the client needs to allocate is at least size * sizeof(struct DMAList). If the size is 0, an error occured, and the DMA operation must be aborted. EXAMPLE /* * This example assumes you want to make a DMA write transfer to * addr, size bytes */ ULONG arraySize; struct DMAEntry *DMAList; ULONG endFlags = 0; /* Tell the system to prepare for DMA */ arraySize = IExec->StartDMA(addr, size, 0); if (0 != arraySize) { /* The memory area is prepared, allocate and retrieve the DMA list */ DMAList = (struct DMAList *) IExec->AllocSysObject(ASOT_DMAENTRY, ASODMAE_NumEntries, arraySize, TAG_DONE); if (NULL != DMAList) { IExec->GetDMAList(addr, size, 0, DMAList); /* Feed the DMA controller and do stuff */ ... /* Get rid of the DMAList's memory */ IExec->FreeSysObject(ASOT_DMAENTRY, DMAList); } else { printf("Can't allocate DMA list\n"); endFlags |= DMAF_NoModify; } /* * Note: We still call EndDMA even though the actual transfer * didn't happen. */ IExec->EndDMA(addr, size, endFlags); } else { printf("Can't initiate DMA transfer\n"); } NOTE Every _succesful_ call to StartDMA *must* be paired with a call to EndDMA with the same address and size. Additionally, all flags given to StartDMA must also be given to EndDMA. SEE ALSO EndDMA, GetDMAList, CachePreDMA, CachePostDMA exec.library/SumInterface exec.library/SumInterface NAME SumInterface -- calculate the checksum of an interface (V50) SYNOPSIS SumInterface(interface); void SumInterface(struct Interface *); FUNCTION This function calculates the checksum from the invariant parts of an interface. If the interface has its IFLF_CHANGED flag not set, and the checksums do not match, the exec.library/Alert function will be called. INPUTS interface - A pointer to the interface to be checksummed SEE ALSO exec.library/SetFunction(), exec.library/SetMethod() exec.library/SumKickData exec.library/SumKickData NAME SumKickData -- compute the checksum for the Kickstart delta list SYNOPSIS checksum = SumKickData() ULONG SumKickData(void); FUNCTION The Amiga system has some ROM (or Kickstart) resident code that provides the basic functions for the machine. This code is unchangeable by the system software. This function is part of a support system to modify parts of the ROM. The ROM code is linked together at run time via ROMTags (also known as Resident structures, defined in exec/resident.h). These tags tell Exec's low level boot code what subsystems exist in which regions of memory. The current list of ROMTags is contained in the ResModules field of ExecBase. By default this list contains any ROMTags found in the address ranges $F80000-$FFFFFF and $F00000-$F7FFFF. There is also a facility to selectively add or replace modules to the ROMTag list. These modules can exist in RAM, and the memory they occupy will be deleted from the memory free list during the boot process. SumKickData() plays an important role in this run-time modification of the ROMTag array. Three variables in ExecBase are used in changing the ROMTag array: KickMemPtr, KickTagPtr, and KickCheckSum. KickMemPtr points to a linked list of MemEntry structures. The memory that these MemEntry structures reference will be allocated (via AllocAbs) at boot time. The MemEntry structure itself must also be in the list. KickTagPtr points to a long-word array of the same format as the ResModules array. The array has a series of pointers to ROMTag structures. The array is either NULL terminated, or will have an entry with the most significant bit (bit 31) set. The most significant bit being set says that this is a link to another long-word array of ROMTag entries. This new array's address can be found by clearing bit 31. KickCheckSum has the result of SumKickData(). It is the checksum of both the KickMemPtr structure and the KickTagPtr arrays. If the checksum does not compute correctly then both KickMemPtr and KickTagPtr will be ignored. If all the memory referenced by KickMemPtr can't be allocated then KickTagPtr will be ignored. There is one more important caveat about adding ROMTags. All this ROMTag magic is run very early on in the system -- before expansion memory is added to the system. Therefore any memory in this additional ROMTag area must be addressable at this time. This means that your ROMTag code, MemEntry structures, and resident arrays cannot be in expansion memory. There are two regions of memory that are acceptable: one is chip memory, and the other is "Ranger" memory (memory in the range between $C00000-$D80000). Remember that changing an existing ROMTag entry falls into the "heavy magic" category -- be very careful when doing it. The odd are that you will blow yourself out of the water. NOTES SumKickData was introduced in the 1.2 release RESULT Value to be stuffed into ExecBase->KickCheckSum. WARNING After writing to KickCheckSum, you should push the data cache. This prevents potential problems with large copyback style caches. A call to CacheClearU will do fine. SEE ALSO InitResident, FindResident exec.library/SumLibrary exec.library/SumLibrary NAME SumLibrary -- compute and check the checksum on a library SYNOPSIS SumLibrary(library) void SumLibrary(struct Library *); FUNCTION SumLibrary computes a new checksum on a library. It can also be used to check an old checksum. If an old checksum does not match, and the library has not been marked as changed, then the system will call Alert(). This call could also be periodically made by some future system-checking task. INPUTS library - a pointer to the library to be changed NOTE An alert will occur if the checksum fails. SEE ALSO SetFunction exec.library/SuperState exec.library/SuperState NAME SuperState -- enter supervisor state with user stack SYNOPSIS oldSysStack = SuperState() APTR SuperState(void); FUNCTION Enter supervisor mode while running on the user's stack. The user still has access to user stack variables. Be careful though, the user stack must be large enough to accommodate space for all interrupt data -- this includes all possible nesting of interrupts. This function does nothing when called from supervisor state. RESULTS oldSysStack - system stack pointer; save this. It will come in handy when you return to user state. If the system is already in supervisor mode, oldSysStack is zero. NOTE Starting from V50, supervisor and user mode use the same stack. SEE ALSO UserState, Supervisor exec.library/Supervisor exec.library/Supervisor NAME Supervisor -- trap to a short supervisor mode function SYNOPSIS result = Supervisor(userFunc) ULONG Supervisor(void *); FUNCTION Allow a normal user-mode program to execute a short function in the supervisor mode of the processor. INPUTS userFunc - A pointer to a short function. Normal ABI rules apply. The prototype for the function looks like this: ULONG userFunc(struct ExecIFace *); The Exec main interface will be passed for convenience. RESULTS result - Whatever values the userFunc left in the registers. SEE ALSO SuperState,UserState exec.library/SuspendTask exec.library/SuspendTask NAME SuspendTask -- Suspend a task from execution (V50) SYNOPSIS void SuspendTask(struct Task *whichTask, uint32 flags); FUNCTION Calling SuspendTask will prevent the given task from further execution. It will not be rescheduled until restarted. This also means that even though it can receive further signals, it will not wake up. It's possible for a running task to suspend itself. However, there's no possibility for a self-suspended task to wake up again unless another task or the system restarts it. INPUTS whichTask - The task to suspend. If 0, the current task is supended. flags - Flags. Currently defined flags are: STF_CRASHED Mark the task as crashed instead of suspended. STF_REMOVED Mark the task as removed for subsequent reaping. Suspending self will also automatically signal the reaper. NOTES Since 53.45 the behavior of STF_CRASHED has been changed to also automatically signal the reaper. The GrimReaper is capable of restarting a crashed task. SEE ALSO RestartTask exec.library/TypeOfMem exec.library/TypeOfMem NAME TypeOfMem -- determine attributes of a given memory address SYNOPSIS attributes = TypeOfMem(address) ULONG TypeOfMem(void *); FUNCTION Given a RAM memory address, search the system memory lists and return its memory attributes. The memory attributes are similar to those specified when the memory was first allocated: (eg. MEMF_CHIP and MEMF_FAST). This function is usually used to determine if a particular block of memory is within CHIP space. If the address is not in known-space, a zero will be returned. (Anything that is not RAM, like the ROM or expansion area, will return zero. Also the first few bytes of a memory area are used up by the MemHeader.) INPUT address - a memory address RESULT attributes - a long word of memory attribute flags. If the address is not in known RAM, zero is returned. SEE ALSO AllocMem() exec.library/UnlockMem exec.library/UnlockMem NAME UnlockMem -- Unlock an address (V50) SYNOPSIS UnlockMem(baseAddress, size); UnlockMem(APTR, ULONG); FUNCTION Calling this function will reverse the effect of a previous Lock. In other words, the memory is marked as being available for remapping, swapping, or other memory operations that interfere with mapping. INPUTS baseAddress - Base address of the memory region to lock size - Size of the region to lock NOTES Memory locking is nested. This means that for each time you lock memory, it must be unlocked. It's not necessary to unlock all in one go, but you must make sure that all addresses that have been locked are unlocked (don't assume that you know the granularity of this operation... you don't). SEE ALSO LockMem exec.library/UnlockNamedMemory exec.library/UnlockNamedMemory NAME UnlockNamedMemory -- Revoke lock of a named memory block (V51) SYNOPSIS void UnlockNamedMemory(STRPTR space, STRPTR name); FUNCTION A call to this function will revoke a previously obtained lock of a named memory block. Every successful call to LockNamedMemory or AttemptNamedMemory MUST be paired with an appropriate call to UnlockNamedMemory. INPUTS space - Namespace to search for the block. name - Name of the block to update. SEE ALSO AllocNamedMemory, FreeNamedMemory, FindNamedMemory, LockNamedMemory, AttemptNamedMemory exec.library/UpdateNamedMemory exec.library/UpdateNamedMemory NAME UpdateNamedMemory -- Recalculate checksum for named memory block (V51) SYNOPSIS void UpdateNamedMemory(STRPTR space, STRPTR name); FUNCTION This function recalculates the checksum for a given named memory block. If the name pointer is NULL or the named block does not exist, this function does nothing. INPUTS space - Namespace to search for the block. name - Name of the block to update. SEE ALSO AllocNamedMemory, FreeNamedMemory, FindNamedMemory NOTE This function does not arbitrate for access of the block exec.library/UserState exec.library/UserState NAME UserState -- return to user state with user stack SYNOPSIS UserState(sysStack) void UserState(APTR); FUNCTION Return to user state with user stack, from supervisor state with user stack. This function is normally used in conjunction with the SuperState function above. This function must not be called from the user state. INPUT sysStack - supervisor stack pointer BUGS This function is broken in V33/34 Kickstart. Fixed in V1.31 setpatch. SEE ALSO SuperState/Supervisor exec.library/Vacate exec.library/Vacate NAME Vacate -- release a bitMessage from Procure() (V39) SYNOPSIS Vacate(semaphore, bidMessage) void Vacate(struct SignalSemaphore *,struct SemaphoreMessage *); FUNCTION This function can be used to release a semaphore obtained via Procure(). However, the main purpose for this call is to be able to remove a bid for a semaphore that has not yet responded. This is required when a Procure() was issued and the program no longer needs to get the semaphore and wishes to cancel the Procure() request. The canceled request will be replied with the ssm_Semaphore field set to NULL. If you own the semaphore, the message was already replied and only the ssm_Semaphore field will be cleared. NOTE: Pre-V39, Procure() and Vacate() did not work correctly. They also did not operate on SignalSemaphore semaphores. Old (and broken) MessageSemaphore use as of V39 will no longer work. INPUT semaphore - The SignalSemaphore that you wish to Vacate() bidMessage- The SemaphoreMessage that you wish to abort. The message's ssm_Semaphore field will be cleared. The message will be replied if it is still on the waiting list. If it is not on the waiting list, it is assumed that the semaphore is owned and it will be released. BUGS Before V39, Procure() and Vacate() used a different semaphore system that was very broken. This new system is only available as of V39 even though the LVOs are the same. SEE ALSO ObtainSemaphoreShared(), InitSemaphore(), ReleaseSemaphore(), AttemptSemaphore(), ObtainSemaphoreList(), Procure(), ObtainSemaphore() exec.library/Wait exec.library/Wait NAME Wait -- wait for one or more signals SYNOPSIS signals = Wait(signalSet) ULONG Wait(ULONG); FUNCTION This function will cause the current task to suspend waiting for one or more signals. When one or more of the specified signals occurs, the task will return to the ready state, and those signals will be cleared. If a signal occurred prior to calling Wait(), the wait condition will be immediately satisfied, and the task will continue to run without delay. CAUTION This function cannot be called while in supervisor mode or interrupts! This function will break the action of a Forbid() or Disable() call. INPUT signalSet - The set of signals for which to wait. Each bit represents a particular signal. RESULTS signals - the set of signals that were active exec.library/WaitIO exec.library/WaitIO NAME WaitIO -- wait for completion of an I/O request SYNOPSIS error = WaitIO(iORequest) BYTE WaitIO(struct IORequest *); FUNCTION This function waits for the specified I/O request to complete, then removes it from the reply port. If the I/O has already completed, this function will immediately remove the I/O request from the reply port without waiting first. This function should be used with care, as it does not return until the I/O request completes; if the I/O never completes, this function will never return, and your task will hang. If this situation is a possibility, it is safer to use the Wait() function. Wait() will return return when any of a specified set of signal is received. This is how I/O timeouts can be properly handled. Note that WaitIO() will not work on I/O requests that haven't been used before. Only use WaitIO() with I/O requests which have been started via SendIO() or BeginIO(). If you did not start the I/O request with either SendIO() or BeginIO(), do not call WaitIO() since it will hang. WARNING If this IORequest was "Quick" or otherwise finished BEFORE this call, this function immediately removes the IORequest, with no call to Wait(). A side effect is that the signal bit related the port may remain set. Expect this. One way to work around WaitIO() not clearing the signal bit is to clear it with SetSignal() before SendIO() or BeginIO() is called. When removing a known complete IORequest from a port, WaitIO() is the required. A simple Remove() is not enough. INPUTS iORequest - pointer to an I/O request block RESULTS error - zero if successful, else an error is returned (a sign extended copy of IORequest->io_Error). BUGS Previous documentation suggested that WaitIO() immediately returned if the I/O request had already completed, and would not even remove the I/O request from the reply port. This was never the case. The documentation now clarifies the context. SEE ALSO DoIO(), SendIO(), CheckIO(), AbortIO() exec.library/WaitPort exec.library/WaitPort NAME WaitPort -- wait for a given port to be non-empty SYNOPSIS message = WaitPort(port) struct Message *WaitPort(struct MsgPort *); FUNCTION This function waits for the given port to become non-empty. If necessary, the Wait() function will be called to wait for the port signal. If a message is already present at the port, this function will return immediately. The return value is always a pointer to the first message queued (but it is not removed from the queue). CAUTION More than one message may be at the port when this returns. It is proper to call the GetMsg() function in a loop until all messages have been handled, then wait for more to arrive. To wait for more than one port, combine the signal bits from each port into one call to the Wait() function, then use a GetMsg() loop to collect any and all messages. It is possible to get a signal for a port WITHOUT a message showing up. Plan for this. INPUT port - a pointer to the message port RETURN message - a pointer to the first available message SEE ALSO GetMsg