From 76befd94f11133e7aaaa4e76a35b89ead9d81dc9 Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Wed, 13 Jul 2011 15:08:33 +0200 Subject: [PATCH] update to current mailbox-system --- arch/x86/include/asm/iRCCE_lib.h | 4 +- arch/x86/include/asm/iRCCE_lib.h.old | 56 ++++ arch/x86/scc/iRCCE_admin.c | 18 +- arch/x86/scc/iRCCE_admin.c.old | 131 ++++++++ arch/x86/scc/iRCCE_mailbox.c | 113 ++++--- arch/x86/scc/iRCCE_mailbox.c.old | 474 +++++++++++++++++++++++++++ 6 files changed, 747 insertions(+), 49 deletions(-) create mode 100644 arch/x86/include/asm/iRCCE_lib.h.old create mode 100644 arch/x86/scc/iRCCE_admin.c.old create mode 100644 arch/x86/scc/iRCCE_mailbox.c.old diff --git a/arch/x86/include/asm/iRCCE_lib.h b/arch/x86/include/asm/iRCCE_lib.h index 372b9cdd..70df2596 100644 --- a/arch/x86/include/asm/iRCCE_lib.h +++ b/arch/x86/include/asm/iRCCE_lib.h @@ -36,7 +36,7 @@ extern volatile iRCCE_MAIL_HEADER* iRCCE_mailbox_send[RCCE_MAXNP]; extern volatile iRCCE_MAIL_HEADER* iRCCE_mailbox_recv[RCCE_MAXNP]; // queue for received headers -extern iRCCE_MAIL_HEADER* iRCCE_mailbox_recv_queue[iRCCE_PRIOS]; +extern iRCCE_MAIL_HEADER_LIST iRCCE_mailbox_recv_queue[iRCCE_PRIOS]; // flags for last mail extern iRCCE_SHORT_FLAG iRCCE_last_mail[RCCE_MAXNP]; @@ -45,7 +45,7 @@ extern iRCCE_SHORT_FLAG iRCCE_last_mail[RCCE_MAXNP]; extern iRCCE_SHORT_FLAG iRCCE_mailbox_status[RCCE_MAXNP]; // garbage collection for mailbox -extern iRCCE_MAIL_TRASH_BIN iRCCE_mail_garbage; +extern iRCCE_MAIL_HEADER_LIST iRCCE_mail_garbage; #ifdef _OPENMP #pragma omp threadprivate (iRCCE_isend_queue, iRCCE_irecv_queue) #endif diff --git a/arch/x86/include/asm/iRCCE_lib.h.old b/arch/x86/include/asm/iRCCE_lib.h.old new file mode 100644 index 00000000..372b9cdd --- /dev/null +++ b/arch/x86/include/asm/iRCCE_lib.h.old @@ -0,0 +1,56 @@ +// +// Copyright 2010 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// [2010-10-25] added support for non-blocking send/recv operations +// - iRCCE_isend(), ..._test(), ..._wait(), ..._push() +// - iRCCE_irecv(), ..._test(), ..._wait(), ..._push() +// by Carsten Clauss, Chair for Operating Systems, +// RWTH Aachen University +// +// [2010-11-12] extracted non-blocking code into separate library +// by Carsten Scholtes +// +#ifndef IRCCE_LIB_H +#define IRCCE_LIB_H +#include +#include + +extern iRCCE_SEND_REQUEST* iRCCE_isend_queue; +extern iRCCE_RECV_REQUEST* iRCCE_irecv_queue[RCCE_MAXNP]; +extern iRCCE_RECV_REQUEST* iRCCE_irecv_any_source_queue; + +// pointer to MPB-mailbox-space +extern volatile iRCCE_MAIL_HEADER* iRCCE_mailbox_send[RCCE_MAXNP]; +extern volatile iRCCE_MAIL_HEADER* iRCCE_mailbox_recv[RCCE_MAXNP]; + +// queue for received headers +extern iRCCE_MAIL_HEADER* iRCCE_mailbox_recv_queue[iRCCE_PRIOS]; + +// flags for last mail +extern iRCCE_SHORT_FLAG iRCCE_last_mail[RCCE_MAXNP]; + +// field to store open/closed status of mailboxes +extern iRCCE_SHORT_FLAG iRCCE_mailbox_status[RCCE_MAXNP]; + +// garbage collection for mailbox +extern iRCCE_MAIL_TRASH_BIN iRCCE_mail_garbage; +#ifdef _OPENMP +#pragma omp threadprivate (iRCCE_isend_queue, iRCCE_irecv_queue) +#endif + +int iRCCE_test_flag(RCCE_FLAG, RCCE_FLAG_STATUS, int *); + +#endif + diff --git a/arch/x86/scc/iRCCE_admin.c b/arch/x86/scc/iRCCE_admin.c index 2a28f09e..cd119167 100644 --- a/arch/x86/scc/iRCCE_admin.c +++ b/arch/x86/scc/iRCCE_admin.c @@ -55,10 +55,10 @@ volatile iRCCE_MAIL_HEADER* iRCCE_mailbox_recv[RCCE_MAXNP]; // store addresses f volatile iRCCE_MAIL_HEADER* iRCCE_mailbox_send[RCCE_MAXNP]; // store addresses for sending headeres // mailbox recv queue -iRCCE_MAIL_HEADER* iRCCE_mailbox_recv_queue[iRCCE_PRIOS]; +iRCCE_MAIL_HEADER_LIST iRCCE_mailbox_recv_queue[iRCCE_PRIOS]; // mail garbage queue -iRCCE_MAIL_TRASH_BIN iRCCE_mail_garbage; +iRCCE_MAIL_HEADER_LIST iRCCE_mail_garbage; // flag indicating if last header was received iRCCE_SHORT_FLAG iRCCE_last_mail[RCCE_MAXNP]; @@ -71,7 +71,16 @@ iRCCE_SHORT_FLAG iRCCE_mailbox_status[RCCE_MAXNP]; //-------------------------------------------------------------------------------------- // FUNCTION: iRCCE_init //-------------------------------------------------------------------------------------- -// initialize the library +/** + * @brief initialize the library + * + * To initialize the mailbox system the function calles RCCE_malloc() as often + * as there are UEs participating. As a result the respective mailboxes are + * located at the begin of the local MPB directly behind the space reserved for + * flags by RCCE_init(). In iRCCE_mailbox_recv[i] a pointer to the mailbox is + * saved respectively. To access the send mailboxes at the receiving UEs the + * coresponding pointers are saved in iRCCE_mailbox_send[i] resprectively. + */ //-------------------------------------------------------------------------------------- int iRCCE_init(void) { int i; @@ -93,7 +102,8 @@ int iRCCE_init(void) { // init mail-priority lists for( i=0; i + +#ifdef CONFIG_ROCKCREEK + +#include + +// send request queue +iRCCE_SEND_REQUEST* iRCCE_isend_queue; +// recv request queue +iRCCE_RECV_REQUEST* iRCCE_irecv_queue[RCCE_MAXNP]; + +// recv request queue for those with source = iRCCE_ANY_SOURCE: +iRCCE_RECV_REQUEST* iRCCE_irecv_any_source_queue; + +// mailbox in MPB +volatile iRCCE_MAIL_HEADER* iRCCE_mailbox_recv[RCCE_MAXNP]; // store addresses for receiving headers +volatile iRCCE_MAIL_HEADER* iRCCE_mailbox_send[RCCE_MAXNP]; // store addresses for sending headeres + +// mailbox recv queue +iRCCE_MAIL_HEADER* iRCCE_mailbox_recv_queue[iRCCE_PRIOS]; + +// mail garbage queue +iRCCE_MAIL_TRASH_BIN iRCCE_mail_garbage; + +// flag indicating if last header was received +iRCCE_SHORT_FLAG iRCCE_last_mail[RCCE_MAXNP]; + +// field to store open/closed status of mailboxes +iRCCE_SHORT_FLAG iRCCE_mailbox_status[RCCE_MAXNP]; + + + +//-------------------------------------------------------------------------------------- +// FUNCTION: iRCCE_init +//-------------------------------------------------------------------------------------- +// initialize the library +//-------------------------------------------------------------------------------------- +int iRCCE_init(void) { + int i; + + for(i=0; inext; + kfree( erase_header, sizeof(iRCCE_MAIL_HEADER) ); + } + + iRCCE_mail_garbage.first = iRCCE_mail_garbage.last = NULL; + return iRCCE_SUCCESS; +} +#endif diff --git a/arch/x86/scc/iRCCE_mailbox.c b/arch/x86/scc/iRCCE_mailbox.c index 1284acf5..045a731d 100644 --- a/arch/x86/scc/iRCCE_mailbox.c +++ b/arch/x86/scc/iRCCE_mailbox.c @@ -1,28 +1,40 @@ -/* - * Copyright 2011 Simon Pickartz, Chair for Operating Systems, - * RWTH Aachen University - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of MetalSVM. - */ +//****************************************************************************** +// Mailbox system. +//****************************************************************************** +// +// Author: Simon Pickartz, +// Chair for Operating Systems, +// RWTH Aachen University +// Date: 005/08/2011 +// +//****************************************************************************** +// +// Copyright 2010 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +#include "iRCCE_lib.h" +#include +#include +#include -/* - * Mailbox system +/** + * + * @file contains implementation of the mailbox system + * @author Simon Pickartz + * * - * [2011-05-08] implemented mailbox send/recv routines - * by Simon Pickartz, Chair for Operating Systems, - * RWTH Aachen University */ #include @@ -48,7 +60,7 @@ static int iRCCE_mailbox_close_one(int rank, int check); void iRCCE_mailbox_print_header(iRCCE_MAIL_HEADER* header) { - kprintf( "\n" + printf( "\n" "-------------------------\n" "| RCK%d\n" "-------------------------\n" @@ -117,14 +129,17 @@ static int iRCCE_mail_fetch( int prio = header->prio; // enqueue accordingly - if( iRCCE_mailbox_recv_queue[prio] == NULL ) { - iRCCE_mailbox_recv_queue[prio] = header; + header->next = NULL; + + if( iRCCE_mailbox_recv_queue[prio].first == NULL ) { + iRCCE_mailbox_recv_queue[prio].first = header; + iRCCE_mailbox_recv_queue[prio].last = header; } else { - iRCCE_MAIL_HEADER* run = iRCCE_mailbox_recv_queue[prio]; - while( run->next != NULL ) run = run->next; - run->next = header; + iRCCE_mailbox_recv_queue[prio].last->next = header; + iRCCE_mailbox_recv_queue[prio].last = header; } + } @@ -138,7 +153,7 @@ static int iRCCE_mail_fetch( /** * @brief routine to check for new mail in mailboxes * - * This function has to be called from time to time. It empties all mailboxes of + * This function has to be called from time to time. It empeies all mailboxes of * the participating cores if the corresponding sent-flag is set and the mailbox * is not closed. After calling iRCCE_mail_fetch the sent-flag has to be reset. * Here we have to use a little trick because we can only write to the MPB in @@ -148,9 +163,13 @@ static int iRCCE_mail_fetch( */ //------------------------------------------------------------------------------ static int iRCCE_mailbox_check() { - int i; + int i,j; + + for( j=1; jnext; + if ( iRCCE_mailbox_recv_queue[i].first ) { + help_header = iRCCE_mailbox_recv_queue[i].first; + + iRCCE_mailbox_recv_queue[i].first = + iRCCE_mailbox_recv_queue[i].first->next; + + if( iRCCE_mailbox_recv_queue[i].first == NULL ) { + iRCCE_mailbox_recv_queue[i].last = NULL; + } + help_header->next = NULL; *header = help_header; @@ -321,10 +346,10 @@ int iRCCE_mail_send( RC_cache_invalidate(); iRCCE_mailbox_send[dest]->sent = RCCE_FLAG_SET; *(int *)RCCE_fool_write_combine_buffer = 1; - RC_cache_invalidate(); + RC_cache_invalidate(); RCCE_release_lock( dest ); - + return iRCCE_SUCCESS; } @@ -391,12 +416,14 @@ int iRCCE_mailbox_flush(void) { int i; for( i=0; inext; + iRCCE_mailbox_recv_queue[i].first = + iRCCE_mailbox_recv_queue[i].first->next; kfree( erase_header, sizeof(iRCCE_MAIL_HEADER) ); - erase_header = iRCCE_mailbox_recv_queue[i]; + erase_header = iRCCE_mailbox_recv_queue[i].first; } } return iRCCE_SUCCESS; diff --git a/arch/x86/scc/iRCCE_mailbox.c.old b/arch/x86/scc/iRCCE_mailbox.c.old new file mode 100644 index 00000000..47935533 --- /dev/null +++ b/arch/x86/scc/iRCCE_mailbox.c.old @@ -0,0 +1,474 @@ +/* + * Copyright 2011 Simon Pickartz, Chair for Operating Systems, + * RWTH Aachen University + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of MetalSVM. + */ + +/* + * Mailbox system + * + * [2011-05-08] implemented mailbox send/recv routines + * by Simon Pickartz, Chair for Operating Systems, + * RWTH Aachen University + */ + +#include +#include + + +#ifdef CONFIG_ROCKCREEK +#include + +// forward declaration +static int iRCCE_mailbox_close_one(int rank, int check); + + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_mailbox_print_header +//------------------------------------------------------------------------------ +// routine for printing given header (debugging purpose) +//------------------------------------------------------------------------------ +/** + * @brief routine for printing a given header + * @param header is a pointer to a given iRCCE_MAIL_HEADER structure +*/ + +void iRCCE_mailbox_print_header(iRCCE_MAIL_HEADER* header) { + + kprintf( "\n" + "-------------------------\n" + "| RCK%d\n" + "-------------------------\n" + "| Sender\t: %d\t\n" + "| Size\t\t: %d\t\n" + "| Tag\t\t: %d\t\n" + "| Prio\t\t: %d\t\n" + "| Payload\t: %s\n" + "-------------------------\n\n", + RCCE_IAM, header->source, + header->size, header->tag, + header->prio, header->payload); +} + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_mail_fetch +//------------------------------------------------------------------------------ +/** + * @brief routine to check for new mail in a given mailbox + * @param rank is the ID of the ranks mailbox to be emptied + * + * The function checks if the mailbox has new mail for a given rank. In case of + * new mail it needs memory for the received header. Either there is memory + * in the internal garbage collection or it has to allocated. The next step is + * to check wheter a last-mail was received or a normal one. A last-mail is + * indicated by the iRCCE_LAST_MAIL tag. A last-mail entails the appropriate + * flag in the iRCCE_last_mail array to be set. Otherwise the header has to be + * enqueued in the mailbox_recv_queue accordingly to the priority field. + */ +//------------------------------------------------------------------------------ +static int iRCCE_mail_fetch( + int rank // rank from whom to empty mailbox + ) { + + iRCCE_MAIL_HEADER* header; + + // check for memory in garbage collection or allocate new + if( iRCCE_mail_garbage.first ) { + header = iRCCE_mail_garbage.first; + iRCCE_mail_garbage.first = + iRCCE_mail_garbage.first->next; + + header->next = NULL; + if( iRCCE_mail_garbage.first == NULL ) { + iRCCE_mail_garbage.last = NULL; + } + } + else { + header = (iRCCE_MAIL_HEADER*)kmalloc(sizeof(iRCCE_MAIL_HEADER)); + } + + + // copy header to allocated memory + RC_cache_invalidate(); + iRCCE_memcpy_get( (void*)header, (void*)iRCCE_mailbox_recv[rank], + RCCE_LINE_SIZE ); + + // check if received a last-mail + if( header->tag == iRCCE_LAST_MAIL ) { + iRCCE_last_mail[rank] = 1; + iRCCE_mailbox_close_one( rank, 0 ); // we can close respective mailbox + iRCCE_mail_release( &header ); + } + else { + // check mail priority + int prio = header->prio; + + // enqueue accordingly + if( iRCCE_mailbox_recv_queue[prio] == NULL ) { + iRCCE_mailbox_recv_queue[prio] = header; + } + else { + iRCCE_MAIL_HEADER* run = iRCCE_mailbox_recv_queue[prio]; + while( run->next != NULL ) run = run->next; + run->next = header; + } + } + + + return iRCCE_SUCCESS; +} + + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_mailbox_check +//------------------------------------------------------------------------------ +/** + * @brief routine to check for new mail in mailboxes + * + * This function has to be called from time to time. It empties all mailboxes of + * the participating cores if the corresponding sent-flag is set and the mailbox + * is not closed. After calling iRCCE_mail_fetch the sent-flag has to be reset. + * Here we have to use a little trick because we can only write to the MPB in + * cacheline granularity. We set the appropriate flag to zero and afterwords + * touch the MPB on another cacheline. That causes the write combine buffer to + * write out the data. + */ +//------------------------------------------------------------------------------ +static int iRCCE_mailbox_check() { + int i; + + for( i=0; isent ) { + iRCCE_mail_fetch(i); + + // reset senders flag + RC_cache_invalidate(); + iRCCE_mailbox_recv[i]->sent = RCCE_FLAG_UNSET; + *(int *)RCCE_fool_write_combine_buffer = 1; + } + } + } + + return iRCCE_SUCCESS; +} + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_mail_recv +//------------------------------------------------------------------------------ +/** + * @brief routine for fetching received headers out of iRCCE_mailbox_recv_queue + * @param header is the address of a pointer to an iRCCE_MAIL_HEADER structure + * @return iRCCE_SUCCESS if there was new mail; iRCCE_MAILBOX_EMPTY else + * @todo implement fairer dequeue mechanism + * + * The function checks if the receive queue with highest priority (priority 0) + * contains any mail headers. In this case we pop the first element of that list + * in a FIFO maner. Otherwise iRCCE_mailbox_check() has to be called. Afterwards + * the first element of a non-empty receive queue with highest priority is + * returned. + */ +//------------------------------------------------------------------------------ +int iRCCE_mail_recv( + iRCCE_MAIL_HEADER** header // pointer to incoming header + ) { // (memory allocated by iRCCE) + + int i; + + // if there is no mail, check for incoming + if ( !iRCCE_mailbox_recv_queue[0] ) { + iRCCE_mailbox_check(); + } + + // check priority queues + for( i=0; inext; + help_header->next = NULL; + + *header = help_header; + return iRCCE_SUCCESS; + } + } + + // no mail queued + *header = NULL; + return iRCCE_MAILBOX_EMPTY; + +} + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_mail_release +//------------------------------------------------------------------------------ +/** + * @brief routine to store released header by user in garbage collection + * @param header is the address of a pointer to an iRCCE_MAIL_HEADER structure + * @return iRCCE_SUCCESS in any case + * + * This function enqueus a pointer to memory for an iRCCE_MAIL_HEADER structure + * that is not used by the user program anymore. 'header' points to NULL by + * return of the function. + */ +//------------------------------------------------------------------------------ +int iRCCE_mail_release( + iRCCE_MAIL_HEADER** header + ) { + // put header in garbage collection + if( (iRCCE_mail_garbage.first == NULL) + && (iRCCE_mail_garbage.last == NULL ) ) { + + iRCCE_mail_garbage.first = *header; + iRCCE_mail_garbage.last = *header; + } + else { + iRCCE_mail_garbage.last->next = *header; + iRCCE_mail_garbage.last = *header; + } + iRCCE_mail_garbage.last->next = NULL; + + // reset header + *header = NULL; + return iRCCE_SUCCESS; +} + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_mail_send +//------------------------------------------------------------------------------ +/** + * @brief routine to send a mail to a given destination (blocking) + * @param size is the size of the following message. This message may be + * contained in the payload or send by an isend()-call + * @param tag is an integer value to distinguish between different mail types + * @param prio indicates the priority of the mail. 0 is the highest priority + * whereas 4 is the lowest. + * @param payload is a pointer to byte array with a size of + * iRCCE_MAIL_HEADER_PAYLOAD. If NULL is passed nothing is done, otherwise array + * pointed by payload is copied into the header. + * @param dest indicates the destination of the mail in terms of the ID of + * one of the participating ranks + * @return iRCCE_SUCCESS if send was successful. If target mailbox is closed + * iRCCE_MAILBOX_CLOESD is returned. + * + * First it has to be checked if the target mailbox still contains an unread mail. + * If this is the case there is time to empty the own mailboxes. It blocks until + * the receiver has emptied its mailbox. The next step is to acquire the lock + * for the target mailbox to be sure that the mailbox is not closed by the + * receiver while the mail is delivered. After locking the mailbox an + * iRCCE_MAIL_HEADER is generated according with the parameters (but with a + * sent-flag set to zero)and is copied into the target mailbox. After all data + * beeing written the appropropriate sent-flag has to be set with the same trick + * already used in iRCCE_mail_check(). Now the lock can be released. + */ +//------------------------------------------------------------------------------ +int iRCCE_mail_send( + size_t size, // size of following message expected to be send/received + int tag, // tag to indicate message type + char prio, // mail priority + char* payload, // pointer to buffer for header payload + int dest // UE that will receive the header + ) { + + // if dest mailbox is full, check for incoming mail + RC_cache_invalidate(); + while( iRCCE_mailbox_send[dest]->sent ) { + iRCCE_mailbox_check(); + RC_cache_invalidate(); + } + + // check if mailbox is closed + RCCE_acquire_lock( dest ); + RC_cache_invalidate(); + if( iRCCE_mailbox_send[dest]->closed ) { + RCCE_release_lock( dest ); + return iRCCE_MAILBOX_CLOSED; + } + + // prepare header + iRCCE_MAIL_HEADER header = { RCCE_IAM, size, tag, NULL, prio, + RCCE_FLAG_UNSET, RCCE_FLAG_UNSET, + {[0 ... iRCCE_MAIL_HEADER_PAYLOAD-1] = 0} }; + + // payload within the header? + if( payload ) { + memcpy( header.payload, payload, iRCCE_MAIL_HEADER_PAYLOAD ); + } + + // do the actual copy to MPB + RC_cache_invalidate(); + iRCCE_memcpy_put( (void*)iRCCE_mailbox_send[dest], + (void*)&header, RCCE_LINE_SIZE ); + + // set senders flag + RC_cache_invalidate(); + iRCCE_mailbox_send[dest]->sent = RCCE_FLAG_SET; + *(int *)RCCE_fool_write_combine_buffer = 1; + RC_cache_invalidate(); + + RCCE_release_lock( dest ); + + return iRCCE_SUCCESS; +} + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_last_mail_recv +//------------------------------------------------------------------------------ +/** + * @brief check if all final headers are received from all UEs + * @return iRCCE_SUCCES if all last-mails arrive iRCCE_LAST_MAILS_NOT_RECV + * otherwise + * + * This functions is used to determine if all last-mails arrived at the calling + * UE. Therefore it checks the iRCCE_last_mail array if all flags are set. + */ +//------------------------------------------------------------------------------ +int iRCCE_last_mail_recv(void) { + int i; + int res = iRCCE_SUCCESS; + + for( i=0; inext; + kfree( erase_header, sizeof(iRCCE_MAIL_HEADER) ); + erase_header = iRCCE_mailbox_recv_queue[i]; + } + } + return iRCCE_SUCCESS; +} + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_mailbox_close_one +//------------------------------------------------------------------------------ +/** + * @brief routine to close one mailbox + * @return iRCCE_SUCCESS + * @param rank is the ID of the ranks mailbox to be closed + * @param check is a flag indicating wether the mailbox has to be emptied before + * closing or not. This is required for a close-call as a result of a received + * last-mail. + * + * This function closes a mailbox of the given rank. If the check flag is set + * an iRCCE_mail_check()-call is performed. The close procedure has to be locked + * to be sure that no UE sends any mail while closing the mailbox. + */ +//------------------------------------------------------------------------------ +static int iRCCE_mailbox_close_one(int rank, int check) { + RCCE_acquire_lock( RCCE_IAM ); + + // check if it contains new mail + RC_cache_invalidate(); + if( check && iRCCE_mailbox_recv[rank]->sent ) { + iRCCE_mail_fetch(rank); + + } + + // close mailbox + iRCCE_MAIL_HEADER help_header = { 0, 0, 0, NULL, 0, RCCE_FLAG_UNSET, + RCCE_FLAG_SET, {[0 ... iRCCE_MAIL_HEADER_PAYLOAD-1] = 0} }; + + RC_cache_invalidate(); + iRCCE_memcpy_put( (void*)iRCCE_mailbox_recv[rank], + &help_header, RCCE_LINE_SIZE ); + + RCCE_release_lock( RCCE_IAM ); + + iRCCE_mailbox_status[rank] = iRCCE_MAILBOX_CLOSED; + + return iRCCE_SUCCESS; +} + + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_mailbox_close() +//------------------------------------------------------------------------------ +/** + * @brief routine to close one or all mailboxes + * @param rank is the ID of the UEs mailbox to be closed if iRCCE_MAILBOX_ALL + * is passed all mailboxes are closed by the calling UE + * @return iRCCE_SUCCESS + * + * This functions closed one or all mailboxes of the calling UE. This is done by + * calling iRCCE_mailbox_close_one for one or all mailboxes. + */ +//------------------------------------------------------------------------------ +int iRCCE_mailbox_close(int rank) { + if( rank == iRCCE_MAILBOX_ALL ) { + int i; + for( i=0; i