The Pandora object kernel is a function library that provides the features
expected of a traditional kernel, while also providing a fully featured object
oriented programming interface. This makes it a unique hybrid that allows for
better portability and services. Support for the management of memory and
resources are all present, plus you will also find extensive support for class
management and field and object handling.
The portability of the object kernel has been ensured by keeping the
functions as generalised as possible. Depending on the intended platform, the
object kernel can be developed to run independently (i.e. as a real kernel) or
it can leech functionality from a dedicated kernel (as is the case with the
Linux version). It is vital that when running on a host environment that the
temptation to use the host's functions are avoided, or you will lose
compatibility with other computer systems running the Pandora Engine.
For summarised information about how the system works, please refer to the
General Documentation which covers all aspects of the design and object
orientation in the system. From here on in the subject matter is very
technical, so if you do not have any background knowledge of the Pandora
Engine, please read the beginner manuals before continuing.
| Function Index |
| AccessMemory | Grants access to public memory blocks. |
| AccessObject | Grants exclusive access to public objects. |
| AccessSemaphore | Grants access to semaphores. |
| Action | This function is responsible for executing action routines. |
| ActionList | Returns a pointer to the kernel's most current action table. |
| ActionMsg | Provides a mechanism for sending actions to objects that belong to other tasks. |
| ActionTags | This is a tag-based version of the Action() function. |
| AllocMemory | Allocates system memory blocks. |
| AllocSemaphore | Allocates a new public semaphore. |
| AllocateClassID | Generates dynamic class ID's. |
| AllocateID | Generates unique ID's for various purposes within the Pandora Engine. |
| CheckAction | Checks objects to see whether or not they support certain actions. |
| CheckMemoryExists | Checks if a memory block still exists. |
| CheckObjectExists | Checks if a particular object is still available in the system. |
| ClearMemory | Clears large blocks of memory very quickly. |
| CloneMemory | Makes an exact duplicate of a memory block. |
| CreateObject | Provides a fast way of creating and initialising new objects. |
| CurrentContext | Returns a pointer to the object that has the current context. |
| CurrentTaskID | Returns the object ID of the current Task. |
| DPrintF | Sends formatted strings to the debugger. |
| DebugState | Turns debug messages on and off. |
| DeregisterFD | Removes previously register FD's from the system. |
| FastFindObject | Searches for objects by name. |
| FindClass | Returns all class objects for a given class ID. |
| FindObject | Searches for objects by name and class. |
| FindPrivateObject | Searches for objects by name. |
| Forbid | Locks other tasks out of the shared memory and object areas. |
| FreeMemory | Frees private memory blocks allocated from AllocMemory(). |
| FreeMemoryID | Frees public memory blocks allocated from AllocMemory(). |
| FreeSemaphore | Frees an allocated semaphore. |
| GetClassID | Returns the class ID of an object. |
| GetField | Retrieves single field values from objects. |
| GetFieldVariable | Retrieves field values by converting them into strings. |
| GetFields | Retrieves multiple field values in a single function call. |
| GetMessage | Reads messages from message queues. |
| GetName | Retrieves object names. |
| GetOwnerID | Returns the unique ID of an object's owner. |
| GetResource | Retrieves miscellaneous resource identifiers. |
| ListChildren | Returns a list of all children belonging to an object. |
| ListMemory | Returns a list of public or private memory blocks that have been allocated in the system. |
| ListObjects | Returns a list of objects that match specific parameters. |
| ManageAction | Allows modules to intercept and manage action calls. |
| MemoryIDInfo | Returns information on memory ID's. |
| MemoryPtrInfo | Returns information on memory addresses. |
| NewObject | Creates new objects. |
| NotifySubscribers | Used to send notification messages to action subscribers. |
| ObtainMethod | Returns a direct pointer to an object's method code. |
| Permit | Releases a lock obtained from Forbid(). |
| ProcessMessages | Processes system messages that are queued in the Task's message buffer. |
| RandomNumber | Generates random numbers. |
| ReallocMemory | Reallocates memory blocks. |
| RegisterFD | Registers a file descriptor for monitoring when the task is asleep. |
| ReleaseMemory | Releases memory blocks from access locks. |
| ReleaseObject | Releases objects from exclusive use. |
| ReleaseSemaphore | Releases a locked semaphore. |
| ResolveClassName | Used to resolve unique class ID's from class names. |
| ResolveFields | Converts field names into globally supported Field ID's. |
| ScanMessages | Scans a message queue for multiple occurances of a message type. |
| SelfDestruct | Destroys the task and frees its resources. |
| SendError | Sends basic error messages to the active debugger. |
| SendMessage | Send messages to message queues. |
| SetContext | Tells the system which object currently has resource control. |
| SetField | Used to set field values of objects. |
| SetFieldVariable | Sets any field using an abstract string value. |
| SetFields | Sets the values of multiple object fields. |
| SetName | Sets the name of an object. |
| SetOwner | Changes object ownership dynamically. |
| SetResource | Sets miscellaneous resource identifiers. |
| StepBack | Steps back the debugging tree. |
| StrCompare | Compares strings to see if they are identical. |
| SubscribeAction | Listens for actions that may be performed on an object. |
| SubscribeActionTags | Listens for actions that may be performed on an object. |
| SubscribeChannel | Listens to an object's incoming data port. |
| SubscribeField | Listens to field read/write activity in an object. |
| SubscribeTimer | Subscribes an object to the system's timer service. |
| SystemTime | Returns the current system time, in milliseconds. |
| TotalChildren | Calculates the total number of children belonging to an object. |
| UnsubscribeAction | Removes action subscriptions from external objects. |
| UnsubscribeChannel | Removes data channel subscriptions from an external object. |
| UnsubscribeField | Removes field-based subscriptions from an object. |
| UnsubscribeTimer | Unsubscribes an object from the system's timer service. |
| UpdateMessage | Updates the data of any message that is queued. |
| WaitTime | Waits for a specified amount of seconds and/or microseconds. |
| WatchPublicMemory | Monitors public memory blocks for foreign access. |
| ActionList() |
| Returns a pointer to the kernel's most current action table. |
| struct ActionTable * ActionList(void) |
|
If you need a dynamic list of all the actions supported by the object
kernel, including information on ID's, names, arguments and structure sizes,
use the ActionList() function. This function will return an array that is
arranged into a look-up table, sorted by action ID. The ActionTable structure
is defined as follows:
struct ActionTable {
STRING Name;
struct FunctionField *Args;
LONG Size;
};
The Name field specifies the name of the action. The Args field refers
to the action's argument definition structure, which lists the argument names
and their relevant types. This is matched by the Size field, which indicates
the byte-size of the action's related argument structure. If the action does
not support arguments, the Args and Size fields will be set to NULL. Here
are two argument definition examples:
struct FunctionField argsCopyData[] = {
{ "Destination", ARG_LONG },
{ NULL, NULL }
};
struct FunctionField argsResize[] = {
{ "Width", ARG_DOUBLE },
{ "Height", ARG_DOUBLE },
{ "Depth", ARG_DOUBLE },
{ NULL, NULL }
};
The argument types that can be set by actions are limited to those listed in
the following table:
| ARG_LONG | A 32-bit integer value ranging from -2,147,483,647 to
2,147,483,648. |
| ARG_LARGE | A 64-bit integer value. |
| ARG_PTR | A standard 32-bit address space pointer. |
| ARG_STRING | A 32-bit address space pointer that refers to a
null-terminated string. |
| ARG_DOUBLE | A 64-bit floating point value. |
| ARG_OBJECT | This flag is sometimes set in conjunction with the
ARG_LONG type. It indicates that the argument refers to an object ID. |
| ARG_PTRSIZE | This argument type can only be used if it follows
an ARG_PTR type, and if the argument itself is intended to reflect the size
of the buffer referred to by the previous ARG_PTR argument. |
| ARG_RESULT | This special flag is set in conjunction with the
other data-based argument types. Example: If the developer is required to supply a
pointer to a LONG field in which the function will store a result, the correct
argument definition will be ARG_RESULT|ARG_LONG|ARG_PTR. To make the definition
of these argument types easier, ARG_PTRRESULT, ARG_LONGRESULT and
ARG_FLOATRESULT macros are also available for use. |
Result
This function returns a pointer to the object kernel's action table (struct ActionTable *). If a failure occurs, NULL will be returned. Please note that the first entry in the ActionTable list has all fields driven to NULL, because valid action ID's start from one, not zero. The final action in the list is also terminated with NULL fields in order to indicate an end to the list. Knowing this can be helpful if you wish to search the list or calculate the total number of actions supported by the kernel. |
|
|
| AllocMemory() |
| Allocates system memory blocks. |
| ERROR AllocMemory(LONG Size, LONG Flags, APTR *Address, MEMORYID *MemoryID) |
| Size | The size of the memory block. |
| Flags | Flag specifications - set to NULL to allocate a standard data memory block. |
| Address | Set this argument to refer to an APTR type to store an address reference to the allocated memory block. |
| MemoryID | Set this argument to refer to a MEMORYID type to store a unique ID reference to the allocated memory block. This is compulsory when allocating public memory blocks. |
|
|
The AllocMemory() function is used to allocate blocks of memory from the
system memory pool. To allocate a new block you need to specify its Size,
allocation Flags and Address and/or MemoryID arguments to store references to
the allocation. Here is an example:
APTR Address;
if (AllocMemory(1000, MEM_DATA, &Address, NULL) IS ERR_Okay) {
...
FreeMemory(Address);
}
A number of flag definitions are available that affect the memory
allocation process. They are:
| MEM_DATA | The default type, MEM_DATA, is used to indicate a standard memory allocation from system RAM. |
| MEM_PUBLIC | Public memory can be allocated by specifying this flag. Public memory blocks are accessible by all tasks, but access can only be gained by knowing the unique memory ID and utilising the AccessMemory() function. |
| MEM_CODE | If the memory will contain executable program code, set this flag. |
| MEM_UNTRACKED | Allocating an untracked memory block will prevent the memory block from being tracked back to the object holding the current context. |
| MEM_STRING | This flag is used to aid debugging - set it if the memory block will be used to store printable string data. |
| MEM_NOBLOCKING | If this flag is set against a public memory block then the access blocking mechanism will be permanently turned off for all accesses to that particular memory block. This means that multiple tasks can have full read/write access to the memory block at once regardless of the flags passed to AccessMemory(). |
| MEM_NOCLEAR | If this flag is set, the memory block's data will not be cleared by the AllocMemory() function. |
| MEM_FIXED | This flag can be applied to public memory blocks that need to be mapped to a fixed address that is common to all tasks. For instance, if the system locks the memory block to address 0x56084000 for your task, then all other tasks that map the memory block will also see it at that address. This flag is typically used for supporting absolute code execution. |
| MEM_CALLER | This flag is useable only in routines that support a class method. It forces the memory allocation to be resourced against the object that made the method call. This is particularly important in methods that return memory blocks that do not form a part of the object itself. |
| MEM_TASK | Tells the allocation function to track the memory block to the current Task, as opposed to the current object. |
| MEM_RESERVED | This special flag is used to allocate shared memory blocks that require reserved ID numbers. When using the MEM_RESERVED flag, you are required to set the longword pointed to by the MemoryID argument to the ID that you wish to reserve. If that memory ID is already taken, the AllocMemory() call will fail. |
You will notice that you have the option of receiving the memory allocation
as an address pointer and/or as a unique memory ID. When allocating private
memory, you can generally just accept an address result and drive the MemoryID
argument to NULL. However when allocating public memory, you should always
retrieve the MemoryID, and optionally the Address pointer if you need immediate
access to the block.
If the block is allocated as private and you retrieve both the MemoryID and
Address pointer, or if the allocation is public and you choose to retrieve the
Address pointer, an internal call will be made to
AccessMemory() to lock the memory block and resolve its address. This
means that before freeing the memory block, you must make a call to the
ReleaseMemory() function to remove the lock, or
it will remain in memory till your Task is terminated.
Memory that is allocated through AllocMemory() is automatically cleared
with zero-byte values. When allocating large blocks it may be wise to turn
off this feature - you can do this by setting the MEM_NOCLEAR flag.
| ERR_Okay | The memory block was allocated successfully. |
| ERR_Args | Incorrect arguments were specified (no Size, or no Address and no MemoryID). |
| ERR_Failed | The block could not be allocated due to insufficient memory space. |
| ERR_ArrayFull | Although memory space for the block was available, all available memory records are in use. |
| ERR_LockFailed | The function failed to gain access to the public memory control semaphore. |
| ERR_SystemCorrupt | The internal tables that manage memory allocations are corrupt. |
| ERR_AccessMemory | The block was allocated but access to it was not granted, causing failure. |
| ERR_ResourceExists | This error is returned if MEM_RESERVED was used and the memory block ID was found to already exist. |
|
|
| AllocSemaphore() |
| Allocates a new public semaphore. |
| ERROR AllocSemaphore(STRING Name, LONG Value, LONG Flags, LONG *Semaphore) |
| Name | The name of the semaphore (up to 12 characters, case-sensitive) that you want to create or find. This argument is optional. |
| Value | The starting value of the semaphore can be specified here. The minimum starting value is 1, for a simple blocking semaphore. |
| Flags | Special flags, currently SMF_EXISTS is supported. |
| Semaphore | A reference to the semaphore will be returned through this pointer. |
|
|
The AllocSemaphore() function is used to create new semaphores and join
existing ones. To create a simple semaphore for private usage, you only
need to provide this function with a return value in the Semaphore parameter.
If you want to share a semaphore with other processes, you need to give it
a unique name limited to 15 characters. The Value argument is optional and
only needs to be used if you need more complex signalling for your program.
Semaphores are most commonly used to control access to shared resources,
typically in shared memory areas. For instance, if you create a shared memory
area for read/write operations between tasks, you need a control system to
prevent the tasks from writing to the memory at the same time (allowing
multiple read access is usually non-harmful and quite convenient). Using
a semaphore is perfect for controlling this type of situation.
For a simple blocking semaphore, you should set a value of 1 in the Value
parameter. If you want to allow multiple processes to read from the resource
then you should set the Value much higher - 100 or more. In this mode, there
are two ways for processes to access the semaphore - blocking and non-blocking
mode. Either type of access is achieved through the AccessSemaphore()
function. Blocking mode is the default and will grant you full access to
the resource if it succeeds. Non-blocking access grants you limited access
to the resource - typically considered 'read only' access. Multiple processes
can have non-blocking access at the same time, but only one process may have
access when blocking mode is required. If you set a value of 100, then
the number of non-blocking accesses will be limited to 100 processes. Any
more processes than this wishing to use the semaphore will need to wait until
some of the accesses are released. If 50 processes currently have read
access and a new process requires blocking access, it will have to wait until
all 50 read accesses are released. The specifics of this are discussed in the
documentation for AccessSemaphore() and ReleaseSemaphore().
The handle returned in the Semaphore argument is global, so if you want
to secretly share an anonymous semaphore with other processes, you may do
so if you pass the handle to them. The other processes will still need to call
AllocSemaphore() to register their interest, but they need to add the SMF_EXISTS
Flag and also pass the semaphore handle to this function via the Semaphore
parameter.
To free a semaphore after you have allocated it, call the FreeSemaphore()
function. It is possible to call AllocSemaphore() with the same Name as
many times as you like because the calls will nest, but you must match them
all with FreeSemaphore() calls. A semaphore will not be completely freed
from the system until all processes that have gained access drop their
control of the semaphore.
| ERR_Okay | The semaphore was successfully allocated. |
| ERR_Args | The SemaphoreID argument was not supplied. |
| ERR_ArrayFull | Allocation failed as the semaphore array is at full capacity. |
| ERR_Forbid | Internal system locking failure. |
|
|
| GetFields() |
| Retrieves multiple field values in a single function call. |
| ERROR GetFields(OBJECTPTR Object, { FIELD FieldID, APTR Value }...) |
| Object | Pointer to the object that you want to access. |
| FieldID | The ID of the field that you want to get. |
| Value | Points to the storage area that is to receive the field value. |
|
|
This function can be used to grab the values of multiple fields in a
single function call. It is primarily provided to give a speed increase
over calling the GetField() function multiple
times. The arguments passed to this function are tag-based and must be
terminated with a TAGEND marker, as shown in the following example:
LONG Width, Height;
GetFields(Screen,
FID_Width|TLONG, &Width,
FID_Height|TLONG, &Height,
TAGEND);
The field ID's that you specify must be logically or'd with tag definitions
that indicate the type of values that you want to get from each field. For
instance, if want to retrieve a field in floating point format, then you must
use the TFLOAT tag and supply a pointer to a FLOAT variable. Please note that
failing to set the tag values correctly can often cause a program to crash.
The recognised tag types are TPTR, TSTRING, TLONG, TLARGE, TFLOAT, and
TDOUBLE.
If the GetFields() does not return an ERR_Okay code, you should work on the
assumption that all of the field settings failed, meaning that your routine
should abort in most cases. This function aborts immediately and makes no
attempt to 'salvage' any other fields that may be left in the list, or undo
earlier field settings that were successful.
For information on the field retrieval process, refer to the
GetField() function.
| ERR_Okay | The field values were retrieved successfully. |
| ERR_Args | Invalid arguments were specified. |
| ERR_UnsupportedField | One of the fields is not supported by the target object. |
|
|