Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
GRAS paper was published, sort the 2006 entries chronologically, and add a new one
[simgrid.git] / doc / gtut-tour-11-explicitwait.doc
index e84c101..37dade0 100644 (file)
 /**
-@page GRAS_tut_tour_explicitwait Lesson 11: Explicitely waiting for messages (TODO)
+@page GRAS_tut_tour_explicitwait Lesson 11: Explicitely waiting for messages
 
 \section GRAS_tut_tour_explicitwait_toc Table of Contents
  - \ref GRAS_tut_tour_explicitwait_intro
  - \ref GRAS_tut_tour_explicitwait_use
+   - \ref GRAS_tut_tour_explicitwait_algo
+   - \ref GRAS_tut_tour_explicitwait_code
+     - \ref GRAS_tut_tour_explicitwait_code_msg
+     - \ref GRAS_tut_tour_explicitwait_code_cb
+     - \ref GRAS_tut_tour_explicitwait_code_api
+     - \ref GRAS_tut_tour_explicitwait_code_smain
+     - \ref GRAS_tut_tour_explicitwait_code_cmain
  - \ref GRAS_tut_tour_explicitwait_recap
    
 <hr>
 
 \section GRAS_tut_tour_explicitwait_intro Introduction
 
+The messaging primitive we have seen so far are somehow limited on the
+receiver side. You have to attach a callback to a message type, and then go
+into an infinite loop. Sometimes, you want to block your execution until a
+message of a given type arrives. This often occures when you want to deal
+with synchronization problems. 
 
-\section GRAS_tut_tour_explicitwait_use Defining structure containing explicitwait
+As an example, we will study a simple centralized algorithm for mutual
+exclusion. In short, when the client wants to enter the critical section
+(CS), it sends a specific message to the server, and waits for the server to
+answer back with another message. While the client is "locked" waiting for
+the message, nothing else should occure for it (no callback or timer should
+be served). 
 
+The simplest interface to explicit message waiting allows you to specify the
+message type you are willing to accept (using gras_msg_wait()). But you can
+also specify a list of accepted message types (using gras_msg_wait_or()), or
+even provide your own message filters to decide precisly the kind of message
+you are waiting for (for example depending on message content -- this is
+done using gras_msg_wait_ext()).
+
+Any message received not matching your expectation will be queued for
+further use. Ie, they will be stored in memory and are candidates for the
+next gras_msg_handle() or gras_msg_wait().
+
+\section GRAS_tut_tour_explicitwait_use Example: mutual exclusion with centralized coordinator
+
+\subsection GRAS_tut_tour_explicitwait_algo GRAS modelization of the algorithm
+
+This section naturally provides an example of how to use gras_msg_wait(),
+but it can also be seen as an example of the guidelines provided in 
+\ref GRAS_howto_design.
+
+So, here are the caracteristics of our example:
+
+There is two types of processes: 
+ - several <i>clients</i> which want to enter a critical section
+ - a <i>server</i>, which grants clients to enter the CS when no other
+   process is already in it.
+
+There is three kind of messages in the system:
+ - <i>request</i> (from clients to server) to ask for the permission to enter the CS
+ - <i>release</i> (from clients to server) to express that they exited the CS
+ - <i>grant</i> (from server to clients) to allow the given process to enter the CS
+
+The server has 2 callbacks attached:
+ - When it gets a <i>request</i>, it checks whether their is already a process in
+   the CS. If yes, it adds the requester into a FIFO list. If not, it sends
+   a <i>grant</i> message to the asking client.
+ - When it gets a <i>release</i>, it checks whether there is some waiting
+   processes in the waiting queue. If yes, it dequeues the first one and
+   send a <i>grant</i> message to it. If no, it notes that the CS is free.
+   
+The server has two private data (for the callbacks to work):
+ - a boolean indicating whether there is a process in the CS already
+ - a waiting queue (#xbt_dynar_t is quite natural to code this).
+The client interface is composed of two functions:
+ - lock(), which tries to get the grant from the server to enter the CS.
+   This is where explicit waiting comes into the game. This function sends a
+   <i>request</i> to the server, and blocks until the server issues a
+   <i>grant</i> back.
+ - unlock(), which informs the server that we exited the CS (by sending a
+   <i>release</i> message)
+
+\subsection GRAS_tut_tour_explicitwait_code The code step-by-step
+
+\subsubsection GRAS_tut_tour_explicitwait_code_msg a) Messages declaration
+
+First of all, we should have a function declaring all used messages. As said
+before, this should be in a separate function so that it can be shared
+between all process kinds and avoid code dupplication which may result in
+definition discrepency.
+
+Here, there is no payload attached to the messages.
+
+\dontinclude 11-explicitwait.c
+\skip message_declaration
+\until }
+
+\subsubsection GRAS_tut_tour_explicitwait_code_cb b) Defining private data and callbacks of the server
+
+Then, we define the callbacks that should be invoqued on the server side 
+when some messages are received, as previously. For this, we also have to
+declare a structure for the private data of the server.
+
+\skip typedef
+\until end_of_release_callback
+
+\subsubsection GRAS_tut_tour_explicitwait_code_api c) Client-side API
+
+Now, we define the functions that the client must call to use the service.
+Note that this is where the explicit wait feature is used.
+
+\skip lock
+\until end_of_unlock
+
+\subsubsection GRAS_tut_tour_explicitwait_code_smain d) Server-side initialization
+
+The core of our distributed service is implemented (protocol, actions on
+server side, and accessing function on client side). We should now
+initialize the server and let it wait for incomming messages. 
+
+Defining when to stop the server can become tricky. The simplest solution is
+to never let the server stop. It simply runs forever. But the simulator will
+raise an error at the end, so I won't do so here to keep the output clean.
+Another solution would be to deal with client membership properly: clients
+registers, use the service and quit afterward. When no client use the
+service, the server stops. This would be a bit difficult to implement
+(actually, there is an AMOK module to do so simply: \ref AMOK_pm).
+Here, we will just hardcode that the clients ask 5 times for the token, and
+that there is two clients. This clearly simplify the problem.
+
+\dontinclude 11-explicitwait.c
+\skip gras_userdata_new
+\until gras_msg_handle
+
+\subsubsection GRAS_tut_tour_explicitwait_code_cmain e) Client-side use
+
+And now, the client is <b>really</b> simple to write:
+
+\skip message_declaration
+\until }
 
 \section GRAS_tut_tour_explicitwait_recap Recapping everything together
 
 The program now reads:
-include 11-explicitwait.c
+\include 11-explicitwait.c
 
 Which produces the expected output:
-include 11-explicitwait.output
-
+\include 11-explicitwait.output
 
 */