remove obsolete files

This commit is contained in:
Stefan Lankes 2011-08-29 04:03:32 -07:00
parent c8b821b8e1
commit 6a9794dc9b
4 changed files with 0 additions and 862 deletions

View file

@ -1,201 +0,0 @@
//
// 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, University of Bayreuth
//
// [2010-12-09] added functions for a convenient handling of multiple
// pending non-blocking requests
// by Jacek Galowicz, Chair for Operating Systems
// RWTH Aachen University
//
#ifndef IRCCE_H
#define IRCCE_H
#include "RCCE.h"
#define iRCCE_SUCCESS RCCE_SUCCESS
#define iRCCE_PENDING -1
#define iRCCE_RESERVED -2
#define iRCCE_NOT_ENQUEUED -3
#define iRCCE_ANY_SOURCE -1
#define iRCCE_PRIOS 5
#define iRCCE_MAILBOX_EMPTY -2
#define iRCCE_LAST_MAILS_NOT_RECV -3
#define iRCCE_MAILBOX_ALL -4
#define iRCCE_MAILBOX_OPEN 0
#define iRCCE_MAILBOX_CLOSED 1
// iRCCE-mailbox-system tags
#define iRCCE_LAST_MAIL -1
#define iRCCE_ANYLENGTH -2
#define iRCCE_ANYLENGTH_PIGGYBACK -3
typedef volatile char iRCCE_SHORT_FLAG;
typedef struct _iRCCE_SEND_REQUEST {
char *privbuf; // source buffer in local private memory (send buffer)
t_vcharp combuf; // intermediate buffer in MPB
size_t chunk; // size of MPB available for this message (bytes)
RCCE_FLAG *ready; // flag indicating whether receiver is ready
RCCE_FLAG *sent; // flag indicating whether message has been sent by source
size_t size; // size of message (bytes)
int dest; // UE that will receive the message
size_t wsize; // offset within send buffer when putting in "chunk" bytes
size_t remainder; // bytes remaining to be sent
size_t nbytes; // number of bytes to be sent in single RCCE_put call
char *bufptr; // running pointer inside privbuf for current location
int label; // jump/goto label for the reentrance of the respective poll function
int finished; // flag that indicates whether the request has already been finished
struct _iRCCE_SEND_REQUEST *next;
} iRCCE_SEND_REQUEST;
typedef struct _iRCCE_RECV_REQUEST {
char *privbuf; // source buffer in local private memory (send buffer)
t_vcharp combuf; // intermediate buffer in MPB
size_t chunk; // size of MPB available for this message (bytes)
RCCE_FLAG *ready; // flag indicating whether receiver is ready
RCCE_FLAG *sent; // flag indicating whether message has been sent by source
size_t size; // size of message (bytes)
int source; // UE that will send the message
size_t wsize; // offset within send buffer when putting in "chunk" bytes
size_t remainder; // bytes remaining to be sent
size_t nbytes; // number of bytes to be sent in single RCCE_put call
char *bufptr; // running pointer inside privbuf for current location
int label; // jump/goto label for the reentrance of the respective poll function
int finished; // flag that indicates whether the request has already been finished
int started; // flag that indicates whether message parts have already been received
struct _iRCCE_RECV_REQUEST *next;
} iRCCE_RECV_REQUEST;
#define iRCCE_WAIT_LIST_RECV_TYPE 0
#define iRCCE_WAIT_LIST_SEND_TYPE 1
typedef struct _iRCCE_WAIT_LISTELEM {
int type;
struct _iRCCE_WAIT_LISTELEM * next;
void * req;
} iRCCE_WAIT_LISTELEM;
typedef struct _iRCCE_WAIT_LIST {
iRCCE_WAIT_LISTELEM * first;
iRCCE_WAIT_LISTELEM * last;
} iRCCE_WAIT_LIST;
#define iRCCE_MAIL_HEADER_PAYLOAD 13
typedef struct _iRCCE_MAIL_HEADER {
int source; // UE that will send the header
size_t size; // size of the message which will be send/received
int tag; // tag indicating which kind of message we have
struct _iRCCE_MAIL_HEADER* next;// pointer for queue - could be replaced by list-object
char prio; // priority of the mail
iRCCE_SHORT_FLAG sent; // flag indicating that header is new
iRCCE_SHORT_FLAG closed; // flag indication that mailbox is closed
char payload[iRCCE_MAIL_HEADER_PAYLOAD]; // payload for small messages
} iRCCE_MAIL_HEADER;
typedef struct _iRCCE_MAIL_TRASH_BIN {
iRCCE_MAIL_HEADER* first;
iRCCE_MAIL_HEADER* last;
} iRCCE_MAIL_TRASH_BIN;
///////////////////////////////////////////////////////////////
//
// THE iRCCE API:
//
// Initialize/Finalize functions:
int iRCCE_init(void);
int iRCCE_finalize(void);
//
// Non-blocking send/recv functions:
int iRCCE_isend(char *, ssize_t, int, iRCCE_SEND_REQUEST *);
int iRCCE_isend_test(iRCCE_SEND_REQUEST *, int *);
int iRCCE_isend_wait(iRCCE_SEND_REQUEST *);
int iRCCE_isend_push(void);
int iRCCE_irecv(char *, size_t, int, iRCCE_RECV_REQUEST *);
int iRCCE_irecv_test(iRCCE_RECV_REQUEST *, int *);
int iRCCE_irecv_wait(iRCCE_RECV_REQUEST *);
int iRCCE_irecv_push(void);
//
// Blocking but pipelined send/recv functions:
int iRCCE_send(char *, size_t, int);
int iRCCE_recv(char *, size_t, int);
//
// SCC-customized put/get and memcpy functions:
int iRCCE_put(t_vcharp, t_vcharp, int, int);
int iRCCE_get(t_vcharp, t_vcharp, int, int);
void* iRCCE_memcpy_put(void*, const void*, size_t);
void* iRCCE_memcpy_get(void*, const void*, size_t);
//
// Wait/test-all/any functions:
void iRCCE_init_wait_list(iRCCE_WAIT_LIST*);
void iRCCE_add_to_wait_list(iRCCE_WAIT_LIST*, iRCCE_SEND_REQUEST *, iRCCE_RECV_REQUEST *);
int iRCCE_test_all(iRCCE_WAIT_LIST*, int *);
int iRCCE_wait_all(iRCCE_WAIT_LIST*);
int iRCCE_test_any(iRCCE_WAIT_LIST*, iRCCE_SEND_REQUEST **, iRCCE_RECV_REQUEST **);
int iRCCE_wait_any(iRCCE_WAIT_LIST*, iRCCE_SEND_REQUEST **, iRCCE_RECV_REQUEST **);
//
// Cancel functions for yet not started non-blocking requests:
int iRCCE_isend_cancel(iRCCE_SEND_REQUEST *, int *);
int iRCCE_irecv_cancel(iRCCE_RECV_REQUEST *, int *);
//
// Blocking send/recv functions for mailbox system
int iRCCE_mail_send(size_t, int, char, char*, int);
int iRCCE_mail_recv(iRCCE_MAIL_HEADER**);
//
// functions to empty mailbox-queue and to check for last mails:
int iRCCE_mail_release(iRCCE_MAIL_HEADER**);
int iRCCE_last_mail_recv(void);
int iRCCE_mailbox_wait(void);
int iRCCE_mailbox_flush(void);
int iRCCE_mailbox_close(int);
void iRCCE_mailbox_print_header(iRCCE_MAIL_HEADER*);
//
///////////////////////////////////////////////////////////////
//
// Just for for convenience:
#if 1
#define RCCE_isend iRCCE_isend
#define RCCE_isend_test iRCCE_isend_test
#define RCCE_isend_wait iRCCE_isend_wait
#define RCCE_isend_push iRCCE_isend_push
#define RCCE_irecv iRCCE_irecv
#define RCCE_irecv_test iRCCE_irecv_test
#define RCCE_irecv_wait iRCCE_irecv_wait
#define RCCE_irecv_push iRCCE_irecv_push
#define RCCE_SEND_REQUEST iRCCE_SEND_REQUEST
#define RCCE_RECV_REQUEST iRCCE_RECV_REQUEST
#endif
///////////////////////////////////////////////////////////////
#endif

View file

@ -1,56 +0,0 @@
//
// 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 <asm/iRCCE.h>
#include <asm/RCCE_lib.h>
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

View file

@ -1,131 +0,0 @@
//***************************************************************************************
// Administrative routines.
//***************************************************************************************
//
// Author: Rob F. Van der Wijngaart
// Intel Corporation
// Date: 008/30/2010
//
//***************************************************************************************
//
//
// 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
//
// [2011-02-21] added support for multiple incoming queues
// (one recv queue per remote rank)
//
#include <metalsvm/stddef.h>
#ifdef CONFIG_ROCKCREEK
#include <asm/iRCCE_lib.h>
// 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; i<RCCE_MAXNP; i++) {
iRCCE_irecv_queue[i] = NULL;
iRCCE_mailbox_recv[i] = NULL;
iRCCE_mailbox_send[i] = NULL;
iRCCE_last_mail[i] = 0;
iRCCE_mailbox_status[i] = iRCCE_MAILBOX_OPEN;
}
iRCCE_isend_queue = NULL;
iRCCE_irecv_any_source_queue = NULL;
// init trash bin for mailbox
iRCCE_mail_garbage.first = NULL;
iRCCE_mail_garbage.last = NULL;
// init mail-priority lists
for( i=0; i<iRCCE_PRIOS; ++i ) {
iRCCE_mailbox_recv_queue[i] = NULL;
}
// allocate space in MPB for mailbox and set senders mailbox-pointer
for( i=0; i<RCCE_NP; i++ ) {
iRCCE_mailbox_recv[i] = (iRCCE_MAIL_HEADER*)RCCE_malloc(RCCE_LINE_SIZE);
}
for( i=0; i<RCCE_NP; i++ ) {
iRCCE_mailbox_send[i] = (iRCCE_MAIL_HEADER*)(RCCE_comm_buffer[i] + ((RCCE_buff_ptr - RCCE_comm_buffer[RCCE_IAM]) - (RCCE_NP-RCCE_IAM)*RCCE_LINE_SIZE ));
}
return (iRCCE_SUCCESS);
}
//--------------------------------------------------------------------------------------
// FUNCTION: iRCCE_finalize
//--------------------------------------------------------------------------------------
// finalize the library
//--------------------------------------------------------------------------------------
int iRCCE_finalize(void) {
// empty iRCCE_mail_garbage
iRCCE_MAIL_HEADER* run;
iRCCE_MAIL_HEADER* erase_header;
for( run = iRCCE_mail_garbage.first; run != NULL; ) {
erase_header = run;
run = run->next;
kfree( erase_header, sizeof(iRCCE_MAIL_HEADER) );
}
iRCCE_mail_garbage.first = iRCCE_mail_garbage.last = NULL;
return iRCCE_SUCCESS;
}
#endif

View file

@ -1,474 +0,0 @@
/*
* 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 <metalsvm/stdlib.h>
#include <metalsvm/string.h>
#ifdef CONFIG_ROCKCREEK
#include <asm/iRCCE_lib.h>
// 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; i<RCCE_NP; ++i ) {
// only check open mailboxes
if( iRCCE_mailbox_status[i] == iRCCE_MAILBOX_OPEN ) {
RC_cache_invalidate();
if( iRCCE_mailbox_recv[i]->sent ) {
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; i<iRCCE_PRIOS; ++i ) {
if ( iRCCE_mailbox_recv_queue[i] ) {
iRCCE_MAIL_HEADER* help_header =
iRCCE_mailbox_recv_queue[i];
iRCCE_mailbox_recv_queue[i] =
iRCCE_mailbox_recv_queue[i]->next;
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; i<RCCE_NP; ++i ) {
if( iRCCE_last_mail[i] == 0 ) {
res = iRCCE_LAST_MAILS_NOT_RECV;
break;
}
}
return res;
}
//------------------------------------------------------------------------------
// FUNCTION: iRCCE_mailbox_wait
//------------------------------------------------------------------------------
/**
* @brief wait for all last-mails to be received
* @return iRCCE_SUCCESS
*
* This functions blocks in a loop calling continously iRCCE_last_mail_recv()
* until its return value is iRCCE_SUCCESS what implicates that all last-mails
* of the participating UEs arrived at the calling UE.
* This function is used to shut down the mailbox environment.
*/
//------------------------------------------------------------------------------
int iRCCE_mailbox_wait(void) {
while( iRCCE_last_mail_recv() == iRCCE_LAST_MAILS_NOT_RECV ) {
iRCCE_mailbox_check();
}
return iRCCE_SUCCESS;
}
//------------------------------------------------------------------------------
// FUNCTION: iRCCE_mailbox_flush
//------------------------------------------------------------------------------
/**
* @brief dequeue all iRCCE_mailbox_recv_queue elements and free memory
* @return iRCCE_SUCCESS
*
* This function empties all iRCCE_mailbox_recv_queues whith no regard to their
* content. This function is used to shut down the mailbox environment.
*/
//------------------------------------------------------------------------------
int iRCCE_mailbox_flush(void) {
int i;
for( i=0; i<iRCCE_PRIOS; ++i ) {
iRCCE_MAIL_HEADER* erase_header = iRCCE_mailbox_recv_queue[i];
while( erase_header != NULL ) {
iRCCE_mailbox_recv_queue[i] = iRCCE_mailbox_recv_queue[i]->next;
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<RCCE_NP; ++i ) {
iRCCE_mailbox_close_one( i, 1 );
}
}
else {
iRCCE_mailbox_close_one( rank, 1 );
}
return iRCCE_SUCCESS;
}
#endif