]> rtime.felk.cvut.cz Git - frescor/fna.git/blobdiff - src_frescan/frescan_queues.c
add group negotiations to frescan and change all the requests and messages to map...
[frescor/fna.git] / src_frescan / frescan_queues.c
index c3e2957443fdc3613e56bd15feb9b55e4484603e..fc29e59edba366cd0ef224b889c5284b25947343 100644 (file)
  *
  * @license
  *
- * See MaRTE OS license
+ * -----------------------------------------------------------------------
+ *  Copyright (C) 2006 - 2008 FRESCOR consortium partners:
+ *
+ *    Universidad de Cantabria,              SPAIN
+ *    University of York,                    UK
+ *    Scuola Superiore Sant'Anna,            ITALY
+ *    Kaiserslautern University,             GERMANY
+ *    Univ. Politécnica  Valencia,           SPAIN
+ *    Czech Technical University in Prague,  CZECH REPUBLIC
+ *    ENEA                                   SWEDEN
+ *    Thales Communication S.A.              FRANCE
+ *    Visual Tools S.A.                      SPAIN
+ *    Rapita Systems Ltd                     UK
+ *    Evidence                               ITALY
+ *
+ *    See http://www.frescor.org for a link to partners' websites
+ *
+ *           FRESCOR project (FP6/2005/IST/5-034026) is funded
+ *        in part by the European Union Sixth Framework Programme
+ *        The European Union is not liable of any use that may be
+ *        made of this code.
+ *
+ *  This file is part of FRESCAN
+ *
+ *  FRESCAN is free software; you can  redistribute it and/or  modify
+ *  it under the terms of  the GNU General Public License as published by
+ *  the Free Software Foundation;  either  version 2, or (at  your option)
+ *  any later version.
+ *
+ *  FRESCAN  is distributed  in  the hope  that  it  will  be useful,  but
+ *  WITHOUT  ANY  WARRANTY;     without  even the   implied   warranty  of
+ *  MERCHANTABILITY  or  FITNESS FOR  A  PARTICULAR PURPOSE. See  the  GNU
+ *  General Public License for more details.
+ *
+ *  You should have  received a  copy of  the  GNU  General Public License
+ *  distributed  with  FRESCAN;  see file COPYING.   If not,  write to the
+ *  Free Software  Foundation,  59 Temple Place  -  Suite 330,  Boston, MA
+ *  02111-1307, USA.
+ *
+ * As a special exception, including FRESCAN header files in a file,
+ * instantiating FRESCAN generics or templates, or linking other files
+ * with FRESCAN objects to produce an executable application, does not
+ * by itself cause the resulting executable application to be covered
+ * by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be
+ * covered by the GNU Public License.
+ * -----------------------------------------------------------------------
  *
  */
 
 #include <stdlib.h>
+#include <time.h>
 
 #include "frescan_queues.h"
 #include "frescan_packets.h"
 #include "frescan_debug.h"
 #include "frescan_id.h"
+#include "frescan_data.h"
 
 /**
  * frescan_pqueue_create() - creates a priority queue
  */
 
-static inline frescan_prio_queue_t *frescan_pqueue_create(uint32_t max_prio)
+static inline frescan_prio_queue_t *frescan_pqueue_create(uint32_t max_prio,
+                                                          frescan_network_t net)
 {
         int ret, prio;
         frescan_prio_queue_t *pq; // priority queue
 
         pq = (frescan_prio_queue_t *)malloc(sizeof(frescan_prio_queue_t));
         if (pq == NULL) {
-                ERROR("could not allocate memory for prio queue\n");
+                FRESCAN_ERROR("could not allocate memory for prio queue\n");
                 return NULL;
         }
 
         pq->max_prio = max_prio;
+        pq->net      = net;
 
         ret = sem_init (&pq->sem, 0, 0);
         if (ret != 0) {
-                ERROR("could not init the semaphore\n");
+                FRESCAN_ERROR("could not init the semaphore\n");
                 free(pq);
                 return NULL;
         }
@@ -80,10 +130,11 @@ int frescan_queues_init(frescan_queues_t *queues,
         uint32_t max_prio;
 
         // create transmission fixed priority queue
-        queues->tx_fp_queue = frescan_pqueue_create(params->tx_fp_max_prio);
+        queues->tx_fp_queue = frescan_pqueue_create(params->tx_fp_max_prio,
+                                                    params->net);
 
         if (queues->tx_fp_queue == NULL)  {
-                ERROR("could not allocate memory for tx fp queue\n");
+                FRESCAN_ERROR("could not allocate memory for tx fp queue\n");
                 return -1;
         }
 
@@ -93,7 +144,8 @@ int frescan_queues_init(frescan_queues_t *queues,
                        sizeof(frescan_prio_queue_t *));
 
         if (queues->rx_channel_queues == NULL) {
-                ERROR("could not allocate memory for receiving channels\n");
+                FRESCAN_ERROR
+                        ("could not allocate memory for receiving channels\n");
                 return -1;
         }
 
@@ -108,10 +160,12 @@ int frescan_queues_init(frescan_queues_t *queues,
                         max_prio = params->rx_channel_max_prio[i];
                 }
 
-                queues->rx_channel_queues[i] = frescan_pqueue_create(max_prio);
+                queues->rx_channel_queues[i] = frescan_pqueue_create
+                                                       (max_prio, params->net);
 
                 if (queues->rx_channel_queues[i] == NULL)  {
-                        ERROR("could not allocate memory for rx pq %d\n", i);
+                        FRESCAN_ERROR
+                               ("could not allocate memory for rx pq %d\n", i);
                         return -1;
                 }
         }
@@ -132,7 +186,7 @@ int frescan_pqueue_enqueue(frescan_prio_queue_t *pqueue,
         int ret;
 
         if (prio >= pqueue->max_prio) {
-                ERROR("priority of the packet is too high\n");
+                FRESCAN_ERROR("priority of the packet is too high\n");
                 return -1;
         }
 
@@ -160,7 +214,7 @@ int frescan_pqueue_requeue(frescan_prio_queue_t *pqueue,
         int ret;
 
         if (prio >= pqueue->max_prio) {
-                ERROR("priority of the packet is too high\n");
+                FRESCAN_ERROR("priority of the packet is too high\n");
                 return -1;
         }
 
@@ -183,7 +237,7 @@ int frescan_pqueue_dequeue(frescan_prio_queue_t *pqueue,
 {
         int prio;
         int ret;
-        frescan_packet_t *tmp;
+        frescan_packet_t *tmp = NULL;
         struct list_head *pos;
 
         *packet = NULL;
@@ -203,6 +257,12 @@ int frescan_pqueue_dequeue(frescan_prio_queue_t *pqueue,
         DEBUG(FRESCAN_QUEUES_ENABLE_DEBUG,
               "check priority fifo queues (max_prio=%u)\n", pqueue->max_prio);
 
+        // NOTE: we only acquire the lock if we block because non-blocking
+        // calls are made from a context with no interrupts (when updating
+        // the buffer at 'frescan_hw_buffer_update' which is always called
+        // with interrupts disabled)
+        if (blocking) FRESCAN_ACQUIRE_LOCK(&frescan_data[pqueue->net].lock);
+
         for(prio=pqueue->max_prio-1; prio >= 0; prio--) {
                 if (!list_empty(&pqueue->fifo_queues[prio].fifo_list)) {
                         list_for_each(pos,
@@ -217,6 +277,8 @@ int frescan_pqueue_dequeue(frescan_prio_queue_t *pqueue,
                 }
         }
 
+        if (blocking) FRESCAN_RELEASE_LOCK(&frescan_data[pqueue->net].lock);
+
         DEBUG(FRESCAN_QUEUES_ENABLE_DEBUG, "dequeued prio %u\n", prio);
         *packet_prio = prio;
 
@@ -233,7 +295,7 @@ int frescan_pqueue_get_highest_prio(frescan_prio_queue_t *pqueue,
                                     frescan_prio_t *packet_prio)
 {
         int prio;
-        frescan_packet_t *tmp;
+        frescan_packet_t *tmp = NULL;
         struct list_head *pos;
 
         *packet = NULL;
@@ -271,22 +333,26 @@ int frescan_servers_enqueue(frescan_network_t net,
                             frescan_ss_t id,
                             frescan_packet_t *packet)
 {
-        DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG, "enqueue packet for id:%u\n", id);
+        frescan_ss_data_t *server = &frescan_data[net].ss_data[id];
+
+        clock_gettime (CLOCK_MONOTONIC, &packet->timestamp);
+
+        DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG, "id:%u timestamp:(%d, %d)\n",
+              id, packet->timestamp.tv_sec, packet->timestamp.tv_nsec);
 
         // add the packet to the server fifo list
-        list_add_tail(&packet->fifo_list,
-                       &the_servers_pool[net][id].packet_list.fifo_list);
+        list_add_tail(&packet->fifo_list, &server->packet_list.fifo_list);
 
-        // if the server was inactive (no packets to send) put it active
-        // (in the active list)
-        if (the_servers_pool[net][id].pending_packets == 0) {
+        // if the server was inactive (no packets) put it in the active list
+        if (server->pending_packets == 0) {
                 DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
-                      "server was inactive, put in the active list\n");
-                list_add_tail(&the_servers_pool[net][id].servers_list,
-                               &the_active_servers[net].servers_list);
+                      "ss becomes active act_time=timestamp\n");
+                list_add_tail(&server->servers_list,
+                               &frescan_data[net].ss_active_head.servers_list);
+                server->act_time = packet->timestamp;
         }
 
-        the_servers_pool[net][id].pending_packets++;
+        server->pending_packets++;
         return 0;
 }
 
@@ -308,18 +374,18 @@ int frescan_servers_requeue(frescan_network_t net,
 
         // add the packet to the server fifo list
         list_add(&packet->fifo_list,
-                  &the_servers_pool[net][id].packet_list.fifo_list);
+                  &frescan_data[net].ss_data[id].packet_list.fifo_list);
 
         // if the server was inactive (no packets to send) put it active
         // (in the active list)
-        if (the_servers_pool[net][id].pending_packets == 0) {
+        if (frescan_data[net].ss_data[id].pending_packets == 0) {
                 DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
                       "server was inactive, put in the active list\n");
-                list_add(&the_servers_pool[net][id].servers_list,
-                          &the_active_servers[net].servers_list);
+                list_add(&frescan_data[net].ss_data[id].servers_list,
+                          &frescan_data[net].ss_active_head.servers_list);
         }
 
-        the_servers_pool[net][id].pending_packets++;
+        frescan_data[net].ss_data[id].pending_packets++;
         return 0;
 }
 
@@ -339,30 +405,33 @@ int frescan_servers_dequeue(frescan_network_t net,
                             frescan_prio_t *packet_prio)
 {
         struct list_head *pos;
+        frescan_ss_data_t *server;
+
+        server = &frescan_data[net].ss_data[id];
 
-        if (list_empty(&the_servers_pool[net][id].packet_list.fifo_list)) {
-                ERROR("no packet in server %d fifo list\n", id);
+        if (list_empty(&server->packet_list.fifo_list)) {
+                FRESCAN_ERROR("no packet in server %d fifo list\n", id);
                 return -1;
         }
 
-        list_for_each(pos, &the_servers_pool[net][id].packet_list.fifo_list) {
+        list_for_each(pos, &server->packet_list.fifo_list) {
                 *packet = list_entry(pos, frescan_packet_t, fifo_list);
                 break;
         }
 
         list_del(&((*packet)->fifo_list));
-        *packet_prio = the_servers_pool[net][id].current_priority;
-        the_servers_pool[net][id].pending_packets--;
+        *packet_prio = server->current_priority;
+        server->pending_packets--;
 
-        if (the_servers_pool[net][id].pending_packets == 0) {
+        if (server->pending_packets == 0) {
                 DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
                       "no more packets, delete from active list\n");
-                list_del(&the_servers_pool[net][id].servers_list);
+                list_del(&server->servers_list);
         }
 
         DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
               "dequeued packet server:%u cur_prio:%u pending:%u\n",
-              id, *packet_prio, the_servers_pool[net][id].pending_packets);
+              id, *packet_prio, server->pending_packets);
 
         return 0;
 }