Revision 84ec8c3a

View differences:

Makefile
79 79

  
80 80
OBJS += chunk_signaling.o
81 81
OBJS += chunklock.o
82
OBJS += transaction.o
82 83
OBJS += channel.o
83 84
ifdef THREADS
84 85
CPPFLAGS += -DTHREADS
transaction.c
1
/*
2
 *  Copyright (c) 2010 Stefano Traverso
3
 *  Copyright (c) 2010 Csaba Kiraly
4
 *
5
 *  This is free software; see gpl-3.0.txt
6
 */
7

  
8
#include <stdint.h>
9
#include <stdio.h>
10
#include <stdbool.h>
11
#include <stdlib.h>
12
#include <sys/time.h>
13

  
14
#include "dbg.h"
15
#include "transaction.h"
16

  
17
typedef struct {
18
	uint16_t trans_id;
19
	double offer_sent_time;
20
	double accept_received_time;
21
	struct nodeID *id;
22
	} service_time;
23

  
24
// List to trace peer's service times
25
struct service_times_element {
26
	service_time st;
27
	struct service_times_element *backward;
28
	struct service_times_element *forward;
29
	};
30

  
31
static struct service_times_element *stl = NULL;
32

  
33

  
34
// register the moment when a transaction is started
35
// return a  new transaction id
36
uint16_t transaction_create(struct nodeID *id)
37
{
38
	static uint16_t trans_id = 1;
39

  
40
	struct service_times_element *stl2, *stl_iterator;
41
	struct timeval current_time;
42

  
43
	gettimeofday(&current_time, NULL);
44
	stl_iterator = stl;
45

  
46
	//create new trans_id;
47
	trans_id++;
48
	//skip 0
49
	if (!trans_id) trans_id++;
50

  
51
	// create a new element in the list with its offer_sent_time and set accept_received_time to -1.0
52
	stl2 = (struct service_times_element*) malloc(sizeof(struct service_times_element));
53
	stl2->st.trans_id = trans_id;
54
	stl2->st.offer_sent_time = current_time.tv_sec + current_time.tv_usec*1e-6;
55
	stl2->st.accept_received_time = -1.0;
56
	stl2->st.id = id;	//TODO: nodeid_dup
57
	stl2->backward = NULL;
58
	if (stl != NULL) {	//List is not empty
59
		dprintf("LIST: adding trans_id %d to the list, offer_sent_time %f -- LIST IS NOT EMPTY\n", trans_id, (current_time.tv_sec + current_time.tv_usec*1e-6));
60
		stl2->forward = stl;
61
		stl->backward = stl2;
62
		stl = stl2; 
63
	} else { // This is the first element to insert
64
		dprintf("LIST: adding trans_id %d to the list, offer_sent_time %f -- LIST IS EMPTY\n", trans_id, current_time.tv_sec + current_time.tv_usec*1e-6);
65
		stl2->forward = NULL;
66
		stl = stl2; 
67
	}
68
	return trans_id;
69
}
70

  
71

  
72
// Add the moment I received a positive select in a list
73
// return true if a valid trans_id is found
74
bool transaction_reg_accept(uint16_t trans_id, struct nodeID *id)
75
{
76
	struct service_times_element *stl_iterator;
77
	struct timeval current_time;
78

  
79
	gettimeofday(&current_time, NULL);
80
	stl_iterator = stl;
81

  
82
	// if an accept was received, look for the trans_id and add current_time to accept_received_time field
83
	dprintf("LIST: changing trans_id %d to the list -- ACCEPT\n", trans_id);
84
	// Iterate the list until you get the right element
85
	while (stl_iterator != NULL) {
86
			if (stl_iterator->st.trans_id == trans_id) {
87
				stl_iterator->st.accept_received_time = current_time.tv_sec + current_time.tv_usec*1e-6;
88
				return true;
89
				}
90
			stl_iterator = stl_iterator->forward;
91
	}
92
	return false;
93
}
94

  
95
// Used to get the time elapsed from the moment I get a positive select to the moment i get the ACK
96
// related to the same chunk
97
// it return -1.0 in case no trans_id is found
98
double transaction_remove(uint16_t trans_id) {
99
	struct service_times_element *stl_iterator;
100
	double to_return;
101

  
102
    dprintf("LIST: deleting trans_id %d\n", trans_id);
103

  
104
	// Start from the beginning of the list
105
	stl_iterator = stl;
106
	// Iterate the list until you get the right element
107
	while (stl_iterator != NULL) {
108
		if (stl_iterator->st.trans_id == trans_id)
109
			break;
110
		stl_iterator = stl_iterator->forward;
111
		}
112
	if (stl_iterator == NULL){
113
		// not found
114
        fprintf(stderr, "LIST: deleting trans_id %d -- STL is already NULL \n", trans_id);
115
		return -2.0;
116
	}
117

  
118
	to_return = stl_iterator->st.accept_received_time;
119

  
120
	// I have to remove the element from the list
121
	// If it is the first element
122
	if (stl_iterator->backward == NULL) {
123
		stl = stl_iterator->forward;
124
		// Check if I have more than one element in the list
125
		if (stl_iterator->forward != NULL)
126
			stl_iterator->forward->backward = NULL;
127
		stl_iterator->forward = NULL;
128
		}
129
	// I have to remove the last element of the list
130
	else {
131
		if (stl_iterator->forward == NULL) {
132
			stl_iterator->backward->forward = NULL;
133
			}
134
		// I have to remove an element in the middle
135
		else {
136
			stl_iterator->backward->forward = stl_iterator->forward;
137
			stl_iterator->forward->backward = stl_iterator->backward;
138
			}
139
		}
140
	free(stl_iterator);
141
	// Remove RTT measure from queue delay
142
// 	if (hrc_enabled() && (to_return.accept_received_time > 0.0 && get_measure(to_return.id, 1, MIN) > 0.0 && get_measure(to_return.id, 1, MIN) != NAN))
143
// 		return (to_return.accept_received_time - get_measure(to_return.id, 1, MIN));
144
	return to_return;
145
}
146

  
147
// Check the service times list to find elements over the timeout
148
void check_neighbor_status_list() {
149
	struct service_times_element *stl_iterator, *stl_aux;
150
	struct timeval current_time;
151
	bool something_got_removed;
152

  
153
	gettimeofday(&current_time, NULL);
154
	something_got_removed = false;
155
	
156
        dprintf("LIST: check trans_id list\n");
157
	
158
	// Check if list is empty
159
	if (stl == NULL) {
160
		return;
161
		}
162
        
163
	// Start from the beginning of the list
164
	stl_iterator = stl;
165
	stl_aux = stl;
166
	// Iterate the list until you get the right element
167
	while (stl_iterator != NULL) {
168
		// If the element has been in the list for a period greater than the timeout, remove it
169
//		if ( (stl_iterator->st.accept_received_time > 0.0 && ( (current_time.tv_sec + current_time.tv_usec*1e-6) - stl_iterator->st.accept_received_time) > TRANS_ID_MAX_LIFETIME) ||  ((current_time.tv_sec + current_time.tv_usec*1e-6) - stl_iterator->st.offer_sent_time > TRANS_ID_MAX_LIFETIME ) ) {
170
		if ( (current_time.tv_sec + current_time.tv_usec*1e-6 - stl_iterator->st.offer_sent_time) > TRANS_ID_MAX_LIFETIME) {
171
			 dprintf("LIST TIMEOUT: trans_id %d, offer_sent_time %f, accept_received_time %f\n", stl_iterator->st.trans_id, (double) ((current_time.tv_sec + current_time.tv_usec*1e-6) - stl_iterator->st.offer_sent_time  ), (double) ((current_time.tv_sec + current_time.tv_usec*1e-6) - stl_iterator->st.accept_received_time));
172
			 //fprintf(stderr, "LIST TIMEOUT: trans_id %d, offer_sent_time %f, accept_received_time %f\n", stl_iterator->st.trans_id, (double) ((current_time.tv_sec + current_time.tv_usec*1e-6) - stl_iterator->st.offer_sent_time  ), (double) ((current_time.tv_sec + current_time.tv_usec*1e-6) - stl_iterator->st.accept_received_time));
173
			// If it is the first element
174
			if (stl_iterator->backward == NULL) {
175
				stl = stl_iterator->forward;
176
				// Check if I have more than one element in the list
177
				if (stl_iterator->forward != NULL)
178
					stl_iterator->forward->backward = NULL;
179
				stl_iterator->forward = NULL;				
180
				}
181
			else { 	// I have to remove the last element of the list
182
				if (stl_iterator->forward == NULL) {
183
					stl_iterator->backward->forward = NULL;
184
					}
185
				// I have to remove an element in the middle
186
				else {
187
					stl_iterator->backward->forward = stl_iterator->forward;
188
					stl_iterator->forward->backward = stl_iterator->backward;
189
					}
190
				}
191
			something_got_removed = true;
192
			stl_aux = stl_iterator->forward;
193
			// Free the memory
194
			free(stl_iterator);
195
			}
196
		if (something_got_removed) {
197
			stl_iterator = stl_aux;
198
			something_got_removed = false;
199
			}
200
		else
201
			stl_iterator = stl_iterator->forward;
202
		}
203
	return;
204
}
205

  
206

  
transaction.h
1
/*
2
 *  Copyright (c) 2010 Stefano Traverso
3
 *  Copyright (c) 2010 Csaba Kiraly
4
 *
5
 *  This is free software; see gpl-3.0.txt
6
 */
7

  
8
#ifndef TRANSACTION_H
9
#define TRANSACTION_H
10

  
11
/* timeout of the offers thread. If it is not updated, it is deleted */
12
#define TRANS_ID_MAX_LIFETIME 1.0
13

  
14
struct nodeID;
15

  
16
// register the moment when a transaction is started
17
// return a  new transaction id
18
uint16_t transaction_create(struct nodeID *id);
19

  
20
// Add the moment I received a positive select in a list
21
// return true if a valid trans_id is found
22
bool transaction_reg_accept(uint16_t trans_id, struct nodeID *id);
23

  
24
// Used to get the time elapsed from the moment I get a positive select to the moment i get the ACK
25
// related to the same chunk
26
// it return -1.0 in case no trans_id is found
27
double transaction_remove(uint16_t trans_id);
28

  
29
// Check the service times list to find elements over the timeout
30
void check_neighbor_status_list();
31

  
32
#endif // TRANSACTION_H

Also available in: Unified diff