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