GNUnet 0.21.2
bandwidth.c File Reference

functions related to bandwidth (unit) More...

#include "platform.h"
#include "gnunet_util_lib.h"
Include dependency graph for bandwidth.c:

Go to the source code of this file.

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "util-bandwidth", __VA_ARGS__)
 

Functions

struct GNUNET_BANDWIDTH_Value32NBO GNUNET_BANDWIDTH_value_init (uint32_t bytes_per_second)
 Create a new bandwidth value. More...
 
struct GNUNET_BANDWIDTH_Value32NBO GNUNET_BANDWIDTH_value_min (struct GNUNET_BANDWIDTH_Value32NBO b1, struct GNUNET_BANDWIDTH_Value32NBO b2)
 Compute the MIN of two bandwidth values. More...
 
struct GNUNET_BANDWIDTH_Value32NBO GNUNET_BANDWIDTH_value_max (struct GNUNET_BANDWIDTH_Value32NBO b1, struct GNUNET_BANDWIDTH_Value32NBO b2)
 Compute the MAX of two bandwidth values. More...
 
struct GNUNET_BANDWIDTH_Value32NBO GNUNET_BANDWIDTH_value_sum (struct GNUNET_BANDWIDTH_Value32NBO b1, struct GNUNET_BANDWIDTH_Value32NBO b2)
 Compute the SUM of two bandwidth values. More...
 
uint64_t GNUNET_BANDWIDTH_value_get_available_until (struct GNUNET_BANDWIDTH_Value32NBO bps, struct GNUNET_TIME_Relative deadline)
 At the given bandwidth, calculate how much traffic will be available until the given deadline. More...
 
struct GNUNET_TIME_Relative GNUNET_BANDWIDTH_value_get_delay_for (struct GNUNET_BANDWIDTH_Value32NBO bps, uint64_t size)
 At the given bandwidth, calculate how long it would take for size bytes to be transmitted. More...
 
static void excess_trigger (void *cls)
 Task run whenever we hit the bandwidth limit for a tracker. More...
 
static void update_excess (struct GNUNET_BANDWIDTH_Tracker *av)
 Recalculate when we might need to call the excess callback. More...
 
void GNUNET_BANDWIDTH_tracker_init2 (struct GNUNET_BANDWIDTH_Tracker *av, GNUNET_BANDWIDTH_TrackerUpdateCallback update_cb, void *update_cb_cls, struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit, uint32_t max_carry_s, GNUNET_BANDWIDTH_ExcessNotificationCallback excess_cb, void *excess_cb_cls)
 Initialize bandwidth tracker. More...
 
void GNUNET_BANDWIDTH_tracker_init (struct GNUNET_BANDWIDTH_Tracker *av, GNUNET_BANDWIDTH_TrackerUpdateCallback update_cb, void *update_cb_cls, struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit, uint32_t max_carry_s)
 Initialize bandwidth tracker. More...
 
void GNUNET_BANDWIDTH_tracker_notification_stop (struct GNUNET_BANDWIDTH_Tracker *av)
 Stop notifying about tracker updates and excess notifications. More...
 
static void update_tracker (struct GNUNET_BANDWIDTH_Tracker *av)
 Update the tracker, looking at the current time and bandwidth consumption data. More...
 
int GNUNET_BANDWIDTH_tracker_consume (struct GNUNET_BANDWIDTH_Tracker *av, ssize_t size)
 Notify the tracker that a certain number of bytes of bandwidth have been consumed. More...
 
struct GNUNET_TIME_Relative GNUNET_BANDWIDTH_tracker_get_delay (struct GNUNET_BANDWIDTH_Tracker *av, size_t size)
 Compute how long we should wait until consuming 'size' bytes of bandwidth in order to stay within the given quota. More...
 
int64_t GNUNET_BANDWIDTH_tracker_get_available (struct GNUNET_BANDWIDTH_Tracker *av)
 Compute how many bytes are available for consumption right now. More...
 
void GNUNET_BANDWIDTH_tracker_update_quota (struct GNUNET_BANDWIDTH_Tracker *av, struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit)
 Update quota of bandwidth tracker. More...
 

Detailed Description

functions related to bandwidth (unit)

Author
Christian Grothoff

Definition in file bandwidth.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "util-bandwidth", __VA_ARGS__)

Definition at line 31 of file bandwidth.c.

Function Documentation

◆ excess_trigger()

static void excess_trigger ( void *  cls)
static

Task run whenever we hit the bandwidth limit for a tracker.

Parameters
clsthe struct GNUNET_BANDWIDTH_Tracker

Definition at line 150 of file bandwidth.c.

151{
152 struct GNUNET_BANDWIDTH_Tracker *av = cls;
153
154 av->excess_task = NULL;
155 if (NULL != av->excess_cb)
156 {
158 "Notifying application about excess bandwidth\n");
159 av->excess_cb (av->excess_cb_cls);
160 }
161}
#define GNUNET_log(kind,...)
@ GNUNET_ERROR_TYPE_DEBUG
Struct to track available bandwidth.
struct GNUNET_SCHEDULER_Task * excess_task
Task scheduled to call the excess_cb once we have reached the maximum bandwidth the tracker can hold.
GNUNET_BANDWIDTH_ExcessNotificationCallback excess_cb
Function we call if the tracker is about to throw away bandwidth due to excess (max carry exceeded).
void * excess_cb_cls
Closure for excess_cb.

References GNUNET_BANDWIDTH_Tracker::excess_cb, GNUNET_BANDWIDTH_Tracker::excess_cb_cls, GNUNET_BANDWIDTH_Tracker::excess_task, GNUNET_ERROR_TYPE_DEBUG, and GNUNET_log.

Referenced by update_excess().

Here is the caller graph for this function:

◆ update_excess()

static void update_excess ( struct GNUNET_BANDWIDTH_Tracker av)
static

Recalculate when we might need to call the excess callback.

Definition at line 168 of file bandwidth.c.

169{
170 struct GNUNET_TIME_Relative delay;
171 struct GNUNET_TIME_Absolute now;
172 uint64_t delta_time;
173 uint64_t delta_avail;
174 int64_t left_bytes;
175 uint64_t max_carry;
176 int64_t current_consumption;
177
178 if (NULL == av->excess_cb)
179 return; /* nothing to do */
181 delta_time = now.abs_value_us - av->last_update__.abs_value_us;
182 delta_avail =
183 (delta_time * ((unsigned long long) av->available_bytes_per_s__)
184 + 500000LL)
185 / 1000000LL;
186 current_consumption = av->consumption_since_last_update__ - delta_avail;
187 if (current_consumption > av->consumption_since_last_update__)
188 {
189 /* integer underflow, cap! */
190 current_consumption = INT64_MIN;
191 }
192 /* negative current_consumption means that we have savings */
193 max_carry = ((uint64_t) av->available_bytes_per_s__) * av->max_carry_s__;
194 if (max_carry < GNUNET_MAX_MESSAGE_SIZE)
195 max_carry = GNUNET_MAX_MESSAGE_SIZE;
196 if (max_carry > INT64_MAX)
197 max_carry = INT64_MAX;
198 left_bytes = current_consumption + max_carry;
199 if (left_bytes < current_consumption)
200 {
201 /* integer overflow, cap! */
202 left_bytes = INT64_MAX;
203 }
204 /* left_bytes now contains the number of bytes needed until
205 we have more savings than allowed */
206 if (left_bytes < 0)
207 {
208 /* having excess already */
209 delay = GNUNET_TIME_UNIT_ZERO;
210 }
211 else
212 {
213 double factor = 1.0 * left_bytes / (double) av->available_bytes_per_s__;
214 delay =
216 (unsigned long long) factor);
217 }
218 GNUNET_log (
220 "At %llu bps it will take us %s for %lld bytes to reach excess threshold\n",
221 (unsigned long long) av->available_bytes_per_s__,
223 (long long) left_bytes);
224 if (NULL != av->excess_task)
227}
static void excess_trigger(void *cls)
Task run whenever we hit the bandwidth limit for a tracker.
Definition: bandwidth.c:150
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
@ GNUNET_NO
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:981
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1278
struct GNUNET_TIME_Relative GNUNET_TIME_relative_saturating_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Saturating multiply relative time by a given factor.
Definition: time.c:531
#define GNUNET_TIME_UNIT_SECONDS
One second.
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:570
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
int64_t consumption_since_last_update__
Number of bytes consumed since we last updated the tracker.
struct GNUNET_TIME_Absolute last_update__
Time when we last updated the tracker.
uint32_t available_bytes_per_s__
Bandwidth limit to enforce in bytes per second.
uint32_t max_carry_s__
Maximum number of seconds over which bandwidth may "accumulate".
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.

References GNUNET_TIME_Absolute::abs_value_us, GNUNET_BANDWIDTH_Tracker::available_bytes_per_s__, GNUNET_BANDWIDTH_Tracker::consumption_since_last_update__, GNUNET_BANDWIDTH_Tracker::excess_cb, GNUNET_BANDWIDTH_Tracker::excess_task, excess_trigger(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MAX_MESSAGE_SIZE, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_cancel(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_saturating_multiply(), GNUNET_TIME_UNIT_SECONDS, GNUNET_TIME_UNIT_ZERO, GNUNET_BANDWIDTH_Tracker::last_update__, and GNUNET_BANDWIDTH_Tracker::max_carry_s__.

Referenced by GNUNET_BANDWIDTH_tracker_consume(), GNUNET_BANDWIDTH_tracker_init2(), and GNUNET_BANDWIDTH_tracker_update_quota().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_tracker()

static void update_tracker ( struct GNUNET_BANDWIDTH_Tracker av)
static

Update the tracker, looking at the current time and bandwidth consumption data.

Parameters
avtracker to update

Definition at line 321 of file bandwidth.c.

322{
323 struct GNUNET_TIME_Absolute now;
324 uint64_t delta_time;
325 uint64_t delta_avail;
326 uint64_t left_bytes;
327 uint64_t max_carry;
328
330 delta_time = now.abs_value_us - av->last_update__.abs_value_us;
331 delta_avail =
332 (delta_time * ((unsigned long long) av->available_bytes_per_s__)
333 + 500000LL)
334 / 1000000LL;
335 av->consumption_since_last_update__ -= delta_avail;
336 av->last_update__ = now;
338 {
339 left_bytes = -av->consumption_since_last_update__;
340 max_carry =
341 ((unsigned long long) av->available_bytes_per_s__) * av->max_carry_s__;
342 if (max_carry < GNUNET_MAX_MESSAGE_SIZE)
343 max_carry = GNUNET_MAX_MESSAGE_SIZE;
344 if (max_carry > INT64_MAX)
345 max_carry = INT64_MAX;
346 if (max_carry > left_bytes)
347 av->consumption_since_last_update__ = -left_bytes;
348 else
349 av->consumption_since_last_update__ = -max_carry;
350 }
351#if ! defined(GNUNET_CULL_LOGGING)
352 {
354
355 delta.rel_value_us = delta_time;
357 "Tracker %p updated, consumption at %lld at %u Bps, last update was %s ago\n",
358 av,
359 (long long) av->consumption_since_last_update__,
360 (unsigned int) av->available_bytes_per_s__,
362 }
363#endif
364}
#define LOG(kind,...)
Definition: bandwidth.c:31
@ GNUNET_YES
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:36
uint64_t rel_value_us
The actual value.

References GNUNET_TIME_Absolute::abs_value_us, GNUNET_BANDWIDTH_Tracker::available_bytes_per_s__, GNUNET_BANDWIDTH_Tracker::consumption_since_last_update__, delta, GNUNET_ERROR_TYPE_DEBUG, GNUNET_MAX_MESSAGE_SIZE, GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get(), GNUNET_YES, GNUNET_BANDWIDTH_Tracker::last_update__, LOG, GNUNET_BANDWIDTH_Tracker::max_carry_s__, and GNUNET_TIME_Relative::rel_value_us.

Referenced by GNUNET_BANDWIDTH_tracker_consume(), GNUNET_BANDWIDTH_tracker_get_available(), GNUNET_BANDWIDTH_tracker_get_delay(), and GNUNET_BANDWIDTH_tracker_update_quota().

Here is the call graph for this function:
Here is the caller graph for this function: