00001 #include <stdio.h>
00002 #include <string.h>
00003
00004 #include <moc.h>
00005 #include <internal/imoc.h>
00006 #include <internal/ppu/imoc_macros_ppu.h>
00007 #include <internal/ppu/imoc_dma_ppu.h>
00008 #include <internal/ppu/imoc_core_ppu.h>
00009
00010 int MOC_Bsend(void* buf, int count, MOC_Datatype datatype, int dest, int tag,
00011 MOC_Comm comm)
00012 {
00013 moc_message_envelope_t tempQueue[node_handle.queue_size] __attribute__((__aligned__(16)));
00014 int err, qindex, mid, bytecount;
00015 unsigned int dmastatus;
00016 void* ea_buffer;
00017
00018 if (((datatype & 0xF0) >> 4) == 0)
00019 bytecount = count;
00020 else
00021 bytecount = count * (((datatype & 0xF0) >> 4) * 2);
00022
00023 IMOC_TEST_PROC_NULL(dest)
00024 IMOC_TEST_PROC_SELF(dest)
00025 IMOC_TEST_BYTECOUNT(bytecount)
00026
00027 if (bytecount != 0)
00028 {
00029 IMOC_TEST_BUFFER(buf)
00030 }
00031 IMOC_TEST_RANK(dest)
00032 IMOC_TEST_TAG_SEND(tag)
00033 IMOC_TEST_COMM_SEND(comm)
00034
00035
00036 if (node_handle.queue_size * sizeof(moc_message_envelope_t)
00037 > MEMCPY_GET_TRESHOLD)
00038 {
00039 err = spe_mfcio_put(
00040 moc_spu_thread_list[dest - moc_ppu_thread_count].speid,
00041 IMOC_LS_REMOTE_QUEUE(dest), tempQueue, node_handle.queue_size
00042 * sizeof(moc_message_envelope_t), 15, 0, 0);
00043 if (err)
00044 return MOC_ERR_INTERN;
00045 err = spe_mfcio_tag_status_read(moc_spu_thread_list[dest
00046 - moc_ppu_thread_count].speid, 0, SPE_TAG_ALL, &dmastatus);
00047 if (err)
00048 return MOC_ERR_INTERN;
00049 }
00050 else
00051 {
00052 memcpy(tempQueue, (void*) IMOC_EA_REMOTE_QUEUE(dest),
00053 node_handle.queue_size * sizeof(moc_message_envelope_t));
00054 }
00055
00056
00057 err = IMOC_getFreeEntry(tempQueue, tag, comm, 0, &qindex);
00058 if (err)
00059 return err;
00060
00061
00062
00063 if (bytecount <= 8)
00064 {
00065 tempQueue[qindex].flags.bits.channel = IMOC_MESSAGE_CHANNEL_ENV;
00066 tempQueue[qindex].flags.bits.signal_back = 0;
00067 tempQueue[qindex].flags.bits.in_mm = 0;
00068 memcpy(&tempQueue[qindex].message_address, buf, bytecount);
00069 }
00070 else
00071 {
00072 IMOC_TEST_ALIGNMENT(buf)
00073
00074 err = IMOC_getFreeMID(&mid);
00075 if (err)
00076 return err;
00077
00078
00079 ea_buffer = (void*) IMOC_bmalloc(bytecount, mid);
00080 if (!ea_buffer)
00081 return MOC_ERR_NO_BUFFER;
00082
00083 tempQueue[qindex].flags.bits.channel = IMOC_MESSAGE_CHANNEL_DMA;
00084 tempQueue[qindex].flags.bits.signal_back = 1;
00085 tempQueue[qindex].flags.bits.in_mm = 1;
00086 tempQueue[qindex].message_address = (uint64_t) ea_buffer;
00087
00088 memcpy(ea_buffer, buf, bytecount);
00089
00090
00091 node_handle.status_array_base[mid].flags.bits.valid = 1;
00092 node_handle.status_array_base[mid].flags.bits.outstanding = 1;
00093 }
00094
00095
00096 tempQueue[qindex].communicator = comm;
00097 tempQueue[qindex].datatype = datatype;
00098 tempQueue[qindex].id = mid;
00099 tempQueue[qindex].size = bytecount;
00100 tempQueue[qindex].tag = tag;
00101 tempQueue[qindex].flags.bits.collaborative = 0;
00102 tempQueue[qindex].flags.bits.special = 0;
00103 tempQueue[qindex].flags.bits.valid = 1;
00104 tempQueue[qindex].flags.bits.keep_valid = 0;
00105
00106
00107
00108 memcpy((void*) IMOC_EA_REMOTE_QUEUE_ENTRY(dest, qindex),
00109 &tempQueue[qindex], sizeof(moc_message_envelope_t));
00110
00111 return 0;
00112 }
00113