mailbox-system thread-safe now
This commit is contained in:
parent
6e14d56de8
commit
f344f65769
7 changed files with 118 additions and 40 deletions
|
@ -235,8 +235,9 @@ void irq_handler(struct state *s)
|
|||
void (*handler) (struct state * s);
|
||||
|
||||
// at first, we check our work queues
|
||||
check_workqueues();
|
||||
|
||||
if( s->int_no == 124 ) {
|
||||
check_workqueues();
|
||||
}
|
||||
/*
|
||||
* Find out if we have a custom handler to run for this
|
||||
* IRQ and then finally, run it
|
||||
|
|
|
@ -81,7 +81,7 @@ void timer_wait(unsigned int ticks)
|
|||
uint64_t eticks = timer_ticks + ticks;
|
||||
|
||||
while (timer_ticks < eticks) {
|
||||
check_workqueues();
|
||||
//check_workqueues();
|
||||
|
||||
// recheck break condition
|
||||
if (timer_ticks >= eticks)
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#ifdef CONFIG_ROCKCREEK
|
||||
#include <asm/iRCCE_lib.h>
|
||||
#include <asm/irqflags.h>
|
||||
|
||||
// forward declaration
|
||||
static int iRCCE_mailbox_close_one(int rank, int check);
|
||||
|
@ -90,7 +91,8 @@ void iRCCE_mailbox_print_header(iRCCE_MAIL_HEADER* header) {
|
|||
static int iRCCE_mail_fetch(
|
||||
int rank // rank from whom to empty mailbox
|
||||
) {
|
||||
|
||||
/* interrupts should already be disabled! */
|
||||
|
||||
iRCCE_MAIL_HEADER* header;
|
||||
|
||||
// check for memory in garbage collection or allocate new
|
||||
|
@ -160,6 +162,10 @@ static int iRCCE_mail_fetch(
|
|||
//------------------------------------------------------------------------------
|
||||
static int iRCCE_mailbox_check() {
|
||||
int i,j;
|
||||
uint32_t flags;
|
||||
|
||||
/* disable interrupts */
|
||||
flags = irq_nested_disable();
|
||||
|
||||
for( j=1; j<RCCE_NP; ++j ) {
|
||||
i = (j+RCCE_IAM)%RCCE_NP;
|
||||
|
@ -181,6 +187,8 @@ static int iRCCE_mailbox_check() {
|
|||
}
|
||||
}
|
||||
|
||||
/* enable interrupts */
|
||||
irq_nested_enable(flags);
|
||||
|
||||
return iRCCE_SUCCESS;
|
||||
}
|
||||
|
@ -206,6 +214,7 @@ int iRCCE_mail_recv(
|
|||
) { // (memory allocated by iRCCE)
|
||||
|
||||
int i;
|
||||
uint32_t flags;
|
||||
iRCCE_MAIL_HEADER* help_header;
|
||||
|
||||
// if there is no mail, check for incoming
|
||||
|
@ -216,6 +225,10 @@ int iRCCE_mail_recv(
|
|||
// check priority queues
|
||||
for( i=0; i<iRCCE_PRIOS; ++i ) {
|
||||
if ( iRCCE_mailbox_recv_queue[i].first ) {
|
||||
/* disable interrupts */
|
||||
flags = irq_nested_disable();
|
||||
|
||||
|
||||
help_header = iRCCE_mailbox_recv_queue[i].first;
|
||||
|
||||
iRCCE_mailbox_recv_queue[i].first =
|
||||
|
@ -228,7 +241,12 @@ int iRCCE_mail_recv(
|
|||
help_header->next = NULL;
|
||||
|
||||
*header = help_header;
|
||||
|
||||
/* enable interrupts */
|
||||
irq_nested_enable(flags);
|
||||
|
||||
return iRCCE_SUCCESS;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,6 +273,11 @@ int iRCCE_mail_recv(
|
|||
int iRCCE_mail_release(
|
||||
iRCCE_MAIL_HEADER** header
|
||||
) {
|
||||
uint32_t flags;
|
||||
|
||||
/* disable interrupts */
|
||||
flags = irq_nested_disable();
|
||||
|
||||
// put header in garbage collection
|
||||
if( (iRCCE_mail_garbage.first == NULL)
|
||||
&& (iRCCE_mail_garbage.last == NULL ) ) {
|
||||
|
@ -270,6 +293,10 @@ int iRCCE_mail_release(
|
|||
|
||||
// reset header
|
||||
*header = NULL;
|
||||
|
||||
/* enable interrupts */
|
||||
irq_nested_enable(flags);
|
||||
|
||||
return iRCCE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -309,6 +336,7 @@ int iRCCE_mail_send(
|
|||
char* payload, // pointer to buffer for header payload
|
||||
int dest // UE that will receive the header
|
||||
) {
|
||||
uint32_t flags;
|
||||
|
||||
// check for an attempt to send in own mailbox
|
||||
if( dest == RCCE_IAM ) {
|
||||
|
@ -344,6 +372,9 @@ int iRCCE_mail_send(
|
|||
RC_cache_invalidate();
|
||||
iRCCE_memcpy_put( (void*)iRCCE_mailbox_send[dest],
|
||||
(void*)&header, RCCE_LINE_SIZE );
|
||||
|
||||
/* disable interrupts */
|
||||
flags = irq_nested_disable();
|
||||
|
||||
// set senders flag
|
||||
RC_cache_invalidate();
|
||||
|
@ -351,6 +382,9 @@ int iRCCE_mail_send(
|
|||
*(int *)RCCE_fool_write_combine_buffer = 1;
|
||||
RC_cache_invalidate();
|
||||
|
||||
/* enable interrupts */
|
||||
irq_nested_enable(flags);
|
||||
|
||||
RCCE_release_lock( dest );
|
||||
|
||||
return iRCCE_SUCCESS;
|
||||
|
@ -417,17 +451,24 @@ int iRCCE_mailbox_wait(void) {
|
|||
//------------------------------------------------------------------------------
|
||||
int iRCCE_mailbox_flush(void) {
|
||||
int i;
|
||||
uint32_t flags;
|
||||
|
||||
for( i=0; i<iRCCE_PRIOS; ++i ) {
|
||||
iRCCE_MAIL_HEADER* erase_header =
|
||||
iRCCE_mailbox_recv_queue[i].first;
|
||||
|
||||
|
||||
/* disable interrupts */
|
||||
flags = irq_nested_disable();
|
||||
|
||||
while( erase_header != NULL ) {
|
||||
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].first;
|
||||
}
|
||||
|
||||
/* enable interrupts */
|
||||
irq_nested_enable(flags);
|
||||
}
|
||||
return iRCCE_SUCCESS;
|
||||
}
|
||||
|
@ -449,11 +490,16 @@ int iRCCE_mailbox_flush(void) {
|
|||
*/
|
||||
//------------------------------------------------------------------------------
|
||||
static int iRCCE_mailbox_close_one(int rank, int check) {
|
||||
uint32_t flags;
|
||||
RCCE_acquire_lock( RCCE_IAM );
|
||||
|
||||
/* disable interrupts */
|
||||
flags = irq_nested_disable();
|
||||
|
||||
// check if it contains new mail
|
||||
RC_cache_invalidate();
|
||||
if( check && iRCCE_mailbox_recv[rank]->sent ) {
|
||||
|
||||
iRCCE_mail_fetch(rank);
|
||||
|
||||
}
|
||||
|
@ -465,10 +511,14 @@ static int iRCCE_mailbox_close_one(int rank, int check) {
|
|||
RC_cache_invalidate();
|
||||
iRCCE_memcpy_put( (void*)iRCCE_mailbox_recv[rank],
|
||||
&help_header, RCCE_LINE_SIZE );
|
||||
|
||||
iRCCE_mailbox_status[rank] = iRCCE_MAILBOX_CLOSED;
|
||||
|
||||
/* enable interrupts */
|
||||
irq_nested_enable(flags);
|
||||
|
||||
RCCE_release_lock( RCCE_IAM );
|
||||
|
||||
iRCCE_mailbox_status[rank] = iRCCE_MAILBOX_CLOSED;
|
||||
|
||||
return iRCCE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -189,22 +189,15 @@ int icc_send_irq(int ue)
|
|||
|
||||
int icc_halt(void)
|
||||
{
|
||||
uint32_t flags;
|
||||
uint32_t do_send = 1;
|
||||
|
||||
// iRCCE is not thread save => disable interrupts
|
||||
flags = irq_nested_disable();
|
||||
|
||||
icc_mail_check();
|
||||
|
||||
irq_nested_enable(flags);
|
||||
|
||||
HALT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ROUNDS 10000
|
||||
#define ROUNDS 300000
|
||||
#define CORE_A 1 // sender
|
||||
#define CORE_B 9 // receiver
|
||||
|
||||
static inline void icc_mail_check_tag(iRCCE_MAIL_HEADER* mail) {
|
||||
char* recv_buffer;
|
||||
|
@ -231,36 +224,62 @@ int icc_mail_ping( void )
|
|||
{
|
||||
uint32_t flags;
|
||||
uint64_t timer = 0;
|
||||
int rem_rank = (my_ue+1)%2;
|
||||
int i;
|
||||
int res;
|
||||
iRCCE_MAIL_HEADER* recv_header = NULL;
|
||||
|
||||
/* leave function if not participating in pingpong */
|
||||
if( (my_ue != CORE_A) && (my_ue != CORE_B) ) return -1;
|
||||
|
||||
kprintf( "my_ue = %d\n", my_ue );
|
||||
kprintf( "Hello from mail_ping ... \n" );
|
||||
|
||||
kprintf( "rounds = %d\n", ROUNDS );
|
||||
|
||||
|
||||
/* wait 10 sec */
|
||||
timer = rdtsc();
|
||||
while( (rdtsc() - timer) < 533e8 ) {
|
||||
kprintf( "waiting ...\n" );
|
||||
}
|
||||
|
||||
kprintf( "waited ..\n" );
|
||||
|
||||
// disable interrupts
|
||||
flags = irq_nested_disable();
|
||||
|
||||
for( i=0; i<ROUNDS+1; ++i ) {
|
||||
if( my_ue == 0 ) {
|
||||
/* senders part */
|
||||
if( my_ue == CORE_A ) {
|
||||
/* send ping request */
|
||||
iRCCE_mail_send(0, PING_REQ, 0, NULL, rem_rank);
|
||||
iRCCE_mail_send(0, PING_REQ, 0, NULL, CORE_B);
|
||||
|
||||
/* wait for response */
|
||||
do {
|
||||
iRCCE_mail_recv(&recv_header);
|
||||
} while( !recv_header );
|
||||
res = iRCCE_mail_recv(&recv_header);
|
||||
if( res == iRCCE_SUCCESS ) {
|
||||
if( recv_header->source == CORE_B )
|
||||
break;
|
||||
iRCCE_mail_release(&recv_header);
|
||||
}
|
||||
} while( 1 );
|
||||
|
||||
/* release mail */
|
||||
iRCCE_mail_release(&recv_header);
|
||||
}
|
||||
/* receivers part */
|
||||
else {
|
||||
/* wait for request */
|
||||
do {
|
||||
iRCCE_mail_recv(&recv_header);
|
||||
res = iRCCE_mail_recv(&recv_header);
|
||||
if( res == iRCCE_SUCCESS ) {
|
||||
if( recv_header->tag == PING_REQ )
|
||||
break;
|
||||
iRCCE_mail_release(&recv_header);
|
||||
}
|
||||
} while( (!recv_header));
|
||||
|
||||
/* send response */
|
||||
iRCCE_mail_send(0, PING_RESP, 0, NULL, rem_rank);
|
||||
iRCCE_mail_send(0, PING_RESP, 0, NULL, recv_header->source);
|
||||
|
||||
/* release mail */
|
||||
iRCCE_mail_release(&recv_header);
|
||||
|
@ -275,10 +294,10 @@ int icc_mail_ping( void )
|
|||
timer = rdtsc() - timer;
|
||||
|
||||
|
||||
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) );
|
||||
if( my_ue == CORE_A ) {
|
||||
kprintf( "timer = %ld\n", timer );
|
||||
kprintf( "mail_pingpong needs in average %d msec (%d ticks)!\n",
|
||||
timer/(2*ROUNDS*533), timer/(2*ROUNDS) );
|
||||
}
|
||||
|
||||
irq_nested_enable(flags);
|
||||
|
@ -287,8 +306,6 @@ int icc_mail_ping( void )
|
|||
}
|
||||
|
||||
|
||||
#define CORE_A 0 // sender
|
||||
#define CORE_B 1 // receiver
|
||||
int icc_mail_ping_irq( void )
|
||||
{
|
||||
/* return if not core 0 */
|
||||
|
@ -304,6 +321,7 @@ int icc_mail_ping_irq( void )
|
|||
kprintf( "Hello from mail_ping_irq ... \n" );
|
||||
kprintf( "my_rank = %d\n", my_ue );
|
||||
kprintf( "rem_rank = %d\n", rem_rank );
|
||||
kprintf( "rounds = %d\n", ROUNDS );
|
||||
// disable interrupts
|
||||
flags = irq_nested_disable();
|
||||
|
||||
|
@ -337,7 +355,7 @@ int icc_mail_ping_irq( void )
|
|||
timer = rdtsc() - timer;
|
||||
|
||||
kprintf( "timer = %ld\n", timer );
|
||||
kprintf( "mail_pingpong needs in average %d µsec (%d ticks)!\n",
|
||||
kprintf( "mail_pingpong needs in average %d msec (%d ticks)!\n",
|
||||
timer/(2*ROUNDS*533), timer/(2*ROUNDS) );
|
||||
|
||||
|
||||
|
@ -357,22 +375,26 @@ int icc_mail_noise() {
|
|||
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;
|
||||
}
|
||||
|
||||
kprintf( "Hello from icc_mail_noise: my_ue = %d\n", my_ue );
|
||||
|
||||
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, 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 */
|
||||
|
@ -380,6 +402,11 @@ int icc_mail_noise() {
|
|||
icc_mail_check_tag(recv_mail);
|
||||
iRCCE_mail_release(&recv_mail);
|
||||
}
|
||||
|
||||
// irq_nested_enable(flags);
|
||||
// NOP8;
|
||||
// NOP8;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -118,7 +118,7 @@ int main(void)
|
|||
|
||||
while(1) {
|
||||
#ifdef CONFIG_ROCKCREEK
|
||||
icc_halt();
|
||||
//icc_halt();
|
||||
#else
|
||||
HALT;
|
||||
#endif
|
||||
|
|
|
@ -70,7 +70,7 @@ int syscall_handler(uint32_t sys_nr, ...)
|
|||
int ret = -EINVAL;
|
||||
va_list vl;
|
||||
|
||||
check_workqueues();
|
||||
// check_workqueues();
|
||||
|
||||
va_start(vl, sys_nr);
|
||||
|
||||
|
|
|
@ -88,8 +88,8 @@ static int STDCALL foo(void* arg)
|
|||
|
||||
#ifdef CONFIG_ROCKCREEK
|
||||
int STDCALL mail_ping(void* arg) {
|
||||
//icc_mail_ping();
|
||||
icc_mail_ping_irq();
|
||||
icc_mail_ping();
|
||||
//icc_mail_ping_irq();
|
||||
icc_halt();
|
||||
|
||||
return 0;
|
||||
|
@ -133,12 +133,12 @@ int test_init(void)
|
|||
ping_send_now();
|
||||
#endif
|
||||
|
||||
create_kernel_task(NULL, foo, "Hello from foo1\n");
|
||||
//create_kernel_task(NULL, foo, "Hello from foo1\n");
|
||||
//create_kernel_task(NULL, join_test, NULL);
|
||||
//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_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);
|
||||
|
|
Loading…
Add table
Reference in a new issue