Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix the path to gras_stub_generator in the tutorial makefile
[simgrid.git] / doc / gtut-files / 11-explicitwait.c
1 /* Copyright (c) 2007, 2010. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5   * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include <stdlib.h>
8 #include <gras.h>
9
10 XBT_LOG_NEW_DEFAULT_CATEGORY(test,"My little example");
11
12 void message_declaration(void) {
13   gras_msgtype_declare("request", NULL);
14   gras_msgtype_declare("grant", NULL);
15   gras_msgtype_declare("release", NULL);
16 }
17
18 typedef struct {
19    int process_in_CS;
20    xbt_dynar_t waiting_queue;
21 } server_data_t;
22
23 int server_request_cb(gras_msg_cb_ctx_t ctx, void *payload) {
24   server_data_t *globals=(server_data_t*)gras_userdata_get();
25   gras_socket_t s = gras_msg_cb_ctx_from(ctx);
26  
27   if (globals->process_in_CS) {
28      xbt_dynar_push(globals->waiting_queue, &s);
29      INFO2("put %s:%d in waiting queue",gras_socket_peer_name(s),gras_socket_peer_port(s));
30   } else {     
31      globals->process_in_CS = 1;
32      INFO2("grant %s:%d since nobody wanted it",gras_socket_peer_name(s),gras_socket_peer_port(s));
33      gras_msg_send(s, "grant", NULL);     
34   }
35   return 0;
36 } /* end_of_request_callback */
37
38 int server_release_cb(gras_msg_cb_ctx_t ctx, void *payload) {
39   server_data_t *globals=(server_data_t*)gras_userdata_get();
40    
41   if (xbt_dynar_length(globals->waiting_queue)) {
42      gras_socket_t s;
43      xbt_dynar_pop(globals->waiting_queue, &s);
44      
45      INFO2("grant %s:%d since token released",gras_socket_peer_name(s),gras_socket_peer_port(s));
46      gras_msg_send(s, "grant", NULL);
47   } else {
48      globals->process_in_CS = 0;
49   }
50    
51   return 0;
52 } /* end_of_release_callback */
53
54 int server(int argc, char *argv[]) { 
55   gras_socket_t mysock;   /* socket on which I listen */
56   server_data_t *globals;
57   int i;
58   
59   gras_init(&argc,argv);
60   mysock = gras_socket_server(atoi(argv[1]));
61
62   globals=gras_userdata_new(server_data_t);
63   globals->process_in_CS=0;
64   globals->waiting_queue=xbt_dynar_new( sizeof(gras_socket_t), NULL /* not closing sockets */);
65
66   message_declaration();   
67   gras_cb_register("request",&server_request_cb);
68   gras_cb_register("release",&server_release_cb);
69
70   for (i=0; i<20; i++)  /* 5 requests of each process, 2 processes, 2 messages per request */
71     gras_msg_handle(-1); 
72     
73   gras_exit();
74   return 0;
75 } /* end_of_server */
76
77 void lock(gras_socket_t toserver) {
78    gras_msg_send(toserver,"request",NULL);
79    gras_msg_wait(-1, "grant",NULL,NULL);
80    INFO0("Granted by server");
81 } /* end_of_lock */
82
83 void unlock(gras_socket_t toserver) {
84    INFO0("Release the token");
85    gras_msg_send(toserver,"release",NULL);
86 } /* end_of_unlock */
87
88 int client(int argc, char *argv[]) {
89   int i;
90   gras_socket_t mysock;   /* socket on which I listen */
91   gras_socket_t toserver; /* socket used to write to the server */
92
93   gras_init(&argc,argv);
94
95   mysock = gras_socket_server_range(1024, 10000, 0, 0);
96   
97   VERB1("Client ready; listening on %d", gras_socket_my_port(mysock));
98   
99   gras_os_sleep(1.5); /* sleep 1 second and half */
100   message_declaration();
101   toserver = gras_socket_client(argv[1], atoi(argv[2]));
102
103   for (i=0;i<5; i++) {
104      gras_os_sleep(0.1);
105      lock(toserver);
106      gras_os_sleep(0.1);
107      unlock(toserver);
108   }
109   gras_exit();
110   return 0;
111 }