Algorithms for farming implementation under pvm. @ int pvm_farm_init (char *farm_name); Client side @ Establish a connection with the server by seeing the name of the server in the list of tasks and extracting its tid. Also, find the farmer process name (opt) and calling process task id. @ Send a message to the server of the type 1 which contains farm_name, process_name, opcode INIT_FARM Note : tid of the server task should be kept in a global variable which can be accessed again later. @ return OK Note : if there is an error in buffer creation, or in locating the server, or sending the message, return ERROR. Server side @ Wait for any request from any task (tid = -1, msgtag = -1) (wildcard recv). @ On getting the message, extract the opcode from the buffer @ If opcode == INIT_FARM, then get tid, farm name and farmer process name. @ Create a farm item in the FList. @ Look at the list of pending requests and service these @ Go back and wait for other messages @ int pvm_get_worker_class_id (char *farm_name,char *worker_class_name); Client side @ Take the global variable which identifies the server task (its tid) and send a message to the server. @ The message should contain opcode GET_WORKER_CLASS_ID, worker class name, farm name @ Receive reply from the server @ Unpack the message and extract the worker class id (wcid). @ Return wcid Note : ERROR is returned if there's an error in packing, unpacking the message, sending message or if the server says ERROR (no such farm name). Server side @ if opcode is GET_WORKER_CLASS_ID @ extract (unpack) worker class name, farm name @ Search for the farm item by farm name. @ If item is not found send a reply containing ERROR (no such farm name) @ Get FItem, using this get WCList @ Search for worker class item by the worker class name @ If not found then, put the request on the list of pending requests @ look for other messages @ If item is found, then see the WCItem and get the worker class id (wcid). @ Send the reply containing the wcid @ int pvm_init_worker_class(char *farm_name, char *worker_class_name); Client side @ Extract the tid of the worker (pvm_mytid ) @ Search for the server task by looking at the list of tasks and get the tid of the server. If there's no server, then return ERROR. @ Send a message to the server. It should contain opcode INIT_WORKER_CLASS, farm name, and worker class name and worker task id. @ Wait for the reply form the server. Get the status ERROR, or wcid and store it in a global variable to be used later. @also store the farmer name in a global variable which can be used later @ return OK Server side @ if opcode == INIT_WORKER_CLASS @ get the farm name, worker class name and worker task id. @ Search the list of the farmers using this farm name. @ if an item is not found then add the request to the list of pending requests and service some other message (client remains blocked) @ If the farmer item is found then, get the FItem and look for WCList. @ Search the list of the worker classes using the worker class name (search by name). @ If the item is not found then Append an item in the list of worker classes and get the worker class id and search for the item (wcid) and append a worker task item in the list (using the wlist ) and send the wcid to the client task. @ If the item is found then get the WCItem which contains the worker class id. @ append the worker task to this list @ send the wcid to the worker task (client) @ service other messages int pvm_send_work_packet(int id,int msgtag); Client side @ get the currently used buffer id and save it. Create another buffer to use for sending a message to the server task. @ The message should contain, the opcode SEND_WORK_PACKET and the the worker class id and the message tag of the following message. @ after sending the message make the old buffer current and send the user specified message. @ return OK Server side @ extract the opcode and the worker class id and the message tag of the following message. Also get the tid of the sender task (farmer task). @ Using the tid, and the message tag, read another message from the farmer task.This contains the work packet to be processed. @ Call the scheduler with the worker class id and the message buffer id and the message tag of the buffer message. @ In the scheduler, using the worker class id, locate the WCitem which contains the information about the work packets. @ Find out if any worker task is free. @ If yes, then using the tid of the task, send the message buffer to the worker task giving the message tag information and the buffer id. @ Clear the buffer used to receive the message and look for other messages @ If there are no workers which can handle the message, then use the pointer to the list of work packets and append the current packet to the end of the list ofwork packets associated with the worker class. @ Go back and check for other messages arriving at the server. int bufid = pvm_recv_work_packet(int msgtag); Client side @ wait for a message of the type -1 from the server. @ if the message is of the type -10 (FARM_HAS_TERMINATED) then return FARM_HAS_TERMINATED @ if not, then on receiving the message, return the buffer id. Server side @ Nothing is done explicitly by the server. int pvm_send_reply_packet(int msgtag); Client side @ get the tid of the server task and save the current buffer, make a new buffer to send a message to the server. @ The message should contain the opcode SEND_REPLY_PACKET, the farmer name, worker class id and the message type of the message following this. @ Send the message of the type msgtag to the server @ return OK. Server side @ get the message from the client and if opcode == SEND_REPLY_PACKET, then extract the other information from the message like the worker class id, the farm name and the message type of the next message. Also find out the tid of the sender (client) @ Receive the message from the client of the type specified by the earlier message and the tid which was found in the previous step. @ find the farmer using search by name. @ If the farmer name is not found - report a system error - (the name is stored at the client site when the call init_worker_class) @ get the tid of the farmer task and send the reply packet to the farmer. @ clear the buffer. int bufid = pvm_recv_reply_packet(id, int msgtag); Client side @ wait for a message of the type msgtag from the server. @ On receiving the message, return the buffer id. Server side @ Nothing is done explicitly by the server. int pvm_farm_terminate(char *farm_name); Client side @ Send a message to the server containing opcode FARM_TERMINATE and the farmer name and the tid of the farmer (no need to send explicitly). Server side @ Receive the message and check if opcode == FARM_TERMINATE @ see the tid of the sender (get from pvm calls) and validate the request as coming from the owner of the farm i.e., search for the farmer name in the list of farmer tasks and extract the tid - if it matches the sender of the message then its valid - else give an error to the farmer. @ go through all the worker classes, and check if any packets are to be distributed, if not then send a message to all the worker tasks that FARM_HAS_BEEN_TERMINATED (msgtag = -10) which would be received in the recv calls. @ send an OK message to the farmer to indicate that all is well. @ look for other messages.