GNUnet  0.19.4
testbed_api_operations.c File Reference

functions to manage operation queues More...

#include "platform.h"
#include "testbed_api_operations.h"
#include "testbed_api_sd.h"
Include dependency graph for testbed_api_operations.c:

Go to the source code of this file.

Data Structures

struct  QueueEntry
 An entry in the operation queue. More...
 
struct  TimeSlot
 A slot to record time taken by an operation. More...
 
struct  FeedbackCtx
 Context for operation queues of type OPERATION_QUEUE_TYPE_ADAPTIVE. More...
 
struct  OperationQueue
 Queue of operations where we can only support a certain number of concurrent operations of a particular type. More...
 
struct  ReadyQueueEntry
 An entry in the ready queue (implemented as DLL) More...
 
struct  GNUNET_TESTBED_Operation
 Opaque handle to an abstract operation to be executed by the testing framework. More...
 

Macros

#define ADAPTIVE_QUEUE_DEFAULT_HISTORY   40
 The number of readings containing past operation's timing information that we keep track of for adaptive queues. More...
 
#define ADAPTIVE_QUEUE_DEFAULT_MAX_ACTIVE   4
 The number of parallel operations we start with by default for adaptive queues. More...
 

Enumerations

enum  OperationState {
  OP_STATE_INIT , OP_STATE_WAITING , OP_STATE_READY , OP_STATE_ACTIVE ,
  OP_STATE_INACTIVE
}
 Operation state. More...
 

Functions

static void assign_timeslot (struct GNUNET_TESTBED_Operation *op, struct OperationQueue *queue)
 Assigns the given operation a time slot from the given operation queue. More...
 
static void remove_queue_entry (struct GNUNET_TESTBED_Operation *op, unsigned int index)
 Removes a queue entry of an operation from one of the operation queues' lists depending on the state of the operation. More...
 
static void change_state (struct GNUNET_TESTBED_Operation *op, enum OperationState state)
 Changes the state of the operation while moving its associated queue entries in the operation's operation queues. More...
 
static void rq_remove (struct GNUNET_TESTBED_Operation *op)
 Removes an operation from the ready queue. More...
 
static void process_rq_task (void *cls)
 Processes the ready queue by calling the operation start callback of the operation at the head. More...
 
static void rq_add (struct GNUNET_TESTBED_Operation *op)
 Adds the operation to the ready queue and starts the 'process_rq_task'. More...
 
static int is_queue_empty (struct OperationQueue *opq)
 Checks if the given operation queue is empty or not. More...
 
static int decide_capacity (struct OperationQueue *opq, struct QueueEntry *entry, struct GNUNET_TESTBED_Operation ***ops_, unsigned int *n_ops_)
 Checks if the given operation queue has enough resources to provide for the operation of the given queue entry. More...
 
static void merge_ops (struct GNUNET_TESTBED_Operation ***old, unsigned int *n_old, struct GNUNET_TESTBED_Operation **new, unsigned int n_new)
 Merges an array of operations into another, eliminating duplicates. More...
 
static int check_readiness (struct GNUNET_TESTBED_Operation *op)
 Checks for the readiness of an operation and schedules a operation start task. More...
 
static void defer (struct GNUNET_TESTBED_Operation *op)
 Defers a ready to be executed operation back to waiting. More...
 
static void cleanup_tslots (struct OperationQueue *queue)
 Cleanups the array of timeslots of an operation queue. More...
 
static void adaptive_queue_set_max_active (struct OperationQueue *queue, unsigned int n)
 Cleansup the existing timing slots and sets new timing slots in the given queue to accommodate given number of max active operations. More...
 
static void adapt_parallelism (struct OperationQueue *queue)
 Adapts parallelism in an adaptive queue by using the statistical data from the feedback context. More...
 
static void update_tslots (struct GNUNET_TESTBED_Operation *op)
 update tslots with the operation's completion time. More...
 
struct GNUNET_TESTBED_OperationGNUNET_TESTBED_operation_create_ (void *cls, OperationStart start, OperationRelease release)
 Create an 'operation' to be performed. More...
 
struct OperationQueueGNUNET_TESTBED_operation_queue_create_ (enum OperationQueueType type, unsigned int max_active)
 Create an operation queue. More...
 
static void queue_destroy (struct OperationQueue *queue)
 Cleanup the given operation queue. More...
 
void GNUNET_TESTBED_operation_queue_destroy_ (struct OperationQueue *queue)
 Destroys an operation queue. More...
 
int GNUNET_TESTBED_operation_queue_destroy_empty_ (struct OperationQueue *queue)
 Destroys the operation queue if it is empty. More...
 
static void recheck_waiting (struct OperationQueue *opq)
 Rechecks if any of the operations in the given operation queue's waiting list can be made active. More...
 
void GNUNET_TESTBED_operation_queue_reset_max_active_ (struct OperationQueue *queue, unsigned int max_active)
 Function to reset the maximum number of operations in the given queue. More...
 
void GNUNET_TESTBED_operation_queue_insert2_ (struct OperationQueue *queue, struct GNUNET_TESTBED_Operation *op, unsigned int nres)
 Add an operation to a queue. More...
 
void GNUNET_TESTBED_operation_queue_insert_ (struct OperationQueue *queue, struct GNUNET_TESTBED_Operation *op)
 Add an operation to a queue. More...
 
void GNUNET_TESTBED_operation_begin_wait_ (struct GNUNET_TESTBED_Operation *op)
 Marks the given operation as waiting on the queues. More...
 
void GNUNET_TESTBED_operation_inactivate_ (struct GNUNET_TESTBED_Operation *op)
 Marks an active operation as inactive - the operation will be kept in a ready-to-be-released state and continues to hold resources until another operation contents for them. More...
 
void GNUNET_TESTBED_operation_activate_ (struct GNUNET_TESTBED_Operation *op)
 Marks and inactive operation as active. More...
 
void GNUNET_TESTBED_operation_release_ (struct GNUNET_TESTBED_Operation *op)
 An operation is 'done' (was cancelled or finished); remove it from the queues and release associated resources. More...
 
void GNUNET_TESTBED_operation_mark_failed (struct GNUNET_TESTBED_Operation *op)
 Marks an operation as failed. More...
 
void __attribute__ ((destructor))
 Cleanup expired operation queues. More...
 

Variables

static struct ReadyQueueEntryrq_head
 DLL head for the ready queue. More...
 
static struct ReadyQueueEntryrq_tail
 DLL tail for the ready queue. More...
 
static struct OperationQueue ** expired_opqs
 Array of operation queues which are to be destroyed. More...
 
static unsigned int n_expired_opqs
 Number of expired operation queues in the above array. More...
 
struct GNUNET_SCHEDULER_Taskprocess_rq_task_id
 The id of the task to process the ready queue. More...
 

Detailed Description

functions to manage operation queues

Author
Christian Grothoff
Sree Harsha Totakura

Definition in file testbed_api_operations.c.

Macro Definition Documentation

◆ ADAPTIVE_QUEUE_DEFAULT_HISTORY

#define ADAPTIVE_QUEUE_DEFAULT_HISTORY   40

The number of readings containing past operation's timing information that we keep track of for adaptive queues.

Definition at line 36 of file testbed_api_operations.c.

◆ ADAPTIVE_QUEUE_DEFAULT_MAX_ACTIVE

#define ADAPTIVE_QUEUE_DEFAULT_MAX_ACTIVE   4

The number of parallel operations we start with by default for adaptive queues.

Definition at line 42 of file testbed_api_operations.c.

Enumeration Type Documentation

◆ OperationState

Operation state.

Enumerator
OP_STATE_INIT 

The operation is just created and is in initial state.

OP_STATE_WAITING 

The operation is currently waiting for resources.

OP_STATE_READY 

The operation is ready to be started.

OP_STATE_ACTIVE 

The operation has started and is active.

OP_STATE_INACTIVE 

The operation is inactive.

It still holds resources on the operation queues. However, this operation will be evicted when another operation requires resources from the maxed out queues this operation is holding resources from.

Definition at line 250 of file testbed_api_operations.c.

251 {
256 
261 
266 
271 
279 };
@ OP_STATE_WAITING
The operation is currently waiting for resources.
@ OP_STATE_ACTIVE
The operation has started and is active.
@ OP_STATE_INIT
The operation is just created and is in initial state.
@ OP_STATE_READY
The operation is ready to be started.
@ OP_STATE_INACTIVE
The operation is inactive.

Function Documentation

◆ assign_timeslot()

static void assign_timeslot ( struct GNUNET_TESTBED_Operation op,
struct OperationQueue queue 
)
static

Assigns the given operation a time slot from the given operation queue.

Parameters
opthe operation
queuethe operation queue
Returns
the timeslot

Definition at line 413 of file testbed_api_operations.c.

415 {
416  struct FeedbackCtx *fctx = queue->fctx;
417  struct TimeSlot *tslot;
418 
420  tslot = fctx->alloc_head;
421  GNUNET_assert (NULL != tslot);
422  GNUNET_CONTAINER_DLL_remove (fctx->alloc_head, fctx->alloc_tail, tslot);
423  GNUNET_CONTAINER_DLL_insert_tail (op->tslots_head, op->tslots_tail, tslot);
424  tslot->op = op;
425 }
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static void queue(const char *hostname)
Add hostname to the list of requests to be made.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Context for operation queues of type OPERATION_QUEUE_TYPE_ADAPTIVE.
struct TimeSlot * alloc_head
Head for DLL of time slots which are free to be allocated to operations.
struct TimeSlot * alloc_tail
Tail for DLL of time slots which are free to be allocated to operations.
A slot to record time taken by an operation.
struct GNUNET_TESTBED_Operation * op
The operation to which this timeslot is currently allocated to.
@ OPERATION_QUEUE_TYPE_ADAPTIVE
Operation queue which adapts the number of operations to be active based on the operation completion ...

References FeedbackCtx::alloc_head, FeedbackCtx::alloc_tail, GNUNET_assert, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_CONTAINER_DLL_remove, op, TimeSlot::op, OPERATION_QUEUE_TYPE_ADAPTIVE, and queue().

Referenced by process_rq_task().

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

◆ remove_queue_entry()

static void remove_queue_entry ( struct GNUNET_TESTBED_Operation op,
unsigned int  index 
)
static

Removes a queue entry of an operation from one of the operation queues' lists depending on the state of the operation.

Parameters
opthe operation whose entry has to be removed
indexthe index of the entry in the operation's array of queue entries

Definition at line 436 of file testbed_api_operations.c.

437 {
438  struct OperationQueue *opq;
439  struct QueueEntry *entry;
440 
441  opq = op->queues[index];
442  entry = op->qentries[index];
443  switch (op->state)
444  {
445  case OP_STATE_INIT:
446  GNUNET_assert (0);
447  break;
448 
449  case OP_STATE_WAITING:
450  GNUNET_CONTAINER_DLL_remove (opq->wq_head, opq->wq_tail, entry);
451  break;
452 
453  case OP_STATE_READY:
454  GNUNET_CONTAINER_DLL_remove (opq->rq_head, opq->rq_tail, entry);
455  break;
456 
457  case OP_STATE_ACTIVE:
458  GNUNET_CONTAINER_DLL_remove (opq->aq_head, opq->aq_tail, entry);
459  break;
460 
461  case OP_STATE_INACTIVE:
462  GNUNET_CONTAINER_DLL_remove (opq->nq_head, opq->nq_tail, entry);
463  break;
464  }
465 }
Queue of operations where we can only support a certain number of concurrent operations of a particul...
struct QueueEntry * rq_tail
DLL tail for the ready queue.
struct QueueEntry * aq_head
DLL head for the active queue.
struct QueueEntry * aq_tail
DLL tail for the active queue.
struct QueueEntry * nq_head
DLL head for the inactive queue.
struct QueueEntry * wq_head
DLL head for the wait queue.
struct QueueEntry * wq_tail
DLL tail for the wait queue.
struct QueueEntry * nq_tail
DLL tail for the inactive queue.
struct QueueEntry * rq_head
DLL head for the ready queue.
An entry in the operation queue.

References OperationQueue::aq_head, OperationQueue::aq_tail, GNUNET_assert, GNUNET_CONTAINER_DLL_remove, OperationQueue::nq_head, OperationQueue::nq_tail, op, OP_STATE_ACTIVE, OP_STATE_INACTIVE, OP_STATE_INIT, OP_STATE_READY, OP_STATE_WAITING, OperationQueue::rq_head, OperationQueue::rq_tail, OperationQueue::wq_head, and OperationQueue::wq_tail.

Referenced by change_state(), and GNUNET_TESTBED_operation_release_().

Here is the caller graph for this function:

◆ change_state()

static void change_state ( struct GNUNET_TESTBED_Operation op,
enum OperationState  state 
)
static

Changes the state of the operation while moving its associated queue entries in the operation's operation queues.

Parameters
opthe operation whose state has to be changed
statethe state the operation should have. It cannot be OP_STATE_INIT

Definition at line 476 of file testbed_api_operations.c.

477 {
478  struct QueueEntry *entry;
479  struct OperationQueue *opq;
480  unsigned int cnt;
481  unsigned int s;
482 
484  GNUNET_assert (NULL != op->queues);
485  GNUNET_assert (NULL != op->nres);
486  GNUNET_assert ((OP_STATE_INIT == op->state) || (NULL != op->qentries));
487  GNUNET_assert (op->state != state);
488  for (cnt = 0; cnt < op->nqueues; cnt++)
489  {
490  if (OP_STATE_INIT == op->state)
491  {
492  entry = GNUNET_new (struct QueueEntry);
493  entry->op = op;
494  entry->nres = op->nres[cnt];
495  s = cnt;
496  GNUNET_array_append (op->qentries, s, entry);
497  }
498  else
499  {
500  entry = op->qentries[cnt];
501  remove_queue_entry (op, cnt);
502  }
503  opq = op->queues[cnt];
504  switch (state)
505  {
506  case OP_STATE_INIT:
507  GNUNET_assert (0);
508  break;
509 
510  case OP_STATE_WAITING:
512  break;
513 
514  case OP_STATE_READY:
516  break;
517 
518  case OP_STATE_ACTIVE:
520  break;
521 
522  case OP_STATE_INACTIVE:
524  break;
525  }
526  }
527  op->state = state;
528 }
enum State state
current state of profiling
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_array_append(arr, len, element)
Append an element to an array (growing the array by one).
unsigned int nres
How many units of resources does the operation need.
struct GNUNET_TESTBED_Operation * op
The operation this entry holds.
static void remove_queue_entry(struct GNUNET_TESTBED_Operation *op, unsigned int index)
Removes a queue entry of an operation from one of the operation queues' lists depending on the state ...

References OperationQueue::aq_head, OperationQueue::aq_tail, GNUNET_array_append, GNUNET_assert, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_new, OperationQueue::nq_head, OperationQueue::nq_tail, QueueEntry::nres, op, QueueEntry::op, OP_STATE_ACTIVE, OP_STATE_INACTIVE, OP_STATE_INIT, OP_STATE_READY, OP_STATE_WAITING, remove_queue_entry(), OperationQueue::rq_head, OperationQueue::rq_tail, state, OperationQueue::wq_head, and OperationQueue::wq_tail.

Referenced by check_readiness(), defer(), GNUNET_TESTBED_operation_activate_(), GNUNET_TESTBED_operation_begin_wait_(), GNUNET_TESTBED_operation_inactivate_(), and process_rq_task().

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

◆ rq_remove()

static void rq_remove ( struct GNUNET_TESTBED_Operation op)
static

Removes an operation from the ready queue.

Also stops the 'process_rq_task' if the given operation is the last one in the queue.

Parameters
opthe operation to be removed

Definition at line 538 of file testbed_api_operations.c.

539 {
540  GNUNET_assert (NULL != op->rq_entry);
542  GNUNET_free (op->rq_entry);
543  op->rq_entry = NULL;
544  if ((NULL == rq_head) && (NULL != process_rq_task_id))
545  {
547  process_rq_task_id = NULL;
548  }
549 }
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
struct GNUNET_SCHEDULER_Task * process_rq_task_id
The id of the task to process the ready queue.
static struct ReadyQueueEntry * rq_tail
DLL tail for the ready queue.
static struct ReadyQueueEntry * rq_head
DLL head for the ready queue.

References GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_SCHEDULER_cancel(), op, process_rq_task_id, rq_head, and rq_tail.

Referenced by defer(), GNUNET_TESTBED_operation_release_(), and process_rq_task().

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

◆ process_rq_task()

static void process_rq_task ( void *  cls)
static

Processes the ready queue by calling the operation start callback of the operation at the head.

The operation is then removed from the queue. The task is scheduled to run again immediately until no more operations are in the ready queue.

Parameters
clsNULL

Definition at line 561 of file testbed_api_operations.c.

562 {
564  struct OperationQueue *queue;
565  unsigned int cnt;
566 
567  process_rq_task_id = NULL;
568  GNUNET_assert (NULL != rq_head);
569  GNUNET_assert (NULL != (op = rq_head->op));
570  rq_remove (op);
571  if (NULL != rq_head)
574  for (cnt = 0; cnt < op->nqueues; cnt++)
575  {
576  queue = op->queues[cnt];
579  }
580  op->tstart = GNUNET_TIME_absolute_get ();
581  if (NULL != op->start)
582  op->start (op->cb_cls);
583 }
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1299
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
Opaque handle to an abstract operation to be executed by the testing framework.
struct GNUNET_TESTBED_Operation * op
The operation associated with this entry.
static void assign_timeslot(struct GNUNET_TESTBED_Operation *op, struct OperationQueue *queue)
Assigns the given operation a time slot from the given operation queue.
static void rq_remove(struct GNUNET_TESTBED_Operation *op)
Removes an operation from the ready queue.
static void change_state(struct GNUNET_TESTBED_Operation *op, enum OperationState state)
Changes the state of the operation while moving its associated queue entries in the operation's opera...
static void process_rq_task(void *cls)
Processes the ready queue by calling the operation start callback of the operation at the head.

References assign_timeslot(), change_state(), GNUNET_assert, GNUNET_SCHEDULER_add_now(), GNUNET_TIME_absolute_get(), op, ReadyQueueEntry::op, OP_STATE_ACTIVE, OPERATION_QUEUE_TYPE_ADAPTIVE, process_rq_task_id, queue(), rq_head, and rq_remove().

Referenced by rq_add().

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

◆ rq_add()

static void rq_add ( struct GNUNET_TESTBED_Operation op)
static

Adds the operation to the ready queue and starts the 'process_rq_task'.

Parameters
opthe operation to be queued

Definition at line 592 of file testbed_api_operations.c.

593 {
594  struct ReadyQueueEntry *rq_entry;
595 
596  GNUNET_assert (NULL == op->rq_entry);
597  rq_entry = GNUNET_new (struct ReadyQueueEntry);
598  rq_entry->op = op;
600  op->rq_entry = rq_entry;
601  if (NULL == process_rq_task_id)
603 }
An entry in the ready queue (implemented as DLL)

References GNUNET_assert, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_new, GNUNET_SCHEDULER_add_now(), op, ReadyQueueEntry::op, process_rq_task(), process_rq_task_id, rq_head, and rq_tail.

Referenced by check_readiness().

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

◆ is_queue_empty()

static int is_queue_empty ( struct OperationQueue opq)
static

Checks if the given operation queue is empty or not.

Parameters
opqthe operation queue
Returns
GNUNET_YES if the given operation queue has no operations; GNUNET_NO otherwise

Definition at line 614 of file testbed_api_operations.c.

615 {
616  if ((NULL != opq->wq_head)
617  || (NULL != opq->rq_head)
618  || (NULL != opq->aq_head)
619  || (NULL != opq->nq_head))
620  return GNUNET_NO;
621  return GNUNET_YES;
622 }
@ GNUNET_YES
@ GNUNET_NO

References OperationQueue::aq_head, GNUNET_NO, GNUNET_YES, OperationQueue::nq_head, OperationQueue::rq_head, and OperationQueue::wq_head.

Referenced by __attribute__(), GNUNET_TESTBED_operation_queue_destroy_(), and GNUNET_TESTBED_operation_queue_destroy_empty_().

Here is the caller graph for this function:

◆ decide_capacity()

static int decide_capacity ( struct OperationQueue opq,
struct QueueEntry entry,
struct GNUNET_TESTBED_Operation ***  ops_,
unsigned int *  n_ops_ 
)
static

Checks if the given operation queue has enough resources to provide for the operation of the given queue entry.

It also checks if any inactive operations are to be released in order to accommodate the needed resources and returns them as an array.

Parameters
opqthe operation queue to check for resource accommodation
entrythe operation queue entry whose operation's resources are to be accommodated
ops_pointer to return the array of operations which are to be released in order to accommodate the new operation. Can be NULL
n_ops_the number of operations in ops_
Returns
GNUNET_YES if the given entry's operation can be accommodated in this queue. GNUNET_NO if it cannot be accommodated; ops_ and n_ops_ will be set to NULL and 0 respectively.

Definition at line 642 of file testbed_api_operations.c.

646 {
647  struct QueueEntry **evict_entries;
648  struct GNUNET_TESTBED_Operation **ops;
650  unsigned int n_ops;
651  unsigned int n_evict_entries;
652  unsigned int need;
653  unsigned int max;
654  int deficit;
655  int rval;
656 
657  GNUNET_assert (NULL != (op = entry->op));
658  GNUNET_assert (0 < (need = entry->nres));
659  ops = NULL;
660  n_ops = 0;
661  evict_entries = NULL;
662  n_evict_entries = 0;
663  rval = GNUNET_YES;
665  {
666  GNUNET_assert (NULL != opq->fctx);
667  GNUNET_assert (opq->max_active >= opq->overload);
668  max = opq->max_active - opq->overload;
669  }
670  else
671  max = opq->max_active;
672  if (opq->active > max)
673  {
674  rval = GNUNET_NO;
675  goto ret;
676  }
677  if ((opq->active + need) <= max)
678  goto ret;
679  deficit = need - (max - opq->active);
680  for (entry = opq->nq_head;
681  (0 < deficit) && (NULL != entry);
682  entry = entry->next)
683  {
684  GNUNET_array_append (evict_entries, n_evict_entries, entry);
685  deficit -= entry->nres;
686  }
687  if (0 < deficit)
688  {
689  rval = GNUNET_NO;
690  goto ret;
691  }
692  for (n_ops = 0; n_ops < n_evict_entries;)
693  {
694  op = evict_entries[n_ops]->op;
695  GNUNET_array_append (ops, n_ops, op); /* increments n-ops */
696  }
697 
698 ret:
699  GNUNET_free (evict_entries);
700  if (NULL != ops_)
701  *ops_ = ops;
702  else
703  GNUNET_free (ops);
704  if (NULL != n_ops_)
705  *n_ops_ = n_ops;
706  return rval;
707 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define max(x, y)
unsigned int overload
The number of resources occupied by failed operations in the current shot.
unsigned int active
Number of operations that are currently active in this queue.
unsigned int max_active
Max number of operations which can be active at any time in this queue.
enum OperationQueueType type
The type of this operation queue.
struct FeedbackCtx * fctx
Feedback context; only relevant for adaptive operation queues.
struct QueueEntry * next
The next DLL pointer.

References OperationQueue::active, OperationQueue::fctx, GNUNET_array_append, GNUNET_assert, GNUNET_free, GNUNET_NO, GNUNET_YES, max, OperationQueue::max_active, QueueEntry::next, OperationQueue::nq_head, QueueEntry::nres, op, QueueEntry::op, OPERATION_QUEUE_TYPE_ADAPTIVE, OperationQueue::overload, ret, and OperationQueue::type.

Referenced by check_readiness().

Here is the caller graph for this function:

◆ merge_ops()

static void merge_ops ( struct GNUNET_TESTBED_Operation ***  old,
unsigned int *  n_old,
struct GNUNET_TESTBED_Operation **  new,
unsigned int  n_new 
)
static

Merges an array of operations into another, eliminating duplicates.

No ordering is guaranteed.

Parameters
oldthe array into which the merging is done.
n_oldthe number of operations in old array
newthe array from which operations are to be merged
n_newthe number of operations in new array

Definition at line 720 of file testbed_api_operations.c.

724 {
725  struct GNUNET_TESTBED_Operation **cur;
726  unsigned int i;
727  unsigned int j;
728  unsigned int n_cur;
729 
730  GNUNET_assert (NULL != old);
731  n_cur = *n_old;
732  cur = *old;
733  for (i = 0; i < n_new; i++)
734  {
735  for (j = 0; j < *n_old; j++)
736  {
737  if (new[i] == cur[j])
738  break;
739  }
740  if (j < *n_old)
741  continue;
742  GNUNET_array_append (cur, n_cur, new[j]);
743  }
744  *old = cur;
745  *n_old = n_cur;
746 }

References GNUNET_array_append, and GNUNET_assert.

Referenced by check_readiness().

Here is the caller graph for this function:

◆ check_readiness()

static int check_readiness ( struct GNUNET_TESTBED_Operation op)
static

Checks for the readiness of an operation and schedules a operation start task.

Parameters
opthe operation

Definition at line 755 of file testbed_api_operations.c.

756 {
757  struct GNUNET_TESTBED_Operation **evict_ops;
758  struct GNUNET_TESTBED_Operation **ops;
759  unsigned int n_ops;
760  unsigned int n_evict_ops;
761  unsigned int i;
762 
763  GNUNET_assert (NULL == op->rq_entry);
764  GNUNET_assert (OP_STATE_WAITING == op->state);
765  evict_ops = NULL;
766  n_evict_ops = 0;
767  for (i = 0; i < op->nqueues; i++)
768  {
769  ops = NULL;
770  n_ops = 0;
771  if (GNUNET_NO == decide_capacity (op->queues[i], op->qentries[i],
772  &ops, &n_ops))
773  {
774  GNUNET_free (evict_ops);
775  return GNUNET_NO;
776  }
777  if (NULL == ops)
778  continue;
779  merge_ops (&evict_ops, &n_evict_ops, ops, n_ops);
780  GNUNET_free (ops);
781  }
782  if (NULL != evict_ops)
783  {
784  for (i = 0; i < n_evict_ops; i++)
785  GNUNET_TESTBED_operation_release_ (evict_ops[i]);
786  GNUNET_free (evict_ops);
787  evict_ops = NULL;
788  /* Evicting the operations should schedule this operation */
789  GNUNET_assert (OP_STATE_READY == op->state);
790  return GNUNET_YES;
791  }
792  for (i = 0; i < op->nqueues; i++)
793  op->queues[i]->active += op->nres[i];
795  rq_add (op);
796  return GNUNET_YES;
797 }
void GNUNET_TESTBED_operation_release_(struct GNUNET_TESTBED_Operation *op)
An operation is 'done' (was cancelled or finished); remove it from the queues and release associated ...
static int decide_capacity(struct OperationQueue *opq, struct QueueEntry *entry, struct GNUNET_TESTBED_Operation ***ops_, unsigned int *n_ops_)
Checks if the given operation queue has enough resources to provide for the operation of the given qu...
static void rq_add(struct GNUNET_TESTBED_Operation *op)
Adds the operation to the ready queue and starts the 'process_rq_task'.
static void merge_ops(struct GNUNET_TESTBED_Operation ***old, unsigned int *n_old, struct GNUNET_TESTBED_Operation **new, unsigned int n_new)
Merges an array of operations into another, eliminating duplicates.

References change_state(), decide_capacity(), GNUNET_assert, GNUNET_free, GNUNET_NO, GNUNET_TESTBED_operation_release_(), GNUNET_YES, merge_ops(), op, OP_STATE_READY, OP_STATE_WAITING, and rq_add().

Referenced by GNUNET_TESTBED_operation_begin_wait_(), and recheck_waiting().

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

◆ defer()

static void defer ( struct GNUNET_TESTBED_Operation op)
static

Defers a ready to be executed operation back to waiting.

Parameters
opthe operation to defer

Definition at line 806 of file testbed_api_operations.c.

807 {
808  unsigned int i;
809 
810  GNUNET_assert (OP_STATE_READY == op->state);
811  rq_remove (op);
812  for (i = 0; i < op->nqueues; i++)
813  {
814  GNUNET_assert (op->queues[i]->active >= op->nres[i]);
815  op->queues[i]->active -= op->nres[i];
816  }
818 }

References change_state(), GNUNET_assert, op, OP_STATE_READY, OP_STATE_WAITING, and rq_remove().

Referenced by GNUNET_TESTBED_operation_queue_reset_max_active_().

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

◆ cleanup_tslots()

static void cleanup_tslots ( struct OperationQueue queue)
static

Cleanups the array of timeslots of an operation queue.

For each time slot in the array, if it is allocated to an operation, it will be deallocated from the operation

Parameters
queuethe operation queue

Definition at line 829 of file testbed_api_operations.c.

830 {
831  struct FeedbackCtx *fctx = queue->fctx;
832  struct TimeSlot *tslot;
834  unsigned int cnt;
835 
836  GNUNET_assert (NULL != fctx);
837  for (cnt = 0; cnt < queue->max_active; cnt++)
838  {
839  tslot = &fctx->tslots_freeptr[cnt];
840  op = tslot->op;
841  if (NULL == op)
842  continue;
843  GNUNET_CONTAINER_DLL_remove (op->tslots_head, op->tslots_tail, tslot);
844  }
845  GNUNET_free (fctx->tslots_freeptr);
846  fctx->tslots_freeptr = NULL;
847  fctx->alloc_head = NULL;
848  fctx->alloc_tail = NULL;
849  fctx->tslots_filled = 0;
850 }
struct TimeSlot * tslots_freeptr
Pointer to the chunk of time slots.
unsigned int tslots_filled
Number of time slots filled so far.

References FeedbackCtx::alloc_head, FeedbackCtx::alloc_tail, GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_free, op, TimeSlot::op, queue(), FeedbackCtx::tslots_filled, and FeedbackCtx::tslots_freeptr.

Referenced by adaptive_queue_set_max_active(), and queue_destroy().

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

◆ adaptive_queue_set_max_active()

static void adaptive_queue_set_max_active ( struct OperationQueue queue,
unsigned int  n 
)
static

Cleansup the existing timing slots and sets new timing slots in the given queue to accommodate given number of max active operations.

Parameters
queuethe queue
nthe number of maximum active operations. If n is greater than the maximum limit set while creating the queue, then the minimum of these two will be selected as n

Definition at line 863 of file testbed_api_operations.c.

864 {
865  struct FeedbackCtx *fctx = queue->fctx;
866  struct TimeSlot *tslot;
867  unsigned int cnt;
868 
870  n = GNUNET_MIN (n, fctx->max_active_bound);
871  fctx->tslots_freeptr = GNUNET_malloc (n * sizeof(struct TimeSlot));
872  fctx->nfailed = 0;
873  for (cnt = 0; cnt < n; cnt++)
874  {
875  tslot = &fctx->tslots_freeptr[cnt];
876  tslot->queue = queue;
878  tslot);
879  }
881 }
#define GNUNET_MIN(a, b)
#define GNUNET_malloc(size)
Wrapper around malloc.
unsigned int max_active_bound
Bound on the maximum number of operations which can be active.
unsigned int nfailed
Number of operations that have failed.
struct OperationQueue * queue
This operation queue to which this time slot belongs to.
void GNUNET_TESTBED_operation_queue_reset_max_active_(struct OperationQueue *queue, unsigned int max_active)
Function to reset the maximum number of operations in the given queue.
static void cleanup_tslots(struct OperationQueue *queue)
Cleanups the array of timeslots of an operation queue.

References FeedbackCtx::alloc_head, FeedbackCtx::alloc_tail, cleanup_tslots(), GNUNET_CONTAINER_DLL_insert_tail, GNUNET_malloc, GNUNET_MIN, GNUNET_TESTBED_operation_queue_reset_max_active_(), FeedbackCtx::max_active_bound, FeedbackCtx::nfailed, queue(), TimeSlot::queue, and FeedbackCtx::tslots_freeptr.

Referenced by adapt_parallelism(), and GNUNET_TESTBED_operation_queue_create_().

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

◆ adapt_parallelism()

static void adapt_parallelism ( struct OperationQueue queue)
static

Adapts parallelism in an adaptive queue by using the statistical data from the feedback context.

Parameters
queuethe queue

Definition at line 891 of file testbed_api_operations.c.

892 {
893  struct GNUNET_TIME_Relative avg;
894  struct FeedbackCtx *fctx;
895  struct TimeSlot *tslot;
896  int sd;
897  unsigned int nvals;
898  unsigned int cnt;
899  unsigned int parallelism;
900 
901  avg = GNUNET_TIME_UNIT_ZERO;
902  nvals = 0;
903  fctx = queue->fctx;
904  for (cnt = 0; cnt < queue->max_active; cnt++)
905  {
906  tslot = &fctx->tslots_freeptr[cnt];
907  avg = GNUNET_TIME_relative_add (avg, tslot->tsum);
908  nvals += tslot->nvals;
909  }
910  GNUNET_assert (nvals >= queue->max_active);
911  GNUNET_assert (fctx->nfailed <= nvals);
912  nvals -= fctx->nfailed;
913  if (0 == nvals)
914  {
915  if (1 == queue->max_active)
917  else
918  adaptive_queue_set_max_active (queue, queue->max_active / 2);
919  return;
920  }
921  avg = GNUNET_TIME_relative_divide (avg, nvals);
922  GNUNET_TESTBED_SD_add_data_ (fctx->sd, (unsigned int) avg.rel_value_us);
923  if (GNUNET_SYSERR ==
925  (unsigned int) avg.rel_value_us,
926  &sd))
927  {
928  adaptive_queue_set_max_active (queue, queue->max_active); /* no change */
929  return;
930  }
931 
932  parallelism = 0;
933  if (-1 == sd)
934  parallelism = queue->max_active + 1;
935  if (sd <= -2)
936  parallelism = queue->max_active * 2;
937  if (1 == sd)
938  parallelism = queue->max_active - 1;
939  if (2 <= sd)
940  parallelism = queue->max_active / 2;
943 
944 #if 0
945  /* old algorithm */
946  if (sd < 0)
947  sd = 0;
948  GNUNET_assert (0 <= sd);
949  // GNUNET_TESTBED_SD_add_data_ (fctx->sd, (unsigned int) avg.rel_value_us);
950  if (0 == sd)
951  {
952  adaptive_queue_set_max_active (queue, queue->max_active * 2);
953  return;
954  }
955  if (1 == sd)
956  {
957  adaptive_queue_set_max_active (queue, queue->max_active + 1);
958  return;
959  }
960  if (1 == queue->max_active)
961  {
963  return;
964  }
965  if (2 == sd)
966  {
967  adaptive_queue_set_max_active (queue, queue->max_active - 1);
968  return;
969  }
970  adaptive_queue_set_max_active (queue, queue->max_active / 2);
971 #endif
972 }
static unsigned int parallelism
#define GNUNET_MAX(a, b)
@ GNUNET_SYSERR
struct GNUNET_TIME_Relative GNUNET_TIME_relative_add(struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_Relative a2)
Add relative times together.
Definition: time.c:585
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_divide(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Divide relative time by a given factor.
Definition: time.c:550
struct SDHandle * sd
Handle for calculating standard deviation.
Time for relative time used by GNUnet, in microseconds.
struct GNUNET_TIME_Relative tsum
Accumulated time.
unsigned int nvals
Number of timing values accumulated.
static void adaptive_queue_set_max_active(struct OperationQueue *queue, unsigned int n)
Cleansup the existing timing slots and sets new timing slots in the given queue to accommodate given ...
#define ADAPTIVE_QUEUE_DEFAULT_MAX_ACTIVE
The number of parallel operations we start with by default for adaptive queues.
int GNUNET_TESTBED_SD_deviation_factor_(struct SDHandle *h, unsigned int amount, int *factor)
Calculates the factor by which the given amount differs.
void GNUNET_TESTBED_SD_add_data_(struct SDHandle *h, unsigned int amount)
Add a reading to SD.

References ADAPTIVE_QUEUE_DEFAULT_MAX_ACTIVE, adaptive_queue_set_max_active(), GNUNET_assert, GNUNET_MAX, GNUNET_SYSERR, GNUNET_TESTBED_SD_add_data_(), GNUNET_TESTBED_SD_deviation_factor_(), GNUNET_TIME_relative_add(), GNUNET_TIME_relative_divide(), GNUNET_TIME_UNIT_ZERO, FeedbackCtx::nfailed, TimeSlot::nvals, parallelism, queue(), GNUNET_TIME_Relative::rel_value_us, FeedbackCtx::sd, FeedbackCtx::tslots_freeptr, and TimeSlot::tsum.

Referenced by update_tslots().

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

◆ update_tslots()

static void update_tslots ( struct GNUNET_TESTBED_Operation op)
static

update tslots with the operation's completion time.

Additionally, if updating a timeslot makes all timeslots filled in an adaptive operation queue, call adapt_parallelism() for that queue.

Parameters
opthe operation

Definition at line 983 of file testbed_api_operations.c.

984 {
985  struct OperationQueue *queue;
986  struct GNUNET_TIME_Relative t;
987  struct TimeSlot *tslot;
988  struct FeedbackCtx *fctx;
989  unsigned int i;
990 
992  while (NULL != (tslot = op->tslots_head)) /* update time slots */
993  {
994  queue = tslot->queue;
995  fctx = queue->fctx;
996  GNUNET_CONTAINER_DLL_remove (op->tslots_head, op->tslots_tail, tslot);
997  tslot->op = NULL;
999  tslot);
1000  if (op->failed)
1001  {
1002  fctx->nfailed++;
1003  for (i = 0; i < op->nqueues; i++)
1004  if (queue == op->queues[i])
1005  break;
1006  GNUNET_assert (i != op->nqueues);
1007  op->queues[i]->overload += op->nres[i];
1008  }
1009  tslot->tsum = GNUNET_TIME_relative_add (tslot->tsum, t);
1010  if (0 != tslot->nvals++)
1011  continue;
1012  fctx->tslots_filled++;
1013  if (queue->max_active == fctx->tslots_filled)
1015  }
1016 }
static struct GNUNET_SCHEDULER_Task * t
Main task.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:436
static void adapt_parallelism(struct OperationQueue *queue)
Adapts parallelism in an adaptive queue by using the statistical data from the feedback context.

References adapt_parallelism(), FeedbackCtx::alloc_head, FeedbackCtx::alloc_tail, GNUNET_assert, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_CONTAINER_DLL_remove, GNUNET_TIME_absolute_get_duration(), GNUNET_TIME_relative_add(), FeedbackCtx::nfailed, TimeSlot::nvals, op, TimeSlot::op, queue(), TimeSlot::queue, t, FeedbackCtx::tslots_filled, and TimeSlot::tsum.

Referenced by GNUNET_TESTBED_operation_release_().

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

◆ GNUNET_TESTBED_operation_create_()

struct GNUNET_TESTBED_Operation* GNUNET_TESTBED_operation_create_ ( void *  cls,
OperationStart  start,
OperationRelease  release 
)

Create an 'operation' to be performed.

Parameters
clsclosure for the callbacks
startfunction to call to start the operation
releasefunction to call to close down the operation
Returns
handle to the operation

Definition at line 1028 of file testbed_api_operations.c.

1030 {
1031  struct GNUNET_TESTBED_Operation *op;
1032 
1034  op->start = start;
1035  op->state = OP_STATE_INIT;
1036  op->release = release;
1037  op->cb_cls = cls;
1038  return op;
1039 }
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
OperationRelease release
Function to call to clean up after the operation (which may or may not have been started yet).

References GNUNET_new, op, OP_STATE_INIT, GNUNET_TESTBED_Operation::release, and start.

Referenced by GNUNET_TESTBED_controller_link(), GNUNET_TESTBED_get_slave_config_(), GNUNET_TESTBED_get_statistics(), GNUNET_TESTBED_overlay_configure_topology_va(), GNUNET_TESTBED_overlay_connect(), GNUNET_TESTBED_peer_create(), GNUNET_TESTBED_peer_destroy(), GNUNET_TESTBED_peer_get_information(), GNUNET_TESTBED_peer_manage_service(), GNUNET_TESTBED_peer_start(), GNUNET_TESTBED_peer_stop(), GNUNET_TESTBED_peer_update_configuration(), GNUNET_TESTBED_service_connect(), GNUNET_TESTBED_shutdown_peers(), GST_connection_pool_get_handle(), and GST_neighbour_get_connection().

Here is the caller graph for this function:

◆ GNUNET_TESTBED_operation_queue_create_()

struct OperationQueue* GNUNET_TESTBED_operation_queue_create_ ( enum OperationQueueType  type,
unsigned int  max_active 
)

Create an operation queue.

Parameters
typethe type of operation queue
max_activemaximum number of operations in this queue that can be active in parallel at the same time.
Returns
handle to the queue

Definition at line 1043 of file testbed_api_operations.c.

1045 {
1046  struct OperationQueue *queue;
1047  struct FeedbackCtx *fctx;
1048 
1049  queue = GNUNET_new (struct OperationQueue);
1050  queue->type = type;
1052  {
1053  queue->max_active = max_active;
1054  }
1055  else
1056  {
1057  fctx = GNUNET_new (struct FeedbackCtx);
1058  fctx->max_active_bound = max_active;
1060  queue->fctx = fctx;
1062  }
1063  return queue;
1064 }
#define ADAPTIVE_QUEUE_DEFAULT_HISTORY
The number of readings containing past operation's timing information that we keep track of for adapt...
@ OPERATION_QUEUE_TYPE_FIXED
Operation queue which permits a fixed maximum number of operations to be active at any time.
struct SDHandle * GNUNET_TESTBED_SD_init_(unsigned int max_cnt)
Initialize standard deviation calculation handle.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model

References ADAPTIVE_QUEUE_DEFAULT_HISTORY, ADAPTIVE_QUEUE_DEFAULT_MAX_ACTIVE, adaptive_queue_set_max_active(), GNUNET_new, GNUNET_TESTBED_SD_init_(), FeedbackCtx::max_active_bound, OPERATION_QUEUE_TYPE_FIXED, queue(), FeedbackCtx::sd, and type.

Referenced by GNUNET_TESTBED_controller_connect(), GNUNET_TESTBED_get_statistics(), GNUNET_TESTBED_host_create_with_id(), and testbed_run().

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

◆ queue_destroy()

static void queue_destroy ( struct OperationQueue queue)
static

Cleanup the given operation queue.

Parameters
queuethe operation queue to destroy

Definition at line 1073 of file testbed_api_operations.c.

1074 {
1075  struct FeedbackCtx *fctx;
1076 
1077  if (OPERATION_QUEUE_TYPE_ADAPTIVE == queue->type)
1078  {
1080  fctx = queue->fctx;
1082  GNUNET_free (fctx);
1083  }
1084  GNUNET_free (queue);
1085 }
void GNUNET_TESTBED_SD_destroy_(struct SDHandle *h)
Frees the memory allocated to the SD handle.

References cleanup_tslots(), GNUNET_free, GNUNET_TESTBED_SD_destroy_(), OPERATION_QUEUE_TYPE_ADAPTIVE, queue(), and FeedbackCtx::sd.

Referenced by __attribute__(), and GNUNET_TESTBED_operation_queue_destroy_().

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

◆ GNUNET_TESTBED_operation_queue_destroy_()

void GNUNET_TESTBED_operation_queue_destroy_ ( struct OperationQueue queue)

Destroys an operation queue.

Destroy an operation queue.

If the queue is still in use by operations it is marked as expired and its resources are released in the destructor GNUNET_TESTBED_operations_fini().

Parameters
queuequeue to destroy

Definition at line 1096 of file testbed_api_operations.c.

1097 {
1098  if (GNUNET_YES != is_queue_empty (queue))
1099  {
1100  GNUNET_assert (0 == queue->expired); /* Are you calling twice on same queue? */
1101  queue->expired = 1;
1103  return;
1104  }
1105  queue_destroy (queue);
1106 }
static void queue_destroy(struct OperationQueue *queue)
Cleanup the given operation queue.
static unsigned int n_expired_opqs
Number of expired operation queues in the above array.
static struct OperationQueue ** expired_opqs
Array of operation queues which are to be destroyed.
static int is_queue_empty(struct OperationQueue *opq)
Checks if the given operation queue is empty or not.

References expired_opqs, GNUNET_array_append, GNUNET_assert, GNUNET_YES, is_queue_empty(), n_expired_opqs, queue(), and queue_destroy().

Referenced by GNUNET_TESTBED_controller_disconnect(), GNUNET_TESTBED_host_destroy(), GNUNET_TESTBED_operation_queue_destroy_empty_(), and shutdown_task().

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

◆ GNUNET_TESTBED_operation_queue_destroy_empty_()

int GNUNET_TESTBED_operation_queue_destroy_empty_ ( struct OperationQueue queue)

Destroys the operation queue if it is empty.

If not empty return GNUNET_NO.

Parameters
queuethe queue to destroy if empty
Returns
GNUNET_YES if the queue is destroyed. GNUNET_NO if not (because it is not empty)

Definition at line 1117 of file testbed_api_operations.c.

1118 {
1119  if (GNUNET_NO == is_queue_empty (queue))
1120  return GNUNET_NO;
1122  return GNUNET_YES;
1123 }
void GNUNET_TESTBED_operation_queue_destroy_(struct OperationQueue *queue)
Destroys an operation queue.

References GNUNET_NO, GNUNET_TESTBED_operation_queue_destroy_(), GNUNET_YES, is_queue_empty(), and queue().

Referenced by oprelease_get_stats().

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

◆ recheck_waiting()

static void recheck_waiting ( struct OperationQueue opq)
static

Rechecks if any of the operations in the given operation queue's waiting list can be made active.

Parameters
opqthe operation queue

Definition at line 1133 of file testbed_api_operations.c.

1134 {
1135  struct QueueEntry *entry;
1136  struct QueueEntry *entry2;
1137 
1138  entry = opq->wq_head;
1139  while (NULL != entry)
1140  {
1141  entry2 = entry->next;
1142  if (GNUNET_NO == check_readiness (entry->op))
1143  break;
1144  entry = entry2;
1145  }
1146 }
static int check_readiness(struct GNUNET_TESTBED_Operation *op)
Checks for the readiness of an operation and schedules a operation start task.

References check_readiness(), GNUNET_NO, QueueEntry::next, QueueEntry::op, and OperationQueue::wq_head.

Referenced by GNUNET_TESTBED_operation_inactivate_(), GNUNET_TESTBED_operation_queue_reset_max_active_(), and GNUNET_TESTBED_operation_release_().

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

◆ GNUNET_TESTBED_operation_queue_reset_max_active_()

void GNUNET_TESTBED_operation_queue_reset_max_active_ ( struct OperationQueue queue,
unsigned int  max_active 
)

Function to reset the maximum number of operations in the given queue.

If max_active is lesser than the number of currently active operations, the active operations are not stopped immediately.

Parameters
queuethe operation queue which has to be modified
max_activethe new maximum number of active operations

Definition at line 1158 of file testbed_api_operations.c.

1160 {
1161  struct QueueEntry *entry;
1162 
1163  queue->max_active = max_active;
1164  queue->overload = 0;
1165  while ((queue->active > queue->max_active)
1166  && (NULL != (entry = queue->rq_head)))
1167  defer (entry->op);
1169 }
static void recheck_waiting(struct OperationQueue *opq)
Rechecks if any of the operations in the given operation queue's waiting list can be made active.
static void defer(struct GNUNET_TESTBED_Operation *op)
Defers a ready to be executed operation back to waiting.

References defer(), QueueEntry::op, queue(), and recheck_waiting().

Referenced by adaptive_queue_set_max_active().

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

◆ GNUNET_TESTBED_operation_queue_insert2_()

void GNUNET_TESTBED_operation_queue_insert2_ ( struct OperationQueue queue,
struct GNUNET_TESTBED_Operation op,
unsigned int  nres 
)

Add an operation to a queue.

An operation can be in multiple queues at once. Once the operation is inserted into all the queues GNUNET_TESTBED_operation_begin_wait_() has to be called to actually start waiting for the operation to become active.

Parameters
queuequeue to add the operation to
opoperation to add to the queue
nresthe number of units of the resources of queue needed by the operation. Should be greater than 0.

Definition at line 1184 of file testbed_api_operations.c.

1187 {
1188  unsigned int qsize;
1189 
1190  GNUNET_assert (0 < nres);
1191  qsize = op->nqueues;
1192  GNUNET_array_append (op->queues, op->nqueues, queue);
1193  GNUNET_array_append (op->nres, qsize, nres);
1194  GNUNET_assert (qsize == op->nqueues);
1195 }

References GNUNET_array_append, GNUNET_assert, QueueEntry::nres, op, and queue().

Referenced by GNUNET_TESTBED_operation_queue_insert_().

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

◆ GNUNET_TESTBED_operation_queue_insert_()

void GNUNET_TESTBED_operation_queue_insert_ ( struct OperationQueue queue,
struct GNUNET_TESTBED_Operation op 
)

Add an operation to a queue.

An operation can be in multiple queues at once. Once the operation is inserted into all the queues GNUNET_TESTBED_operation_begin_wait_() has to be called to actually start waiting for the operation to become active. The operation is assumed to take 1 queue resource. Use GNUNET_TESTBED_operation_queue_insert2_() if it requires more than 1

Parameters
queuequeue to add the operation to
opoperation to add to the queue

Definition at line 1210 of file testbed_api_operations.c.

1212 {
1214 }
void GNUNET_TESTBED_operation_queue_insert2_(struct OperationQueue *queue, struct GNUNET_TESTBED_Operation *op, unsigned int nres)
Add an operation to a queue.

References GNUNET_TESTBED_operation_queue_insert2_(), op, and queue().

Referenced by GNUNET_TESTBED_controller_link(), GNUNET_TESTBED_get_slave_config_(), GNUNET_TESTBED_get_statistics(), GNUNET_TESTBED_host_queue_oc_(), GNUNET_TESTBED_overlay_configure_topology_va(), GNUNET_TESTBED_peer_create(), GNUNET_TESTBED_peer_destroy(), GNUNET_TESTBED_peer_get_information(), GNUNET_TESTBED_peer_manage_service(), GNUNET_TESTBED_peer_start(), GNUNET_TESTBED_peer_stop(), GNUNET_TESTBED_peer_update_configuration(), GNUNET_TESTBED_service_connect(), GNUNET_TESTBED_shutdown_peers(), GST_connection_pool_get_handle(), and GST_neighbour_get_connection().

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

◆ GNUNET_TESTBED_operation_begin_wait_()

void GNUNET_TESTBED_operation_begin_wait_ ( struct GNUNET_TESTBED_Operation op)

Marks the given operation as waiting on the queues.

Once all queues permit the operation to become active, the operation will be activated. The actual activation will occur in a separate task (thus allowing multiple queue insertions to be made without having the first one instantly trigger the operation if the first queue has sufficient resources).

Parameters
opthe operation to marks as waiting

Definition at line 1227 of file testbed_api_operations.c.

1228 {
1229  GNUNET_assert (NULL == op->rq_entry);
1231  (void) check_readiness (op);
1232 }

References change_state(), check_readiness(), GNUNET_assert, op, and OP_STATE_WAITING.

Referenced by GNUNET_TESTBED_controller_link(), GNUNET_TESTBED_get_slave_config_(), GNUNET_TESTBED_get_statistics(), GNUNET_TESTBED_overlay_configure_topology_va(), GNUNET_TESTBED_overlay_connect(), GNUNET_TESTBED_peer_create(), GNUNET_TESTBED_peer_destroy(), GNUNET_TESTBED_peer_get_information(), GNUNET_TESTBED_peer_manage_service(), GNUNET_TESTBED_peer_start(), GNUNET_TESTBED_peer_stop(), GNUNET_TESTBED_peer_update_configuration(), GNUNET_TESTBED_service_connect(), GNUNET_TESTBED_shutdown_peers(), GST_connection_pool_get_handle(), and GST_neighbour_get_connection().

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

◆ GNUNET_TESTBED_operation_inactivate_()

void GNUNET_TESTBED_operation_inactivate_ ( struct GNUNET_TESTBED_Operation op)

Marks an active operation as inactive - the operation will be kept in a ready-to-be-released state and continues to hold resources until another operation contents for them.

Parameters
opthe operation to be marked as inactive. The operation start callback should have been called before for this operation to mark it as inactive.

Definition at line 1245 of file testbed_api_operations.c.

1246 {
1247  struct OperationQueue **queues;
1248  size_t ms;
1249  unsigned int nqueues;
1250  unsigned int i;
1251 
1252  GNUNET_assert (OP_STATE_ACTIVE == op->state);
1254  nqueues = op->nqueues;
1255  ms = sizeof(struct OperationQueue *) * nqueues;
1256  queues = GNUNET_malloc (ms);
1257  /* Cloning is needed as the operation be released by waiting operations and
1258  hence its nqueues memory ptr will be freed */
1259  GNUNET_memcpy (queues, op->queues, ms);
1260  for (i = 0; i < nqueues; i++)
1261  recheck_waiting (queues[i]);
1262  GNUNET_free (queues);
1263 }
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.

References change_state(), GNUNET_assert, GNUNET_free, GNUNET_malloc, GNUNET_memcpy, op, OP_STATE_ACTIVE, OP_STATE_INACTIVE, and recheck_waiting().

Referenced by GST_neighbour_get_connection_cancel(), and GST_neighbour_release_connection().

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

◆ GNUNET_TESTBED_operation_activate_()

void GNUNET_TESTBED_operation_activate_ ( struct GNUNET_TESTBED_Operation op)

Marks and inactive operation as active.

This function should be called to ensure that the oprelease callback will not be called until it is either marked as inactive or released.

Parameters
opthe operation to be marked as active

Definition at line 1274 of file testbed_api_operations.c.

1275 {
1276  GNUNET_assert (OP_STATE_INACTIVE == op->state);
1278 }

References change_state(), GNUNET_assert, op, OP_STATE_ACTIVE, and OP_STATE_INACTIVE.

Referenced by GNUNET_TESTBED_operation_release_(), and trigger_notifications().

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

◆ GNUNET_TESTBED_operation_release_()

void GNUNET_TESTBED_operation_release_ ( struct GNUNET_TESTBED_Operation op)

An operation is 'done' (was cancelled or finished); remove it from the queues and release associated resources.

Parameters
opoperation that finished

Definition at line 1288 of file testbed_api_operations.c.

1289 {
1290  struct QueueEntry *entry;
1291  struct OperationQueue *opq;
1292  unsigned int i;
1293 
1294  if (OP_STATE_INIT == op->state)
1295  {
1296  GNUNET_free (op);
1297  return;
1298  }
1299  if (OP_STATE_READY == op->state)
1300  rq_remove (op);
1301  if (OP_STATE_INACTIVE == op->state) /* Activate the operation if inactive */
1303  if (OP_STATE_ACTIVE == op->state)
1304  update_tslots (op);
1305  GNUNET_assert (NULL != op->queues);
1306  GNUNET_assert (NULL != op->qentries);
1307  for (i = 0; i < op->nqueues; i++)
1308  {
1309  entry = op->qentries[i];
1310  remove_queue_entry (op, i);
1311  opq = op->queues[i];
1312  switch (op->state)
1313  {
1314  case OP_STATE_INIT:
1315  case OP_STATE_INACTIVE:
1316  GNUNET_assert (0);
1317  break;
1318 
1319  case OP_STATE_WAITING:
1320  break;
1321 
1322  case OP_STATE_ACTIVE:
1323  case OP_STATE_READY:
1324  GNUNET_assert (0 != opq->active);
1325  GNUNET_assert (opq->active >= entry->nres);
1326  opq->active -= entry->nres;
1327  recheck_waiting (opq);
1328  break;
1329  }
1330  GNUNET_free (entry);
1331  }
1332  GNUNET_free (op->qentries);
1333  GNUNET_free (op->queues);
1334  GNUNET_free (op->nres);
1335  if (NULL != op->release)
1336  op->release (op->cb_cls);
1337  GNUNET_free (op);
1338 }
void GNUNET_TESTBED_operation_activate_(struct GNUNET_TESTBED_Operation *op)
Marks and inactive operation as active.
static void update_tslots(struct GNUNET_TESTBED_Operation *op)
update tslots with the operation's completion time.

References OperationQueue::active, GNUNET_assert, GNUNET_free, GNUNET_TESTBED_operation_activate_(), QueueEntry::nres, op, OP_STATE_ACTIVE, OP_STATE_INACTIVE, OP_STATE_INIT, OP_STATE_READY, OP_STATE_WAITING, recheck_waiting(), remove_queue_entry(), rq_remove(), and update_tslots().

Referenced by check_readiness(), GNUNET_TESTBED_operation_done(), and GST_neighbour_list_clean().

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

◆ GNUNET_TESTBED_operation_mark_failed()

void GNUNET_TESTBED_operation_mark_failed ( struct GNUNET_TESTBED_Operation op)

Marks an operation as failed.

Parameters
opthe operation to be marked as failed

Definition at line 1347 of file testbed_api_operations.c.

1348 {
1349  op->failed = GNUNET_YES;
1350 }

References GNUNET_YES, and op.

Referenced by handle_op_fail_event().

Here is the caller graph for this function:

◆ __attribute__()

void __attribute__ ( (destructor)  )

Cleanup expired operation queues.

While doing so, also check for any operations which are not completed and warn about them.

Definition at line 1357 of file testbed_api_operations.c.

1359 {
1360  struct OperationQueue *queue;
1361  unsigned int i;
1362  int warn = 0;
1363 
1364  for (i = 0; i < n_expired_opqs; i++)
1365  {
1366  queue = expired_opqs[i];
1367  if (GNUNET_NO == is_queue_empty (queue))
1368  warn = 1;
1369  queue_destroy (queue);
1370  }
1372  n_expired_opqs = 0;
1373  if (warn)
1375  "Be disciplined. Some operations were not marked as done.\n");
1376 }
#define GNUNET_log(kind,...)
@ GNUNET_ERROR_TYPE_WARNING

References expired_opqs, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_NO, is_queue_empty(), n_expired_opqs, queue(), and queue_destroy().

Here is the call graph for this function:

Variable Documentation

◆ rq_head

struct ReadyQueueEntry* rq_head
static

DLL head for the ready queue.

Definition at line 382 of file testbed_api_operations.c.

Referenced by process_rq_task(), rq_add(), and rq_remove().

◆ rq_tail

struct ReadyQueueEntry* rq_tail
static

DLL tail for the ready queue.

Definition at line 387 of file testbed_api_operations.c.

Referenced by rq_add(), and rq_remove().

◆ expired_opqs

struct OperationQueue** expired_opqs
static

Array of operation queues which are to be destroyed.

Definition at line 392 of file testbed_api_operations.c.

Referenced by __attribute__(), and GNUNET_TESTBED_operation_queue_destroy_().

◆ n_expired_opqs

unsigned int n_expired_opqs
static

Number of expired operation queues in the above array.

Definition at line 397 of file testbed_api_operations.c.

Referenced by __attribute__(), and GNUNET_TESTBED_operation_queue_destroy_().

◆ process_rq_task_id

struct GNUNET_SCHEDULER_Task* process_rq_task_id

The id of the task to process the ready queue.

Definition at line 402 of file testbed_api_operations.c.

Referenced by process_rq_task(), rq_add(), and rq_remove().