
% Template for a simple journal or conference style article

\documentstyle[12pt,fullpage]{article}
\begin{document}
\pagestyle{plain}
\title{\bf CIS 631: Project Design Documentation\\ \ \\ Implementation of Farming Under PVM}
\author {Sameer S. Shende}
\maketitle
\vspace*{.3in}


\section*{Algorithms for farming implementation under pvm}
\begin{enumerate}

\item {\bf int 	pvm\_farm\_init (char *farm\_name); }
 
\subsection*{Client side}
\begin{enumerate}
\item 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.
\item The server task id should be stored in a global variable and if it 
contains a server tid, then the search for the server is not required (say a
a server tid, then the search for the server is not required (say a
previous pvm\_farm\_init() call has already set it).
\item Send a message to the server of the type DEF\_MSGTAG (1) which contains
	farm\_name, opcode INIT\_FARM
\item Receive a message from the server containing the result of the operation.
\item Return the value read from the server. This value can be OK or FARM\-\_NAME\_\-PRESENT or ERROR.
\end{enumerate}

\subsection*{Server side }

\begin{enumerate}
\item Wait for any request from any task (tid = -1, msgtag = -1) (wildcard recv).
\item On getting the message, extract the opcode from the buffer
\item If opcode == INIT\_FARM, then get tid and  farm name from the client.
\item Search the list of farm names for a farm of the name received from the client.
\item If such a farm does not exist, append the farm name (and farmer tid) to 
the list of farm names. This creates a new farm item in the list of farms. Return OK the client if it is created successfully or ERROR if an error occurs.
\item If the farm name already exists, then send a message to the client containing the return value FARM\_NAME\_PRESENT.
\item Look at the list of pending requests and service these.
\item Go back and wait for other messages
\end{enumerate}


\item {\bf int	pvm\_get\_worker\_class\_id (char 	*farm\_name,char	*worker\_class\_name); }
\subsection*{Client side }
\begin{enumerate}
\item Take the global variable which identifies the server task (its tid) and
send a message to the server.
\item The message should contain 
opcode GET\_WORKER\_CLASS\_ID, farm name and the worker class name.
\item Receive reply from the server 
\item Unpack the message and extract the return value.
\item The return value (if nonnegative) will contain the worker class id 
(wcid) or the error message FARM\_NOT\_CREATED if the farm is not created by 
the farmer prior to invoking this call.
\item return the integer received from the server.
\end{enumerate}

\subsection*{Server side }
\begin{enumerate}
\item if opcode is GET\_WORKER\_CLASS\_ID
\item extract (unpack) farm name and worker class name.
\item Search for the farm item by farm name.
\item If item is not found send a reply containing FARM\_NOT\_CREATED error message.
\item Get the farm item (FItem), using this get access to the worker class list (WCList).
\item Search for worker class item by the worker class name.
\item If not found then, put the request on the list of pending requests and  look for other messages (while the farmer task blocks for a reply).
\item If item is found, then see the WCItem and get the worker class id (wcid).
\item Send the reply containing the wcid.
\end{enumerate}


\item 
{\bf int	pvm\_init\_worker\_class(char *farm\_name, char *worker\_class\_name); }

\subsection*{Client side }
\begin{enumerate}
\item Get the tid of the worker (pvm\_mytid )
\item 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.  (check the global variable containing the server task id).
\item Send a message to the server. It should contain
opcode INIT\_WORKER\_CLASS, farm name, and worker class name.
\item Wait for the reply  from the server. Get the status ERROR, or wcid and store it in a global variable to be used later.
\item Get and store the farmer name and the farmer task id  in a global variable which could be used later.

\item return OK
\end{enumerate}


\subsection*{Server side }
\begin{enumerate}
\item If opcode == INIT\_WORKER\_CLASS
\item Get the farm name, worker class name and worker task id.
\item Search the list of the farmers using this farm name.
\item If an item is not found then add the request to the list of pending requests
and service some other message (client remains blocked)
\item If the farmer item is found then, get the farm item (FItem) and look for
the list of worker classes (WCList).
\item Search the list of the worker classes using the worker class name (search by name).
\item If the item is not found then Append an item in the list of worker classes and get the worker class id.
\item If the worker class id exceeds the hard limit, return an ERROR.
\item Make an entry in the Cache of worker class ids regarding
the worker class item and the worker class id.
\item Append a worker task item in the list (using the wlist ) and send the wcid  to the client task.
\item If the worker class item is found then get the WCItem which contains the worker class id.
\item Append the worker task to this list 
\item Send the wcid to the worker task (client)
\item Service other messages
\end{enumerate}

\subsection*{Algorithm for ProcessPending() at the Server side.}
\begin{enumerate}
\item Check the number of pending items in the global list of the pending requests related to farm setup.
\item Pop one by one all the requests from the list.
\item If the opcode in the pending request is GET\_WORKER\_CLASS\_ID, then get the farm name, the worker class name, and the task id of the farmer. 
\item Execute ProcessGetWorkerClassId() with these parameters. This function is the same as above (when a pvm\_get\_worker\_class\_id() call is executed).
\item If the opcode is INIT\_WORKER\_CLASS, then get the farm name, the worker class name and the task id of the worker task.
\item Execute ProcessInitWorkerClass() with these parameters. This function is illustrated above. 
\item Note that all the algorithms of farm set up functions are executed as functions with parameters. This helps so that either the main server task can call these when the client requests for the service, or the ProcessPending() can call these.
\end{enumerate}

\item {\bf int	pvm\_send\_work\_packet(int id); 	}

\subsection*{Client side }
\begin{enumerate}
\item Get the currently used buffer id and save it. Create another buffer to
use for sending a message to the server task.
\item The message should contain, the opcode 
	SEND\_WORK\_PACKET and the the worker class id of the following message.\item After sending the message, make the user message buffer the current active
send buffer and send the user specified message.
\item Return OK.
\end{enumerate}

\subsection*{Server side }
\begin{enumerate}
\item Extract the opcode and the worker class id of the message. Also get the tid of the sender task (farmer task).

\item Using the tid, and the default message tag, receive another message from the 
farmer task. This would contain the work packet to be processed.
\item Call the scheduler with the worker class id and the message buffer id and the message tag of the buffer message.
\item In the scheduler, using the worker class id, locate the WCitem which contains the information about the work packets. 
\item If no worker class item is found, then return an ERROR. 
\item Find out if any worker task is free by checking if the item returned by asking for an item which has no packets pending, is NULL.
\item 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.
\item Clear the buffer used to receive the message and look for other messages.
\item If there are no workers which can handle the message, then check the list of work packets. If it does not exist, create it and use the pointer to
the list of work packets and append the current packet to the end of the list of work packets associated with the worker class.
\item Go back and check for other messages arriving at the server.
\end{enumerate}



\item {\bf int	bufid = pvm\_recv\_work\_packet(void); }

\subsection*{Client side }
\begin{enumerate}
\item Create a buffer and send a message to the server containing op\-code RECV\_\-WORK\_\-PACKET and the worker class id, which is stored in a global variable.
\item Block on a receive from the server task with a wildcard message tag ($-1$). 
\item After receiving the message find out the message tag of 
the buffer received. 
\item If the message tag is FARM\_HAS\_TERMINATED, then return the constant PvmFarmHasTerminated (a negative number).
\item Else, return the positive integer which contains the buffer id of the message received.
\end{enumerate}
 
\subsection*{Server side }
\begin{enumerate}
\item If the opcode matched RECV\_WORK\_PACKET, extract the unique worker class id of the client and the tid of the client (using the buffer id of the received message).
\item Using this worker class id, search for the worker class item using the Cache of worker class ids (array index is wcid).
\item If the worker class item is not present (pointer is NULL), then that means that the farm associated with the current worker class id has terminated and the data structure associated with the farm has been deleted. Send a message to the client which has a message tag of FARM\_HAS\_TERMINATED and look for other service requests.
\item If the worker class item is present then using the client tid, search for a worker item. If not present then return ERROR.
\item Pop a work packet from the list of work packets pending and associated with the current worker class. 
\item If there are no pending items (pointer is NULL), then set the  number of packets pending field of the worker task as 0 and look for other service requests.
\item If there is a packet pending then set the active send buffer id to that of the packet item which has been popped.
\item Send the message to the client and free the buffer which was sent and the pointer of the popped item (housekeeping).
\item Look for other service requests.
\end{enumerate}


\item {\bf int	pvm\_send\_reply\_packet(void); }


\subsection*{Client side }

\begin{enumerate}
\item Get the worker class id and the farmer tid of the worker
task and validate these (if these are improper, return ERROR).
\item Send the message  in the active send buffer with message tag equal to the worker class id to the farmer task directly.
\item Return OK.
\end{enumerate}

\subsection*{Server side }
\begin{enumerate}
\item No action is performed by the server as the packet is sent directly from the worker task to the farmer task.
\end{enumerate}


\item {\bf int	bufid = pvm\_recv\_reply\_packet(worker\_class\_id); }
\subsection*{Client side }
\begin{enumerate}
\item Block on a wildcard receive (-1 - from anyone),having the message tag of the worker class id.
\item If the buffer id is negative, return ERROR, else return the buffer id of the received message.
\end{enumerate}
 
\subsection*{Server side }
\begin{enumerate}
\item Nothing is done explicitly by the server as this involves only the client and the farmer task.
\end{enumerate}


\item {\bf int	pvm\_farm\_terminate(char *farm\_name); }

\subsection*{Client side }
\begin{enumerate}
\item Send a message to the server containing opcode FARM\_TERMINATE and the farm name.
\item Wait for a reply from the server and unpack the return value from the message once it is received.
\item Return this value. It could be OK or NO\_SUCH\_FARM or NOT\_FARM\_OWNER.
\end{enumerate}

\subsection*{Server side }
\begin{enumerate}
\item Receive the message and check if opcode is  FARM\_TERMINATE and get the tid of the client.
\item Search for the farm using the farm name.
\item If its not found, return a value NO\_SUCH\_FARM to the client.
\item If its found, check the client tid and the tid of the creator of the farm. If they donot match send a return value NOT\_FARM\_OWNER to the client.
\item If everything is OK, keep on popping all worker classes from the list of worker classes till there are no more worker classes.
\item In each worker class, get the worker class id and reset the entry in the Cache of the worker classes which contains the worker class id and the pointer to the worker class item. 
\item Then in the worker class while there are still worker items which have no packets pending (the ones which are blocked on the pvm\_recv\_work\_packet() request), process each worker item.
\item Send a message to the worker tasks which contains the inte\-ger FARM\-\_HAS\-\_TERMINATED with message tag of FARM\_HAS\_TERMINATED.
\item Set the number of packets pending as a non-zero number ($1$) so that the next search does not return the same entry.
\item Do the housekeeping with the buffer used for sending the message to the worker.
\item After all the blocked workers in the worker class have been sent this message, delete the worker list and the pending work packet list associated with the worker class.
\item After all  the worker classes have been processed, delete the worker class list (thereby destroying all worker classes associated with the farm).
\item Delete the farm item entry from the list of farms using the farm name.
\item Return a message OK to the farmer waiting for conformation on the farm.
\item Look for other messages.
\end{enumerate}

\item 
{\bf int	pvm\_start\_farmd(void);	}
\subsection*{Client side} 
\begin{enumerate}
\item Spawn a pvm task whose name is SERVER\_NAME. 
\item If it is spawned properly, return OK.
\item If there's an error in spawning the task, return ERROR.
\end{enumerate}
\subsection*{Server side}
\begin{enumerate}
\item Starts the pvmfarmd - farm daemon on one of the nodes.
\item Execute the function Server() which services requests from the tasks.
\end{enumerate}

\item 
{\bf int	pvm\_stop\_farmd(void); 	}
\subsection*{Client side}
\begin{enumerate}
\item Get the server task id. If it is not located, return ERROR.
\item Create a buffer and send an opcode STOP\_FARMD to the server process using DEF\_MSGTAG message tag.
\item Return OK.
\end{enumerate}
\subsection*{Server side}
\begin{enumerate}
\item If the opcode is STOP\_FARMD, then exit from the pvm system.
\item Exit from the operating system calling exit(0);
\item This shuts down the farming related server and should only be called once in the application after all useful farm related work is done. Even if this is not executed, the pvmfarmd can be shutdown manually from the pvm shell after the application has exited.
\end{enumerate}
\end{enumerate}



\end{document}

% ------------ end of document ----------------------

% here are some templates of different environments you can cut and paste:

\begin{figure}
\vspace{3in}
\caption{}
\end{figure}

\begin{itemize}
\item
...
\end{itemize}

\begin{enumerate}
\item
...
\end{enumerate}

