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_core_spu.h"
00009
00010 #define IMOC_BARRIER_TAG 1
00011
00012 int MOC_Barrier(MOC_Comm comm)
00013 {
00014 moc_message_envelope_t tempQueue[node_handle.queue_size] __attribute__((__aligned__(16)));
00015 moc_message_envelope_t *sourceQueueEntry;
00016 MOC_Status status;
00017 unsigned int tag_id;
00018 int err, qindex;
00019
00020 if (comm == MOC_COMM_SELF)
00021 return 0;
00022
00023 if (node_handle.rank == node_handle.comm_size - 1)
00024 {
00025 int t;
00026 for (t = 0; t < node_handle.comm_size - 1; t++)
00027 {
00028
00029 sourceQueueEntry = 0;
00030 while (sourceQueueEntry == 0)
00031 {
00032 sourceQueueEntry = IMOC_get_entry(t, IMOC_BARRIER_TAG, comm, 1,
00033 &status);
00034 }
00035 sourceQueueEntry->flags.value = 0;
00036 }
00037 for (t = 0; t < node_handle.comm_size - 1; t++)
00038 {
00039
00040 if ((tag_id = mfc_tag_reserve()) == MFC_TAG_INVALID)
00041 return MOC_ERR_INTERN;
00042 mfc_get(tempQueue, IMOC_EA_REMOTE_QUEUE(t), node_handle.queue_size
00043 * sizeof(moc_message_envelope_t), tag_id, 0, 0);
00044 mfc_write_tag_mask(1 << tag_id);
00045 mfc_read_tag_status_all();
00046 mfc_tag_release(tag_id);
00047
00048
00049 err = IMOC_getFreeEntry(tempQueue, IMOC_BARRIER_TAG, comm, 1,
00050 &qindex);
00051 if (err)
00052 return err;
00053
00054 tempQueue[qindex].communicator = comm;
00055 tempQueue[qindex].flags.bits.special = 1;
00056 tempQueue[qindex].flags.bits.valid = 1;
00057 tempQueue[qindex].tag = IMOC_BARRIER_TAG;
00058
00059
00060 if ((tag_id = mfc_tag_reserve()) == MFC_TAG_INVALID)
00061 return MOC_ERR_INTERN;
00062 mfc_put(&tempQueue[qindex], IMOC_EA_REMOTE_QUEUE_ENTRY(t, qindex),
00063 sizeof(moc_message_envelope_t), tag_id, 0, 0);
00064 mfc_write_tag_mask(1 << tag_id);
00065 mfc_read_tag_status_all();
00066 mfc_tag_release(tag_id);
00067 }
00068 }
00069 else
00070 {
00071
00072 if ((tag_id = mfc_tag_reserve()) == MFC_TAG_INVALID)
00073 return MOC_ERR_INTERN;
00074 mfc_get(tempQueue, IMOC_EA_REMOTE_QUEUE(node_handle.comm_size - 1),
00075 node_handle.queue_size * sizeof(moc_message_envelope_t),
00076 tag_id, 0, 0);
00077 mfc_write_tag_mask(1 << tag_id);
00078 mfc_read_tag_status_all();
00079 mfc_tag_release(tag_id);
00080
00081
00082 err = IMOC_getFreeEntry(tempQueue, IMOC_BARRIER_TAG, comm, 1, &qindex);
00083 if (err)
00084 return err;
00085
00086 tempQueue[qindex].communicator = comm;
00087 tempQueue[qindex].flags.bits.special = 1;
00088 tempQueue[qindex].flags.bits.valid = 1;
00089 tempQueue[qindex].tag = IMOC_BARRIER_TAG;
00090
00091
00092 if ((tag_id = mfc_tag_reserve()) == MFC_TAG_INVALID)
00093 return MOC_ERR_INTERN;
00094 mfc_put(&tempQueue[qindex],
00095 IMOC_EA_REMOTE_QUEUE_ENTRY(node_handle.comm_size - 1, qindex),
00096 sizeof(moc_message_envelope_t), tag_id, 0, 0);
00097 mfc_write_tag_mask(1 << tag_id);
00098 mfc_read_tag_status_all();
00099 mfc_tag_release(tag_id);
00100
00101
00102 sourceQueueEntry = 0;
00103 while (sourceQueueEntry == 0)
00104 {
00105 sourceQueueEntry = IMOC_get_entry(node_handle.comm_size - 1,
00106 IMOC_BARRIER_TAG, comm, 1, &status);
00107 }
00108 sourceQueueEntry->flags.value = 0;
00109 }
00110
00111 return 0;
00112 }
00113