Statistics
| Branch: | Revision:

streamers / transaction.c @ 84ec8c3a

History | View | Annotate | Download (6.96 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
        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