The OSCL Inter-Thread Communication framework.
Multi-threading is a powerful technique used for software development. Multi-threading is a software tool that has the potential to allow designers to produce software systems with a number of desirable characteristics including:
Designs which take advantage of M-T can take advantage of Semetric Multi-Processing (SMP) to improve the perfmance of the software application using upgraded hardware.
- Scalable performance
- Improved partitioning
- Simplified independent sub-systems
- Improved reusability
Contrary to popular notions, M-T can be used to actually simplify the implemention of an application by partitioning the application into a set of services each of which operates in an apparently independent application. Such servers have a well defined interface and provide a relatively simple service to its clients. The result is that the designers can write software that is more easily implemented (due to its independence) and more easily verified for correct operation.
Having divided the application into independent subsystems also has the added potential for reusing these subsystems in other applications.
Achieving these goals requires that the designer be consistent in the application of appropriate practices.
The ITC framework described in this document supports a programming idiom that encorages the development of software with these desirable characteristics.
The ITC framework extends OOP technology into the concurrency domain. Threads communicate between one another by exchanging messages.
At its most fundamental, the ITC framework is used to send messages between threads. The two most fundamental parts of this implementation are the message and the mailbox. Messages are sent to a thread when the sender places the message into the receiver's mailbox.
At a higher level of abstraction, the framework distinguishes between client and server roles. Clients send request messages to servers and may receive response messages from servers. Servers receive request messages from clients and may send response messages to clients (albeit indirectly).
Client role threads may send request messages using one of two modes supported by the framework. The two modes correspond to the way in which the client is notified that the server has completed the request.
When using the synchronous method, the client blocks after the request message is placed into the server's mailbox. When the server completes the request, the client thread resumes execution.
The asynchronous method requires the client to create a response message, which is sent along with the request message. The client thread does not block, but continues to execute after the request is sent to the server's mailbox. When the server completes the request, the response message is sent to the client's mailbox.
The server role knows nothing of these two modes of client operation, it only knows about the request. When the server completes the request, it invokes an abstract operation on the request that either causes the client to resume execution, or sends the response message to the client's mailbox.
A thread may have both client and server roles. For example, it may receive requests from clients (server role), and as a result send requests to lower layer servers (client role).
Mailboxes are glorified FIFO linked lists. Each message has a link field that is used to maintain the linked list. Each mailbox has two fundamental operations.
The post() operation is invoked by the sending thread. It takes a message reference as an argument. The operation aquires exclusive access to the mailbox; links the message to the tail of the mailbox linked list; signals the receiving thread that the mailbox is not empty; and releases its exclusive access to the mailbox.
The waitNext() operation is invoked by the receiving thread. If the mailbox is not empty the first message in the FIFO linked list is removed and returned. If the mailbox is empty, the receiving thread blocks until a message is placed in the mailbox.
Each thread may have exactly one mailbox. Obviously, a thread must have a mailbox to receive messages.
Messages reference a payload, which carries the data that is exchanged between the threads. The payload type is used by the receiver to distinguish individual message types. Messages which have a zero size payload are known within the ITC framework as an event.
Messages fall into two catagories:
Request messages are defined for a particular interface type. The memory for a request operation is owned and allocated by the client. The client must create the request message and its payload prior to sending the request . All request messages have a returnToSender() operation. When a server completes the processing of a request message, it invokes the returnToSender() operation. This action causes the client to be notified that the server has fulfilled the request.
- Request messages are sent by a client thread to a server thread.
- Response messages may be sent indirectly by a server thread to the client thread that originated the corresponding request.
Response messages are always defined in terms request messages. Response messages are indirectly sent by a server thread to the client thread that initiated the corresponding request. This happens when the
One important point to make here is that a server only "knows" about the request messages that it accepts.
ITC clients and servers communicate through ITC interfaces defined by the server. An ITC interface specifies the messages that the server accepts on the interface. This includes the message type and the data payload that form each "request". The actual implementation of how the requests are processed is encapsulated in the server implementation which is not visible to the client.
A client needs two pieces of information to send a request to a server.
These two items are bound together in an object known in the ITC framework as a SAP (a.k.a. Service Access Point). Thus, a client needs a reference to a server's SAP in order to send a request message to a server. The SAP reference is typically supplied to the client through its constructor when the client is instantiated.
- A reference to the server's "request API" (a.k.a. ReqApi). This item refers to the procedural domain interface of the server.
- A reference to the server's "mailbox" (a.k.a. PostMsgApi). This item defines the concurrency domain interface to the server.