1 /*
2  * Copyright (C) 2002-2009, Edmundo Albuquerque de Souza e Silva.
3  *
4  * This file may be distributed under the terms of the Q Public License
5  * as defined by Trolltech AS of Norway and appearing in the file
6  * LICENSE.QPL included in the packaging of this file.
7  *
8  * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
9  * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
10  * PURPOSE.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
11  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
12  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
13  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
14  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  *
16  */
17 
18 /***************************************************************************
19                              rmwinmask.c
20                              -------------------
21     begin                : Feb 2002
22     Authors              : Jorge Allyson Azevedo
23                            Milena Scanferla
24                            Daniel Sadoc
25     email                : {allyson,milena,sadoc}@land.ufrj.br
26  ***************************************************************************/
27 
28 #ifndef _RMWINMASK_C
29 
30 #include "rmwinmask.h"
31 
32 #ifdef SINGLE_NACK
33 
34 #define _RMWINMASK_C
35 
36 #include "rmcache.h"
37 #include "rminternals.h"
38 #include "rmstruct.h"
39 
40 #include <pthread.h>
41 #include <string.h>
42 #include <signal.h>
43 #include <errno.h>
44 
45 #include <sys/time.h>
46 #include <unistd.h>
47 #include <stdio.h>
48 #include <time.h>
49 
50 
51 
52 pthread_mutex_t nak_window_mask_mutex = PTHREAD_MUTEX_INITIALIZER;
53 
54 /*********************** Routines to handle the window nack mask ************************************/
55 
56 
57 
window_mask_get_bit2(int * window_mask,int position)58 int window_mask_get_bit2(int *window_mask, int position)
59 {
60     int retval = -1;
61 
62 #ifdef DWINDOW_MASK
63    fprintf(stderr,"DWINDOW_MASK window_mask_get_bit2: entering\n");
64 #endif
65     if (position < MAX_WINDOW_SIZE)
66     {
67 
68 #ifdef DWINDOW_MASK
69    fprintf(stderr,"DWINDOW_MASK window_mask_get_bit2: inside if\n");
70 #endif
71         pthread_mutex_lock(&nak_window_mask_mutex);
72 #ifdef DWINDOW_MASK
73    fprintf(stderr,"DWINDOW_MASK window_mask_get_bit2: inside if, after locking nak_window_mask_mutex\n");
74 #endif
75         retval = window_mask[position];
76         pthread_mutex_unlock(&nak_window_mask_mutex);
77     }
78 #ifdef DWINDOW_MASK
79    fprintf(stderr,"DWINDOW_MASK window_mask_get_bit2: leaving return=%d\n",retval);
80 #endif
81     return(retval);
82 }
83 
84 
85 /***************************************************************************************
86  *
87  * int window_mask_sn_within_window(int *window_mask, int sn, MEMBER_STATUS *mstatus)
88  *
89  * Arguments:	window_mask - pointer to the member's window mask;
90  *				sn - sn number;
91                 mstatus - pointer to the member's status structure;
92  *
93  * Return value: 1 on success;
94  *				 0 otherwise.
95  *
96  ***************************************************************************************/
97 
window_mask_sn_within_window(int * window_mask,int sn,MEMBER_STATUS * mstatus)98 int window_mask_sn_within_window(int *window_mask, int sn, MEMBER_STATUS *mstatus)
99 {
100 
101     if ( sn > ( (mstatus->last_seq_rcv) + MAX_WINDOW_SIZE ) || sn < (mstatus->last_seq_rcv + 1) )
102     {
103         return 0;
104     }
105     else
106     {
107         return 1;
108     }
109 
110 }
111 
window_mask_get_bit(int * window_mask,int sn,MEMBER_STATUS * mstatus)112 int window_mask_get_bit(int *window_mask, int sn, MEMBER_STATUS *mstatus)
113 {
114 
115     int aux_position=0;
116     int retval=-1;
117     int out_retval=0;
118 
119 #ifdef DWINDOW_MASK
120    fprintf(stderr,"DWINDOW_MASK window_mask_get_bit: Inside window_mask_get_bit\n");
121    fprintf(stderr,"DWINDOW_MASK window_mask_get_bit: mstatus=%p window_mask=%p sn=%d\n",mstatus,window_mask,sn);
122 #endif
123 
124    if( (mstatus!=NULL) && (out_retval=window_mask_sn_within_window(window_mask, sn, mstatus)))
125    {
126 
127        aux_position= ( mstatus->window_ini + ( sn - (mstatus->last_seq_rcv +1))) % MAX_WINDOW_SIZE;
128 #ifdef DWINDOW_MASK
129        fprintf(stderr,"DWINDOW_MASK window_mask_get_bit: aux_position=%d\n",aux_position);
130 #endif
131        retval=window_mask_get_bit2 ( mstatus->window_mask,aux_position );
132    }
133    else
134    {
135 #ifdef DWINDOW_MASK
136        if (out_retval==0)
137            fprintf(stderr,"window_mask_get_bit Warning: sn=%d out of window!\n",sn);
138 #endif
139    };
140 
141    return (retval);
142 
143 }
144 
145 
window_mask_set_bit2(int * window_mask,int position,int value)146 int window_mask_set_bit2(int *window_mask, int position, int value)
147 {
148 
149     int retval=1;
150 
151 #ifdef DWINDOW_MASK
152     fprintf(stderr,"DWINDOW_MASK window_mask_set_bit2: position=%d value=%d\n",position,value);
153 #endif
154 
155     if (position <= MAX_WINDOW_SIZE)
156     {
157         pthread_mutex_lock(&nak_window_mask_mutex);
158         window_mask[position] = value;
159         pthread_mutex_unlock(&nak_window_mask_mutex);
160 
161         retval=0;
162     }
163 
164     return (retval);
165 }
166 
167 
168 
window_mask_set_bit(int * window_mask,int sn,MEMBER_STATUS * mstatus,int value)169 int window_mask_set_bit(int *window_mask, int sn, MEMBER_STATUS *mstatus, int value)
170 {
171 
172     int retval=0;
173 
174 #ifdef DWINDOW_MASK
175     int l=0;
176     int h=0;
177     window_mask_array2numbers(window_mask,&h,&l,mstatus->window_ini);
178     fprintf(stderr,"DWINDOW_MASK window_mask_set_bit: window_mask before h=%d l=%d \n",h,l);
179 #endif
180 
181     if (window_mask_sn_within_window(window_mask, sn, mstatus))
182     {
183         retval=window_mask_set_bit2( window_mask,
184                           ( mstatus->window_ini + ( sn - (mstatus->last_seq_rcv + 1 )) ) % MAX_WINDOW_SIZE,
185                           value );
186 #ifdef DWINDOW_MASK
187     window_mask_array2numbers(window_mask,&h,&l,mstatus->window_ini);
188     fprintf(stderr,"DWINDOW_MASK window_mask_set_bit: window_mask after h=%d l=%d \n",h,l);
189 #endif
190 
191    }
192     return retval;
193 
194 }
195 
196 
window_mask_numbers2array(int * window_mask,int hmask,int lmask)197 int window_mask_numbers2array(int *window_mask, int  hmask, int  lmask)
198 {
199     int cont = 0;
200 
201     pthread_mutex_lock(&nak_window_mask_mutex);
202 
203     for (cont = 0; cont < min(MAX_WINDOW_SIZE,8*sizeof(int)); cont ++)
204     {
205         window_mask[ cont ] = (( lmask >> cont ) & 1 );
206     }
207     for (cont = sizeof(int) * 8; cont < min(MAX_WINDOW_SIZE,2*8*sizeof(int)); cont ++)
208     {
209         window_mask[ cont ] = ( ( hmask >> (cont - (sizeof(int)*8)) ) & 1 );
210     }
211 
212     pthread_mutex_unlock(&nak_window_mask_mutex);
213 
214     return 1;
215 }
216 
window_mask_array2numbers(int * window_mask,int * hmask,int * lmask,int mask_ini)217 int window_mask_array2numbers(int *window_mask, int *hmask, int *lmask, int mask_ini)
218 {
219     int cont = 0;
220 
221     pthread_mutex_lock(&nak_window_mask_mutex);
222 
223     *lmask = 0; *hmask = 0;
224 
225     for (cont = 0; cont < min(MAX_WINDOW_SIZE,8*sizeof(int)); cont ++)
226     {
227         if (window_mask[ (cont + mask_ini)%MAX_WINDOW_SIZE ] == 1)
228         {
229                 *lmask  |= (1 << cont);
230         }
231 
232     }
233     for (cont = sizeof(int) * 8; cont < min(MAX_WINDOW_SIZE,2*8*sizeof(int)); cont ++)
234     {
235         if (window_mask[ (cont + mask_ini)%MAX_WINDOW_SIZE ] == 1)
236         {
237                 *hmask  |= 1 << (cont - sizeof(int) * 8);
238         }
239 
240     }
241 
242     pthread_mutex_unlock(&nak_window_mask_mutex);
243 
244     return 1;
245 }
246 #endif  /* SINGLE_NACK */
247 #endif  /* _RMWINMASK_C */
248 
249