Previous | Contents | Index |
With DEDICATED stacks, the addresses of parameters to a constructor derived from the task class change. This change occurs between the time when the base class (task) constructor is called by the derived class constructor and when the first statement in the derived class constructor begins executing. Constructors for the task class and the classes derived from the task class cannot be inlined. These classes perform actions that start up a child task (in a new thread) and then resume execution of the parent task. To prevent these constructors from being inlined, use the -noinline command-line switch to specify no inlining when you compile your program, or put the constructor in a separate source file from the parts of the program that you want to inline. |
void cancel(int result)
Puts a task object into the TERMINATED state without suspending the calling task (that is, without invoking the scheduler); sets the result of the object to result.void delay(long delay)
Suspends a task object for the time specified by delay. A delayed task is in the RUNNING state. The task object resumes at the current time on the system clock, plus the time specified by delay. Only calling delay(), or waiting for a timer, advances the clock.task *get_task_chain()
Returns a pointer to the first task on the list of all task objects linked by next_t pointers.virtual objtype o_type()
Returns object::TASK.long preempt()
Suspends a RUNNING object of the task class making it IDLE. Returns the number of time units left in the task's delay. Calling this function for an IDLE or TERMINATED task causes a run-time error.virtual void print(int verbosity, int internal_use = 0)
Prints a task object on cout. The verbosity argument specifies the information to be printed. Do not supply a value for the internal_use parameter.void resultis(int result)
Sets the return value of a task object to be the value of result; it puts the task object in the TERMINATED state. To examine the result, call the sched::result() function. The constructor for a class derived from task must not return by any of the following actions:The end of a constructor for a class derived from the task class and the main function must call the resultis() function. A task is pending until its stage changes to TERMINATED. For more information, see sched::pending().
- Executing a return statement
- Throwing an exception
- Not catching an exception thrown by a subroutine
void setwho(object *alerter)
Keeps track of which object alerted the object. The alerter argument should represent a pointer to the object that caused the task package to alert the task.void sleep(object *object_waiting_for)
Suspends a task object unconditionally (that is, it puts the task object in the IDLE state). The argument object_waiting_for is optional; if it is pointing to a pending object, the object remembers the task. When the object is no longer pending, the task is rescheduled. If you do not supply an argument, the event that causes the task object to resume remains unspecified.void wait(object *object_waiting_for)
Suspends a task object (it puts the task object in the IDLE state) until that object is ready, if object_waiting_for points to an object that is pending. If object_waiting_for points to an object that is ready (not pending), then task::wait does not suspend the task object.int waitlist(object *first_object_waiting_for ...)
Suspends a task object to wait for one of a list of objects to become ready. The waitlist() function takes a list of object pointers linked by o_next and terminated by a NULL argument. If any of the arguments point to a ready object, then the task object is not suspended. When one of the objects pointed to in the argument list is ready, waitlist() returns the position in the list of the object that caused the return; position numbering starts at 0.int waitvec(object **object_waiting_for_vector)
Differs from waitlist() only in that waitvec() takes as an argument the address of a vector holding a list of pointers to objects and terminating NULL. When one of the objects pointed to in the argument vector is ready, waitvec() returns the position in a vector of the object that caused the return; position numbering starts at 0.object *who_alerted_me()
Returns a pointer to the object whose state change, from pending to ready, caused a task to be put back on the run chain (put in the RUNNING state).
long t = sched::get_clock; delay(10000); |
Delays a task so that it resumes executing at t+10,000.
A timer delays for a specified amount of simulated time.
#include <task.hxx>Alternative Header
#include <task.h>
class timer: public sched { public: timer(long delay); ~timer(); void reset(long delay); void setwho(object *alerter); virtual void print(int verbosity, int internal_use = 0); virtual objtype o_type(); };
Objects of this class are timers. When a timer is created its state is RUNNING, and it is scheduled to change its state to TERMINATED after a specified number of time units. When the timer becomes TERMINATED, tasks waiting for it are scheduled to resume execution.
When a run-time error occurs, the following error code is passed to the object::task_error() function:
Value Error Description e_timerdel Cannot delete a timer that is idle or running
timer(long delay)
Constructs an object of the timer class and schedules it for delay time units after the current clock time.~timer()
Deletes an object of the timer class; the timer's state must be TERMINATED.
virtual objtype o_type()
Returns object::TIMER.virtual void print(int verbosity, int internal_use = 0)
Prints a timer object on cout. The verbosity argument specifies the information to be printed. Do not supply a value for the internal_use parameter.void reset(long delay)
Sets the state of the timer to RUNNING (even if it was TERMINATED) and reschedules it to terminate after the specified delay from the current simulated time.void setwho(object *alerter)
Returns NULL.
extern "C" { #include <stdlib.h> } #include <task.hxx> #include <iostream.hxx> class DelayTask: public task { public: DelayTask(char *, long); }; // This task just does a delay, much like a timer. DelayTask::DelayTask(char *task_name, long delay_length): task(task_name) { cout << "at beginning of DelayTask, clock is " << sched::get_clock() << "\n"; delay(delay_length); cout << "at end of DelayTask, clock is " << sched::get_clock() << "\n"; thistask->resultis(0); } int main() { cout << "at beginning of main\n"; cout << "creating task\n"; DelayTask delay_task1("delay_task1", 100); cout << "creating timer\n"; timer *pt1 = new timer(10); cout << "waiting for timer\n"; thistask->wait(pt1); cout << "clock is " << sched::get_clock() << "\n"; cout << "resetting timer\n"; pt1->reset(1000); cout << "waiting for timer\n"; thistask->wait(pt1); cout << "clock is " << sched::get_clock() << "\n"; cout << "at end of main\n"; thistask->resultis(0); return EXIT_SUCCESS; }This code generates the following output:
at beginning of main creating task at beginning of DelayTask, clock is 0 creating timer waiting for timer clock is 10 resetting timer waiting for timer at end of DelayTask, clock is 100 clock is 1010 at end of main
Objects of the urand class generate uniformly distributed random integers within a given range from a low to a high value.
#include <task.hxx>Alternative Header
#include <task.h>
class urand: public randint { public: int low; int high; urand(int arg_low, int arg_high); int draw(); };
int low
Is the lower bound of the range of generated random numbers.int high
Is the upper bound of the range of generated random numbers.
urand(int arg_low, int arg_high)
Constructs an object of the urand class. Generated random numbers are uniformly distributed from arg_low to arg_high.
int draw()
Returns the next random integer generated by the object.
randint class
The vector package provides ways to define vectors or stacks of objects of any type by using the macro expansion capability of the DEC C++ preprocessor.
declare(vector, TYPE) |
implement(vector, TYPE) |
class MyType {/*...*/}; declare(vector,MyType) implement(vector,MyType) vector(MyType) vec1(100), vec2(5); MyType x,y; //... if(vec2[4] == y) vec1[98] = x; |
The TYPE parameter must be an identifier. If it is not a class name, a fundamental type, or a type name, create a name for the type using a typedef declaration. For example:
typedef char *PCHAR; declare(vector, PCHAR) implement(vector, PCHAR) implement(vector, PCHAR) void f() { vector(PCHAR) ptrvec(10); char *p = "Text"; ptrvec[0] = p; // ... } |
Thread Safety
The generation of error messages within the vector package is not thread safe; the package relies on static members to handle the current error message and there is no synchonization between threads. If this creates a problem for your application, Digital recommends that you define a single Mutex object to synchronize all use of the vector package. For more information on synchronizing access to user-defined objects, see Chapter 6.
Provides a generic (parameterized) data abstraction for a fixed-sized stack of objects of some given type.
#include <vector.hxx>Alternative Header
#include <vector.h>
TYPE---The type of the objects in the stack. It must be an identifier.
class stack(TYPE): private vector(TYPE) { public: stack(TYPE)(int); // objection size_error stack(TYPE)(stack(TYPE) &); void push(TYPE); // objection overflow_error TYPE pop(); // objection underflow_error TYPE &top(); // objection no_top_error int full(); int empty(); int size(); int size_used(); static Objection overflow_error; static Objection underflow_error; static Objection no_top_error; };
This class provides a generic (parameterized) data abstraction for a fixed-sized stack of objects of some given type.Before a stack object can be declared or implemented, the base class, a vector object with the same type parameter, must also be declared and implemented. To declare a stack object you need to both declare and implement the base vector class and the stack class.
Exceptions are implemented with the Objection package. The initial action function for all objections prints an error message on cerr and calls abort().
stack(TYPE)(int size)
Constructs a stack object with room for size elements in the stack. If size is less than or equal to 0, the objection vector(TYPE)::size_error is raised.stack(TYPE)(stack(TYPE) &src)
Constructs a stack object that takes the initial values of the elements from another stack object of the same type and size.
The following objections are raised for the stack errors described.static Objection no_top_error
Attempted to reference the top of an empty stack.static Objection overflow_error
Attempted to push too many elements onto the stack.static Objection underflow_error
Attempted to pop an empty stack.
int empty()
Returns TRUE if the stack is empty; otherwise, it returns FALSE.int full()
Returns TRUE if the stack is full; otherwise, it returns FALSE.TYPE pop()
Pops an element off the top of the stack. If the stack underflows, the objection stack(TYPE)::underflow_error is raised.void push(TYPE new_elem)
Pushes an element onto the stack. If the stack overflows, the objection stack(TYPE)::overflow_error is raised.int size()
Returns the maximum number of elements in the stack.int size_used()
Returns the number of elements currently used in a generic stack.TYPE &top()
Returns a reference to the element on the top of the stack. If the stack is empty, the objection stack(TYPE)::no_top_error is raised.
declare(vector, int) implement(vector, int) declare(stack, int) implement(stack, int) void f() { stack(int) st(20); st.push(17); // ... } |
This example shows the four steps required to declare and implement the base vector class and to declare and implement the stack class.
Objection Package
generic Package
vector(TYPE) class
Provides the (parameterized) data abstraction for a fixed-sized vector of objects of some given type.
#include <vector.hxx>Alternative Header
#include <vector.h>
TYPE---The type of the objects in the vector. It must be an identifier.
class vector(TYPE) { public: vector(TYPE)(int); // objection size_error vector(TYPE)(vector(TYPE) &); ~vector(TYPE)(); vector(TYPE) &operator=(vector(TYPE) &); // objection copy_size_error TYPE &elem(int); TYPE &operator[](int); // objection index_error int size(); void set_size(int); static Objection size_error; static Objection copy_size_error; static Objection index_error; };
This class provides the (parameterized) data abstraction for a fixed-sized vector of objects of some given type.
Exceptions are implemented with the Objection package. The initial action function for all objections prints an error message on cerr and calls abort().
vector(TYPE)(int new_size)
Constructs a vector object with the integer argument representing the number of elements in the vector. If the number of elements is less than or equal to 0, the objection vector(TYPE)::size_error is raised.vector(TYPE)(vector(TYPE) &src)
Constructs a vector object that takes initial values of the elements from another vector object of the same type and size.~vector(TYPE)()
Deletes a vector object.
The following objections are raised for the vector errors described.static Objection copy_size_error
Attempted to assign a vector to another vector that has a different number of elements.static Objection index_error
Attempted to reference a vector element with a subscript out of range.static Objection size_error
Attempted to create a vector with less than one element in it.
vector(TYPE) &operator = (vector(TYPE) &src)
Assigns a vector to another vector. If the sizes of the vectors are different, the objection vector(TYPE)::copy_size_error is raised.TYPE &operator [] (int i)
Returns a reference to the ith element in the vector. The value of i has a range from 0 to size()--1. If the subscript is out of bounds, the objection vector(TYPE)::index_error is raised.
TYPE &elem(int i)
Behaves like operator [] but without bounds checking.void set_size(int new_size)
Changes the size of the vector.int size()
Returns the number of elements in the vector.
Objection Package
generic Package
Index | Contents |