93 of 158
87 Task Control Block Elements (Native mode Devices) Offset Length Description 0 1 Task status. See StatusTask() for details. 1 2 Remaining time to sleep (in RTC ticks). 3 2 Address of next task control block. 5 2 Task context: SP (valid only when not the current task). 7 2 Task stack starting address. 9 2 Unused. 11 1 Task control flags (used internally). Caution: directly modifying the task control block (other than the “time to sleep” value) is strongly discouraged as doing so will probably cause your program to malfunction. 3.28 Dynamic Memory Allocation The ZX system maintains a dynamic memory allocation heap that is primarily used internally. For example, space is allocated from the heap automatically by the system to hold the characters of String variables. That allocated space is automatically returned to the heap when String variables change or go out of scope. In some applications, it is useful to be able to allocate a block of memory to use for some period of time (perhaps for a data buffer, for example) and then to deallocate the block when it is no longer needed. The ZBasic System Library routines System.Alloc() and System.Free() provide access to the dynamic memory allocation heap for such purposes. While these routines provide a very useful functionality, they must be used with great care because careless or improper use can result in malfunctioning of the heap. There are two fundamental problems that can arise: heap exhaustion and heap corruption. If blocks of memory are allocated from the heap and never freed, the heap will eventually become exhausted and subsequent allocation requests will fail. Since String variable types rely on proper heap function, assigning values to String variables will not have the desired effect when the heap is exhausted. Heap corruption occurs when the heap management data structures are inadvertently modified. Such corruption can result from writing to a previously allocated block after it has been freed or writing to memory outside the bounds of a properly allocated but not yet freed block. The heap may also be corrupted by inadvertent writes to RAM within the bounds of the entire heap such as might result from the careless use of the RamPoke() or BlockMove() routines, by writing beyond the bounds of an array, or overflowing the stack assigned to a task. Heap corruption will also be the likely result of passing an invalid value to System.Free(). The only values that may be safely passed to System.Free() are those that have been returned by System.Alloc() but have not yet been passed to SystemFree(). As a special case, passing the value zero to SystemFree() is benign. The value Register.HeapEnd, described in this document, may be useful for monitoring the state of the heap. For additional information, see the descriptions of System.Alloc() and System.Free() in the ZBasic System Library Reference manual. Also, for native mode devices (e.g. the ZX-24n) the function System.HeapHeadRoom() may be used to determine, at any time, the amount of unused space that remains in the heap. Moreover, for native mode devices the directive Option HeapSize can be used to specify an upper limit on the size of the heap thereby preventing it from encroaching on the task stacks.