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