mailbox does not support sendings to own mailbox

This commit is contained in:
Simon Pickartz 2011-07-18 01:14:18 -07:00
parent ac840a835a
commit 6e14d56de8
5 changed files with 96 additions and 81 deletions

View file

@ -45,6 +45,7 @@
#define iRCCE_MAILBOX_ALL -4
#define iRCCE_MAILBOX_OPEN 0
#define iRCCE_MAILBOX_CLOSED 1
#define iRCCE_MAILBOX_INVALID -1
// iRCCE-mailbox-system tags
#define iRCCE_LAST_MAIL -1

View file

@ -233,11 +233,9 @@ void irq_handler(struct state *s)
{
/* This is a blank function pointer */
void (*handler) (struct state * s);
// at first, we check our work queues
// if( s->int_no == 124 ) {
check_workqueues();
// }
check_workqueues();
/*
* Find out if we have a custom handler to run for this

View file

@ -24,10 +24,6 @@
// limitations under the License.
//
//
#include "iRCCE_lib.h"
#include <stdlib.h>
#include <string.h>
#include <time.h>
/**
*
@ -60,7 +56,7 @@ static int iRCCE_mailbox_close_one(int rank, int check);
void iRCCE_mailbox_print_header(iRCCE_MAIL_HEADER* header) {
printf( "\n"
kprintf( "\n"
"-------------------------\n"
"| RCK%d\n"
"-------------------------\n"
@ -185,6 +181,7 @@ static int iRCCE_mailbox_check() {
}
}
return iRCCE_SUCCESS;
}
@ -210,7 +207,7 @@ int iRCCE_mail_recv(
int i;
iRCCE_MAIL_HEADER* help_header;
// if there is no mail, check for incoming
if ( !iRCCE_mailbox_recv_queue[0].first ) {
iRCCE_mailbox_check();
@ -237,6 +234,7 @@ int iRCCE_mail_recv(
// no mail queued
*header = NULL;
return iRCCE_MAILBOX_EMPTY;
}
@ -312,6 +310,11 @@ int iRCCE_mail_send(
int dest // UE that will receive the header
) {
// check for an attempt to send in own mailbox
if( dest == RCCE_IAM ) {
return iRCCE_MAILBOX_INVALID;
}
// if dest mailbox is full, check for incoming mail
RC_cache_invalidate();
while( iRCCE_mailbox_send[dest]->sent ) {

View file

@ -192,25 +192,40 @@ int icc_halt(void)
uint32_t flags;
uint32_t do_send = 1;
do {
// iRCCE is not thread save => disable interrupts
flags = irq_nested_disable();
// iRCCE is not thread save => disable interrupts
flags = irq_nested_disable();
if (do_send) {
do_send = (iRCCE_isend_push() == iRCCE_PENDING);
iRCCE_irecv_push();
}
icc_mail_check();
icc_mail_check();
irq_nested_enable(flags);
} while(do_send);
irq_nested_enable(flags);
HALT;
return 0;
}
#define ROUNDS 100000
#define ROUNDS 10000
static inline void icc_mail_check_tag(iRCCE_MAIL_HEADER* mail) {
char* recv_buffer;
switch( mail->tag ) {
case iRCCE_ANYLENGTH:
recv_buffer = (char*)kmalloc( mail->size );
iRCCE_irecv(recv_buffer, mail->size,
mail->source, NULL );
break;
case PING_REQ:
iRCCE_mail_send(0, PING_RESP, 0, NULL, mail->source);
break;
default:
break;
}
}
int icc_mail_ping( void )
{
@ -271,11 +286,9 @@ int icc_mail_ping( void )
return 0;
}
#define CORE_A 0 // sender
#define CORE_B RCCE_num_ues()-1 // receiver
#define NOISE_ROUNDS 1000000
#define CORE_B 1 // receiver
int icc_mail_ping_irq( void )
{
/* return if not core 0 */
@ -285,34 +298,36 @@ int icc_mail_ping_irq( void )
uint64_t timer = 0;
int rem_rank = CORE_B;
int i;
int res;
iRCCE_MAIL_HEADER* recv_header = NULL;
kprintf( "Hello from mail_ping_irq ... \n" );
kprintf( "my_rank = %d\n", my_ue );
kprintf( "rem_rank = %d\n", rem_rank );
// disable interrupts
flags = irq_nested_disable();
for( i=0; i<ROUNDS+1; ++i ) {
if( my_ue == 0 ) {
/* send ping request */
iRCCE_mail_send(0, PING_REQ, 0, NULL, rem_rank);
/* send ping request */
iRCCE_mail_send(0, PING_REQ, 0, NULL, rem_rank);
/* send interrupt */
NOP8;
icc_send_irq(rem_rank);
/* wait for response */
do {
iRCCE_mail_recv(&recv_header);
if( recv_header->tag == PING_RESP )
/* send interrupt */
icc_send_irq(rem_rank);
/* wait for response */
do {
res = iRCCE_mail_recv(&recv_header);
if( res == iRCCE_SUCCESS ) {
if( (recv_header->source == rem_rank)
&& (recv_header->tag == PING_RESP) )
break;
} while( 1 );
iRCCE_mail_release(&recv_header);
}
} while( 1 );
/* release mail */
iRCCE_mail_release(&recv_header);
/* release mail */
iRCCE_mail_release(&recv_header);
}
/* start timer in first round */
if( i == 0 ) timer = rdtsc();
@ -321,40 +336,52 @@ int icc_mail_ping_irq( void )
/* stop timer */
timer = rdtsc() - timer;
kprintf( "timer = %ld\n", timer );
kprintf( "mail_pingpong needs in average %d µsec (%d ticks)!\n",
timer/(2*ROUNDS*533), timer/(2*ROUNDS) );
kprintf( "timer = %d\n", timer );
if( my_ue == 0 ) {
kprintf( "mail_pingpong needs in average %f µsec (%d ticks)!\n",
timer/(2.0*ROUNDS*533), timer/(2*ROUNDS) );
/* recv noise mails */
while(1) {
iRCCE_mail_recv(&recv_header);
if(recv_header) iRCCE_mail_release(&recv_header);
}
irq_nested_enable(flags);
return 0;
}
int icc_mail_noise() {
int i, j;
int j, res;
int num_ranks = RCCE_num_ues();
iRCCE_MAIL_HEADER* recv_mail = NULL;
kprintf( "Hello from icc_mail_noise: my_ue = %d\n", my_ue );
// leave function if not participating
if( (my_ue == CORE_A) || (my_ue == CORE_B) ) {
if( (my_ue == CORE_A) /*|| (my_ue == CORE_B)*/) {
return -1;
}
}
for( i=0; i<NOISE_ROUNDS; ++i ) {
for( ;; ) {
/* send a mail to each UE */
for( j=0; j<num_ranks; ++j ) {
if ( (j == CORE_A) || (j == CORE_B) ) continue;
iRCCE_mail_send(0, my_ue*NOISE_ROUNDS+j, 0, NULL, j);
iRCCE_mail_recv(&recv_mail);
if( recv_mail ) iRCCE_mail_release(&recv_mail);
iRCCE_mail_send(0, 100, 1, NULL, j);
res = iRCCE_mail_recv(&recv_mail);
if( res == iRCCE_SUCCESS ) {
icc_mail_check_tag(recv_mail);
iRCCE_mail_release(&recv_mail);
}
}
/* read some mails */
for( res = iRCCE_mail_recv(&recv_mail), j=0; (res == iRCCE_SUCCESS) && (j<48); res = iRCCE_mail_recv(&recv_mail), ++j ) {
icc_mail_check_tag(recv_mail);
iRCCE_mail_release(&recv_mail);
}
}
iRCCE_mailbox_close(iRCCE_MAILBOX_ALL);
return 0;
}
@ -362,28 +389,8 @@ void icc_mail_check(void)
{
iRCCE_MAIL_HEADER* header = NULL;
int res;
char* recv_buffer;
// empty mailbox and interpret headers
while( (res = iRCCE_mail_recv( &header )) == iRCCE_SUCCESS ) {
switch( header->tag ) {
case iRCCE_ANYLENGTH:
recv_buffer = (char*)kmalloc( header->size );
iRCCE_irecv(recv_buffer, header->size,
header->source, NULL );
iRCCE_mail_send(0, 2, 0, NULL, header->source);
break;
case iRCCE_ANYLENGTH_PIGGYBACK:
iRCCE_mail_send(0, 2, 0, NULL, header->source);
break;
case PING_REQ:
iRCCE_mail_send(0, PING_RESP, 0, NULL, header->source);
break;
}
while( (res = iRCCE_mail_recv(&header)) == iRCCE_SUCCESS ) {
icc_mail_check_tag(header);
iRCCE_mail_release( &header );
}
}

View file

@ -90,11 +90,16 @@ static int STDCALL foo(void* arg)
int STDCALL mail_ping(void* arg) {
//icc_mail_ping();
icc_mail_ping_irq();
//icc_mail_noise(); // generate noise in the mesh
icc_halt();
return 0;
}
int STDCALL mail_noise(void*arg) {
icc_mail_noise(); // generate noise in the mesh
return 0;
}
#endif
static int STDCALL join_test(void* arg)
@ -133,6 +138,7 @@ int test_init(void)
//create_kernel_task(NULL, producer, NULL);
//create_kernel_task(NULL, consumer, NULL);
create_kernel_task(NULL, mail_ping, NULL);
create_kernel_task(NULL, mail_noise, NULL);
//create_user_task(NULL, "/bin/hello", argv);
//create_user_task(NULL, "/bin/tests", argv);
//create_user_task(NULL, "/bin/jacobi", argv);