/*************************************************************************
* Mach Operating System
* Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University.
* Copyright (c) 1993,1994 The University of Utah and
* the Computer Systems Laboratory (CSL).
* All rights reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF
* THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY
* OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF
* THIS SOFTWARE.
************************************************************************/

Specifiction for Eric v2.0
By Gavin R. Brewer
26/07/01

kTask Methods:


kTask::kTask( int inherit_memory, long parent_task);

Arguments:

inherit_memory
If set, the child task's address space is built from the parent task according to its memory inheritance values.
parent_task
The handle of the parent task.
Description:

This constructor creates a new task; the resulting task acquires shared or copied parts of the parent's address space (see vm_inherit).

The task initially contains no threads, except a special thread denoting the main flow of control, ie. tMain().

The new task gets the four special ports created or copied for it at task creation. The kernel_port is created and send rights for it are given to the child and returned to the caller. The notify_port is created and receive, ownership and send rights for it are given to the child.

The bootstrap_port and exception_port are inherited from the parent task. The new task can get send rights to these ports with the call get_special_port.

Throws:

ERIC_RESOURCE_SHORTAGE Some critical kernel resource is available


kTask::~kTask();
 

Description:

Destroys the task specified and all of its threads. All resources that are used only by this task are freed. Any port to which this task has receive and ownership rights is destroyed.
 


int kTask::suspend();

Description:

Increments the task's suspend count and stops all threads in the task. As long as the suspend count is positive newly created threads will not run. This call does not return until all threads are suspended.

Returns:

ERIC_SUCCESS The task has been suspended


int kTask::resume();

Description:

Decrements the task's suspend count. If it becomes zero, all threads with zero suspend count in the task are resumed. The count may not become negative.

Returns:

ERIC_SUCCESS The task has been resumed.
ERIC_FAILURE The suspend count is already zero.


int kTask::get_special_ports(int which_port, long& special_port);
int kTask::set_special_ports(int which_port, long& special_port);
int task_self();
long task_notify();

Arguments:

which_port The port that is requested.

TASK_NOTIFY_PORT,
TASK_BOOTSTRAP_PORT
TASK_EXCEPTION_PORT

special_port The value of the port that is requested or being set.

Description:

Returns send rights to one of a set of special ports for the task specified by task. In the case of the task's own notify_port, the task also gets receive and ownership rights. set_special_port() sets one of a set of special ports.

task_self() returns the port to which kernel calls for the currently executing thread should be directed. Currently, task_self returns the 'task kernel port' and which is a port for which the kernel has receive rights and which it uses to identify a task.

If one task, the controller, has send access to the kernl port of another task, the subject task, then the controller task can perform kernel operations for the subject task. Normally only the task itself and the task that created it will have access to the task kernel port, but any task may pass rights to its kernel port to any other task.

task_notify() returns receive, ownership and send rights to the notify port associated with the task to which the executing thread belongs. The notify port is a port on which the task should receive notification of such kernel events of the destruction of a port to which it has send rights.

The other special ports associated with a task are the 'BOOTSTRAP PORT' and the 'EXCEPTION PORT'. The bootstrap port is a port to which a thread may send a message requesting other system service ports. This port is not used by the kernel. The task's 'EXCEPTION PORT' is the port to which a thread may send a message requesting other system service ports.

Returns: ERIC_SUCCESS The port was returned or set.
 


int kTask::info(Array <int> task_info, int& task_infoCnt);

Arguments:

flavor The type of statistics that are wanted task_info Statistics about the current task task_infoCnt Size of the info structure. Currently only TASK_BASIC_INFO_COUNT is implemented.

Description:

Returns the selected information array for a task, as specified by flavor. task_info is an array of integers in task_info. On return it contains the actual number of integers in task_info.

Returns:

ERIC_SUCCESS The call succeeded.

EIG_ARRAY_TOO_LARGE Returned info array is too large for task_info. task_info is filled as much as possible. task_infoCnt is set to the number of elements that would be returned if there were enough room.


int kTask::thread(Array<long> thread_list, int& thread_cnt);

Description:

Gets send rights to the kernel portfor each thread contained in target_task. thread_list is an array that is created as a result of the call. The caller may wish to deallocate this array when the data is no longer valid.

Arguments:

target_task  The task to be affected

thread_list  The set of threads contained within the current task. No particular ordering is guaranteed.

thread_count The number of threads in the thread list...

Returns:

ERIC_SUCCESS The call succeeded



int kTask::send(kMsg* mesg,int option, int timeout);
 

timeout
      In the event that the destination port is full and the SEND_TIMEOUT option has been specified, this
      value specifies the maximum wait time, (in milliseconds).

option

The failure conditions under which send() should terminate; the value of this parameter is an ORd combination of the following two options. Unless one of the two following values for the option parameter is explicitly specified, send() does not return until the message is successfully queued for the intended receiver.

SEND_TIMEOUT:

specifies that the send() request should terminate after the timeout period has expired, even if the kernel has been unable to queue the message.

SEND_NOTIFY:

allows the sender to give exactly one message to the OS without being suspended should the destination port be full. When another message can be forced to the receiving port's queue using SEND_NOTIFY the sending task receives a NOTIFY_MSG_ACCEPTED notification.

A second attempt to send a message with the notify option before the notification arrives, results in an error. If SEND_TIMEOUT is also specified, send() will wait until the specified timeout has elapsed before invoking the SEND_NOTIFY action.

SEND_INTERRUPT:
      Specifies that send() should return if a software interrupt occurs in this thread.

MSG_OPTION_NONE:
      A constant defined as zero which may be used to specify that neither of the previous options are
      wanted.

Description:

send() transmits a message from the current task to the remote port specified in the object's header field. The message consists of its header, followed by a variable number of data descriptors and data items.

If the msg_local_port field is not set to PORT_NULL, send rights to that port will be passed to the receiver of this message. The receiver task may use that port to send a reply to this message.

If the SEND_NOTIFY option is used and this call returns a SEND_WILL_NOTIFY code, then the user can expect to receive a notify message from the kernel. This message will either be a
NOTIFY_MSG_ACCEPTED or a NOTIFY_PORT_DELETED message depending on what happened to the queued message. The first and only data item in these messages is the port to which the original message
was sent.

Returns:

SEND_SUCCESS The message has been queued for the destination port

SEND_INVALID_MEMORY

The message header or body was not readable by the calling task, or the message body specified out-of line data which was not readable.

SEND_INVALID_PORT

The mesage refers to a name for which the current task does not have access, or to which access was explicitly removed from the current task, while waiting for the message to be posted, or a msg_type_name field in the message specifies rights that the name doesnt denote in the task, (e.g. specifying MSG_TYPE_SEND and supplying a port set's name.)..

SEND_TIMED_OUT
The message was not sent since the destination port was still full after 'timeout' microseconds.

SEND_WILL_NOTIFY
The destination port was full but the SEND_NOTIFY option was specified. A notification message can be posted.

SEND_NOTIFY_IN_PROGRESS

The SEND_NOTIFY option was specified but a notification request is already outstanding for this thread and given destination port.
 
 

int kTask::receive(kMesg* mesg, int option, int timeout);

Arguments:

timeout
      If RCV_TIMEOUT is specified this value is the maximum time in milliseconds to wait for a message
      before giving up.
option

The failure conditions under which receive() should terminate; again this is the bit ORd combination of the following two options. Unless one of the two following values for the option parameter is explicitly specified, receive() does not return until a message has been received.

RCV_TIMEOUT:

Specifies that receive() should return when the specified timeout elapses, if a message has not arrived by that time; if not specified, the timeout will be ignored. (ie infinite).

RCV_NO_SENDERS:

Specifies that receive() should return if the receiver and owner tasks have only access rights to the port specified in the message header. (not implemented yet).

RCV_INTERRUPT:

Specifies that receive() should return when a software interrupt occurs in this thread.

MSG_OPTION_NONE:

Specifies that none of the above options are required.

Description:

receive() retrieves the next message from a port or port set specified in the msg_local_port field of the calling object. If a port is specified, the port may not be a member of a port set.

The msg_local_port field will be set to the specific port on which the message was found.

If a port is to be specified, the receive() will retrieve messages sent to any of the set's member ports. It is not an error for the port set to have no members, or for memeber to be added and removed from a port set while a receive() on the port set is in progress.

The message consists of its header, followed by a variable amount of data; the message header supplied to receive() must specify the maximum size of the mssage which can be received into the buffer provided.

If no messages are present on the port(s) in question, receive() will wait until a message or until on of the specifie termination conditions is met, (see above for discussion of parameter).

Returns:
 

RCV_SUCCESS          The message has been received
RCV_INVALID_MEMORY   The message specified was not writable to the calling task

RCV_INVALID_PORT

An attempt was made to receive on a port to which the calling task does not have the proper access, or which was deallocated while waiting for a message.

RCV_TOO_LARGE

The message header and body combined are larger than the size specified by msg_size.

RCV_NOT_ENOUGH_MEMORY

The message to be received contains more out-of-line data than can be allocated in the receiving task.

RCV_ONLY_SENDER

An attempt was made to receive on a port to which only the receive and/or owner have access, and the RCV_NO_SENDERS option was specified.

RCV_INTERRUPTED

A software interrupt occurred.

RCV_PORT_CHANGE

The port specified was moven into a port set during the duration of the msg_receive call.


int kTask::rpc(kMesg* mesg, int option, int rcv_size, int send_timeout, int rcv_timeout);

Arguments:

option
      A union of the option parameters for the component operations (see send() and receive()).

rcv_size
 
The maximum size of allowed for the received for the received message; this must be less than or
equal to the size of the message buffer. The msg_size field in the header specifies the size of the message to be sent.

send_timeout;
rcv_timeout;
 
These timeout values can be applied to concurrent operations. These are only used if the options SEND_TIMEOUT and/or RCV_TIMEOUT are specified.

Description:

rpc() is a hybrid call which performs a send() followed by a receive(), using the same message buffer.

Returns:

RPC_SUCCESS    message was successfully sent and a reply was received.

Failures:

Are the same as those for send() and receive(); any error during the send() portion will terminate the call.