Statistics
| Branch: | Revision:

streamers / transaction.c @ c7c42215

History | View | Annotate | Download (7.04 KB)

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
        check_neighbor_status_list();
44

    
45
        gettimeofday(&current_time, NULL);
46
        stl_iterator = stl;
47

    
48
        //create new trans_id;
49
        trans_id++;
50
        //skip 0
51
        if (!trans_id) trans_id++;
52

    
53
        // create a new element in the list with its offer_sent_time and set accept_received_time to -1.0
54
        stl2 = (struct service_times_element*) malloc(sizeof(struct service_times_element));
55
        stl2->st.trans_id = trans_id;
56
        stl2->st.offer_sent_time = current_time.tv_sec + current_time.tv_usec*1e-6;
57
        stl2->st.accept_received_time = -1.0;
58
        stl2->st.id = id;        //TODO: nodeid_dup
59
        stl2->backward = NULL;
60
        if (stl != NULL) {        //List is not empty
61
                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));
62
                stl2->forward = stl;
63
                stl->backward = stl2;
64
                stl = stl2; 
65
        } else { // This is the first element to insert
66
                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);
67
                stl2->forward = NULL;
68
                stl = stl2; 
69
        }
70
        return trans_id;
71
}
72

    
73

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

    
81
        gettimeofday(&current_time, NULL);
82
        stl_iterator = stl;
83

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

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

    
104
    dprintf("LIST: deleting trans_id %d\n", trans_id);
105

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

    
120
        to_return = stl_iterator->st.accept_received_time;
121

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

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

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

    
208