*
* @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;
}
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;
}
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;
}
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;
}
}
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;
}
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;
}
{
int prio;
int ret;
- frescan_packet_t *tmp;
+ frescan_packet_t *tmp = NULL;
struct list_head *pos;
*packet = NULL;
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,
}
}
+ if (blocking) FRESCAN_RELEASE_LOCK(&frescan_data[pqueue->net].lock);
+
DEBUG(FRESCAN_QUEUES_ENABLE_DEBUG, "dequeued prio %u\n", prio);
*packet_prio = prio;
frescan_prio_t *packet_prio)
{
int prio;
- frescan_packet_t *tmp;
+ frescan_packet_t *tmp = NULL;
struct list_head *pos;
*packet = NULL;
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;
}
// 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;
}
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;
}