Modifies: pause() Changes: *task* operators to *thread* operators (task_id() -> thread_id()) Adds: sync () {}, atomic {}, fork() and synchronized/atomic methods. * Overview A frame is the execution state of a ColdC method. The current frame is only relative to the current method, beginning execution within a new frame uses a new frame context. ColdC ticks are contained within each frame, rather than in a global context. A thread is a stack of methods executing in relation to each other (one after another). * Outline Preemptive multi-threading will be based upon either CPU ticks or ColdC ticks (have not decided which). CPU ticks give the advantage of also taking native functions into consideration. However, this will also cause threads to be preempted faster on a loaded machine. When a certain threshold has been reached, the task will be preempted (suspended) and added to a list of preempted tasks, to continue execution at a later time. Being preempted also refreshes the current frame's ticks. * Synchronizing Synchronization is the act of a thread gaining absolute control of an object. Only one thread can be synchronized with an object at any given time. There are two ways of synchronizing with an object. First, one can implicitly synchronize the method with an object by adding the synchronized method flag. Or the block statement 'sync' can be used, which accepts a list of objects and contains a block of code to execute while synchronized to the object(s), such as: sync (this()) { while (times) { .call_synced_method(); times = times - 1; } } When a thread is synchronized with an object, it has full read/write ability to any object variables it can access. Synchronized threads can be preempted, just like unsynchronized threads (preemptiveness is defined by the atomic state). Furthermore, the synchronization is cooperative througout the thread. If a synchronized frame calls a method which must be synchronized, it is not blocked. If a synchronize call is made, and the thread is unable to synchronize with the object, it may be blocked (if it is not atomic). Blocked threads are suspended, and added to a list for that object. When the current thread synchronizing to the object releases it's hold, the first thread in the blocked list is executed. If an atomic thread is blocked, the error ~blocked is thrown. * Atomic code blocks If a frame is preempted, blocked or suspended while it is set as atomic, the error ~preempted, ~blocked or ~suspended is thrown. The atomic state is propogated through subsequent frames in the thread, so that if a frame becomes atomic, while it is atomic any frames deeper into the thread from it become atomic. Frames become atomic by either setting the atomic method flag, or by using the block statement 'atomic' in ColdC code. Examples: atomic .do_this(); atomic { .do_this(); .do_that(); } * Function pause() pause() gives the ability to cooperatively multh-thread. It will have an optional flag which can be passed (1 or 0), if it is true (1) then pause() will act nicely, if it is false (default, 0) it will not act nicely. When pause() is called it will instantly preempt the thread, unless it is within an atomic block. If it is within an atomic block and is a nice pause, the thread will continue to run until it either runs out of frame ticks or it reaches the end of the atomic block. If it runs out of ticks, the usual error is thrown (~ticks). If it reaches the end of the atomic block it instantly preempts. * Function fork() fork() splits a thread. When called it splits the thread into two exact frames. The function fork() has a logical expression value of 0 to the child process, and the value is the forked thread id for the parent thread. An optional delay argument may be supplied to fork, defaulting to 0. The delay specifies how long to wait before beginning execution of the child thread. Notes: possibly have a MAX_FORK for each thread; possibly have a method flag of 'fork', where if that method is called it starts its own execution thread, rather than becoming a part of the current thread. The logical expression value of a forked method is it's thread_id.