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