From 52bc9c76a6346a1786ed938288a40ecf86493e08 Mon Sep 17 00:00:00 2001 From: sangorrin Date: Mon, 14 Apr 2008 16:58:45 +0000 Subject: [PATCH] abort when higher prio frame git-svn-id: http://www.frescor.org/private/svn/frescor/fna/trunk@1105 35b4ef3e-fd22-0410-ab77-dab3279adceb --- src_frescan/TODO | 9 ++++ src_frescan/frescan.c | 87 ++++++++++++++++++++++++++++++--- src_frescan/frescan_debug.h | 8 +-- src_frescan/frescan_hw_buffer.c | 23 ++++----- 4 files changed, 104 insertions(+), 23 deletions(-) create mode 100644 src_frescan/TODO diff --git a/src_frescan/TODO b/src_frescan/TODO new file mode 100644 index 0000000..951582d --- /dev/null +++ b/src_frescan/TODO @@ -0,0 +1,9 @@ +- LOCKS to protect the share structures +- Renegotiate, cancel contract +- reserve commit functions +- use an internal thread as a bottom half for irq hooks +- corrections in fna + * CTU corrections + * fna_vres_id_t will be frsh_vres_index_T +- integrate with frsh_sa scheduling analysis module and spare capacity +- deliverable diff --git a/src_frescan/frescan.c b/src_frescan/frescan.c index 0630342..114e059 100644 --- a/src_frescan/frescan.c +++ b/src_frescan/frescan.c @@ -43,6 +43,8 @@ static int frescan_hook_frame_recv (const struct can_chip_t *chip, static int frescan_hook_frame_sent(const struct can_chip_t *chip); +static int frescan_hook_frame_aborted(const struct can_chip_t *chip); + /** * frescan_init - initializes the network and the internal structures * @@ -100,7 +102,7 @@ int frescan_init(frescan_init_params_t *params) return -1; } - DEBUG(FRESCAN_INIT_ENABLE_DEBUG, "set tx and rx hooks\n"); + DEBUG(FRESCAN_INIT_ENABLE_DEBUG, "set tx, rx, abort hooks\n"); ret = ioctl(fd, CAN_IOCTL_SET_TX_HOOK, frescan_hook_frame_sent); if (ret == -1) { @@ -116,6 +118,13 @@ int frescan_init(frescan_init_params_t *params) return -1; } + ret = ioctl(fd, CAN_IOCTL_SET_AB_HOOK, frescan_hook_frame_aborted); + if (ret == -1) { + ERROR ("ioctl CAN_IOCTL_SET_AB_HOOK failed /dev/can%u\n", + params->net); + return -1; + } + DEBUG(FRESCAN_INIT_ENABLE_DEBUG, "init the rest of modules\n"); ret = frescan_data_init(fd, params); @@ -503,7 +512,6 @@ static int frescan_hook_frame_recv (const struct can_chip_t *chip, return 0; }; - /** * frescan_hook_frame_sent - frame sent hook * @@ -522,14 +530,14 @@ static int frescan_hook_frame_sent(const struct can_chip_t *chip) packet = the_networks[chip->minor].last_packet; + id = frescan_id_get_field(packet->frame->id, + FRESCAN_FIELD_FRAG_ID); + DEBUG(FRESCAN_SENT_HOOK_ENABLE_DEBUG, - "frame sent, minor:%u flags:0x%X\n", - chip->minor, packet->flags); + "frame sent, minor:%u flags:0x%X frag_id:0x%X\n", + chip->minor, packet->flags, id); if (packet->flags & FRESCAN_SS) { - id = frescan_id_get_field(packet->frame->id, - FRESCAN_FIELD_FRAG_ID); - DEBUG(FRESCAN_SENT_HOOK_ENABLE_DEBUG, "calling frame_sent + program repl for id:%u\n", id); @@ -592,7 +600,7 @@ static int frescan_hook_frame_sent(const struct can_chip_t *chip) return ret; } - // TODO: signal semaphores, server consume budget... + // TODO: signal semaphore for send_sync } the_networks[chip->minor].last_packet = NULL; @@ -605,3 +613,66 @@ static int frescan_hook_frame_sent(const struct can_chip_t *chip) return 0; }; + +/** + * frescan_hook_frame_aborted - frame frame aborted hook + * + * This function will be called by the CAN driver's IRQ handler when a frame + * is aborted (because another frame with higher priority is waiting). We + * have to requeue the frame and update the buffer. + */ + +static int frescan_hook_frame_aborted(const struct can_chip_t *chip) +{ + int ret; + frescan_packet_t *packet; + frescan_prio_queue_t *pqueue; + frescan_prio_t prio; + frescan_ss_t id; + + packet = the_networks[chip->minor].last_packet; + + id = frescan_id_get_field(packet->frame->id, + FRESCAN_FIELD_FRAG_ID); + + DEBUG(FRESCAN_SENT_HOOK_ENABLE_DEBUG, + "frame aborted, minor:%u flags:0x%X frag_id:0x%X\n", + chip->minor, packet->flags, id); + + if (packet->flags & FRESCAN_FP) { + prio = frescan_id_get_field(packet->frame->id, + FRESCAN_FIELD_PRIO); + + DEBUG(FRESCAN_FRAG_ENABLE_DEBUG, + "requeue fp packet, prio:%u\n", prio); + + pqueue = the_networks[chip->minor].queues.tx_fp_queue; + ret = frescan_pqueue_requeue(pqueue, packet, prio); + if (ret != 0) { + ERROR("could not requeue the packet\n"); + return -1; + } + } else if (packet->flags & FRESCAN_SS) { + DEBUG(FRESCAN_FRAG_ENABLE_DEBUG, + "requeue server %u packet\n", id); + + ret = frescan_servers_requeue(chip->minor, id, packet); + if (ret != 0) { + ERROR("could not requeue the packet\n"); + return -1; + } + } else { + ERROR("flags are not correct\n"); + return -1; + } + + the_networks[chip->minor].last_packet = NULL; + + ret = frescan_hw_buffer_update(chip->minor); + if (ret != 0) { + ERROR("could not update hw buffer\n"); + return -1; + } + + return 0; +} diff --git a/src_frescan/frescan_debug.h b/src_frescan/frescan_debug.h index e9a981c..d0f34d7 100644 --- a/src_frescan/frescan_debug.h +++ b/src_frescan/frescan_debug.h @@ -53,10 +53,10 @@ #define FRESCAN_REPL_ENABLE_DEBUG false #define FRESCAN_REPLYOBJ_ENABLE_DEBUG false #define FRESCAN_NEG_THREAD_ENABLE_DEBUG false -#define FRESCAN_BWRES_ENABLE_DEBUG true +#define FRESCAN_BWRES_ENABLE_DEBUG false #define FRESCAN_REQUESTS_ENABLE_DEBUG false -#define FRESCAN_ACCEPTOR_THREAD_ENABLE_DEBUG true -#define FRESCAN_NEG_MESSAGES_ENABLE_DEBUG true -#define FRESCAN_FNA_ENABLE_DEBUG true +#define FRESCAN_ACCEPTOR_THREAD_ENABLE_DEBUG false +#define FRESCAN_NEG_MESSAGES_ENABLE_DEBUG false +#define FRESCAN_FNA_ENABLE_DEBUG false #endif // _MARTE_FRESCAN_DEBUG_H_ diff --git a/src_frescan/frescan_hw_buffer.c b/src_frescan/frescan_hw_buffer.c index f2996c7..3d8a57d 100644 --- a/src_frescan/frescan_hw_buffer.c +++ b/src_frescan/frescan_hw_buffer.c @@ -40,21 +40,22 @@ * buffer of the chip. It is useful to prevent priority inversion when there * is another packet with highest priority waiting in the frescan queues. * - * TODO: implement it + * NOTE: if the frame is already being transmitted it won't abort it. In both + * cases a IRQ will be raised and either 'frescan_hook_frame_sent' or + * 'frescan_hook_frame_aborted' will be called. */ int frescan_hw_buffer_abort(frescan_network_t net) { -// int ret; -// -// ret = ioctl(the_networks[net].fd, -// CAN_IOCTL_ABORT_FRAME, NULL); -// if (ret == -1) { -// ERROR ("could not abort the frame\n"); -// return -1; -// } - ERROR ("NOT IMPLEMENTED\n"); - return -1; + int ret; + + ret = ioctl(the_networks[net].fd, CAN_IOCTL_ABORT_FRAME, NULL); + if (ret == -1) { + ERROR ("could not abort the frame\n"); + return -1; + } + + return 0; } /** -- 2.39.2