anylength support in isend

This commit is contained in:
Simon Pickartz 2011-05-31 10:48:28 +02:00
parent 75ed99db86
commit b05400348a
3 changed files with 140 additions and 36 deletions

View file

@ -1,4 +1,4 @@
C_source := icc.c SCC_API.c iRCCE_admin.c iRCCE_send.c iRCCE_isend.c iRCCE_irecv.c iRCCE_recv.c iRCCE_get.c iRCCE_put.c iRCCE_synch.c RCCE_malloc.c RCCE_shmalloc.c RCCE_debug.c RCCE_qsort.c RCCE_DCMflush.c RCCE_send.c RCCE_recv.c RCCE_flags.c RCCE_comm.c RCCE_put.c RCCE_get.c RCCE_synch.c RCCE_bcast.c RCCE_admin.c # RCCE_power_management.c
C_source := icc.c SCC_API.c iRCCE_admin.c iRCCE_mailbox.c iRCCE_send.c iRCCE_isend.c iRCCE_irecv.c iRCCE_recv.c iRCCE_get.c iRCCE_put.c iRCCE_synch.c RCCE_malloc.c RCCE_shmalloc.c RCCE_debug.c RCCE_qsort.c RCCE_DCMflush.c RCCE_send.c RCCE_recv.c RCCE_flags.c RCCE_comm.c RCCE_put.c RCCE_get.c RCCE_synch.c RCCE_bcast.c RCCE_admin.c # RCCE_power_management.c
ASM_source :=
MODULE := arch_x86_scc

View file

@ -47,6 +47,27 @@ 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
//--------------------------------------------------------------------------------------
@ -56,10 +77,34 @@ int iRCCE_init(void) {
int i;
for(i=0; i<RCCE_MAXNP; i++) {
iRCCE_irecv_queue[i] = NULL;
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);
}

View file

@ -1,12 +1,12 @@
//***************************************************************************************
//******************************************************************************
// Non-blocking send routines.
//***************************************************************************************
//******************************************************************************
//
// Author: Rob F. Van der Wijngaart
// Intel Corporation
// Date: 008/30/2010
//
//***************************************************************************************
//******************************************************************************
//
// Copyright 2010 Intel Corporation
//
@ -158,56 +158,115 @@ static void iRCCE_init_send_request(
}
//--------------------------------------------------------------------------------------
// FUNCTION: iRCCE_isend
// FUNCTION: iRCCE_isend_general
//--------------------------------------------------------------------------------------
// non-blocking send function; returns a handle of type iRCCE_SEND_REQUEST
//--------------------------------------------------------------------------------------
static iRCCE_SEND_REQUEST blocking_isend_request;
int iRCCE_isend(char *privbuf, size_t size, int dest, iRCCE_SEND_REQUEST *request) {
static int iRCCE_isend_general(char *privbuf, size_t size, int dest, iRCCE_SEND_REQUEST *request) {
if(request == NULL) request = &blocking_isend_request;
if (dest<0 || dest >= RCCE_NP)
return(RCCE_error_return(RCCE_debug_comm,RCCE_ERROR_ID));
else {
iRCCE_init_send_request(privbuf, RCCE_buff_ptr, RCCE_chunk,
&RCCE_ready_flag[dest], &RCCE_sent_flag[RCCE_IAM],
size, dest, request);
if(iRCCE_isend_queue == NULL) {
iRCCE_init_send_request(privbuf, RCCE_buff_ptr, RCCE_chunk,
&RCCE_ready_flag[dest], &RCCE_sent_flag[RCCE_IAM],
size, dest, request);
if(iRCCE_push_send_request(request) == iRCCE_SUCCESS) {
return(iRCCE_SUCCESS);
}
else {
iRCCE_isend_queue = request;
if(iRCCE_isend_queue == NULL) {
if(request == &blocking_isend_request) {
iRCCE_isend_wait(request);
return(iRCCE_SUCCESS);
}
return(iRCCE_PENDING);
}
if(iRCCE_push_send_request(request) == iRCCE_SUCCESS) {
return(iRCCE_SUCCESS);
}
else {
if(iRCCE_isend_queue->next == NULL) {
iRCCE_isend_queue->next = request;
}
else {
iRCCE_SEND_REQUEST *run = iRCCE_isend_queue;
while(run->next != NULL) run = run->next;
run->next = request;
}
iRCCE_isend_queue = request;
if(request == &blocking_isend_request) {
iRCCE_isend_wait(request);
return(iRCCE_SUCCESS);
}
return(iRCCE_RESERVED);
return(iRCCE_PENDING);
}
}
else {
if(iRCCE_isend_queue->next == NULL) {
iRCCE_isend_queue->next = request;
}
else {
iRCCE_SEND_REQUEST *run = iRCCE_isend_queue;
while(run->next != NULL) run = run->next;
run->next = request;
}
if(request == &blocking_isend_request) {
iRCCE_isend_wait(request);
return(iRCCE_SUCCESS);
}
return(iRCCE_RESERVED);
}
}
//------------------------------------------------------------------------------
// FUNCTION: iRCCE_isend
//------------------------------------------------------------------------------
// wrapper function to differentiate between anylength and normal call
//------------------------------------------------------------------------------
static iRCCE_SEND_REQUEST blocking_isend_request;
int iRCCE_isend(
char *privbuf,
ssize_t size,
int dest,
iRCCE_SEND_REQUEST *request
) {
if(request == NULL) request = &blocking_isend_request;
if (dest<0 || dest >= RCCE_NP) {
return(RCCE_error_return(RCCE_debug_comm,RCCE_ERROR_ID));
}
else {
// anylength call
if( size < 0 ){
// convert size to positive range */
int send_size = -size;
// use header payload
if( send_size <= iRCCE_MAIL_HEADER_PAYLOAD ) {
iRCCE_init_send_request(privbuf, RCCE_buff_ptr,
RCCE_chunk, &RCCE_ready_flag[dest],
&RCCE_sent_flag[RCCE_IAM],
send_size, dest, request);
request->finished = 1;
iRCCE_mail_send( send_size,
iRCCE_ANYLENGTH_PIGGYBACK,
0, privbuf, dest );
return iRCCE_SUCCESS;
}
// we need an extra isend-call
else {
iRCCE_mail_send( send_size, iRCCE_ANYLENGTH,
0, NULL, dest );
return iRCCE_isend_general( privbuf, send_size,
dest, request );
}
}
// normal call
else if( size > 0 ) {
return iRCCE_isend_general( privbuf, size,
dest, request );
}
// do nothing
else {
iRCCE_init_send_request(privbuf, RCCE_buff_ptr,
RCCE_chunk, &RCCE_ready_flag[dest],
&RCCE_sent_flag[RCCE_IAM],
size, dest, request);
request->finished = 1;
return(iRCCE_SUCCESS);
}
}
}
//--------------------------------------------------------------------------------------