package csp; // circular list of messages, dummy first node public class MessageList { // used to store received messages protected class MessageEntry { // source address // DONT NEED THIS really! // int address; // first word in the buffer, the local id int message0; // the rest of the int message[]; MessageEntry next; public MessageEntry() { // this.address = address; message = null; next = null; } // constructor that splits the header public MessageEntry(int buf[], int cnt) { // address = src; message = new int[cnt-1]; System.arraycopy(buf,1,message,0,cnt-1); message0 = buf[0]; next = null; } // constructor that already has the header split public MessageEntry(int buf0, int buf[], int cnt) { // address = src; message = new int[cnt]; System.arraycopy(buf,0,message,0,cnt); message0 = buf0; next = null; } } volatile MessageEntry first; volatile MessageEntry last; public MessageList() { first = last = new MessageEntry(); first.next = first; } // adds a new entry to the end of the list private synchronized MessageEntry add(MessageEntry m) { m.next = last.next; last.next = m; last = m; return m; } // adds a new entry from elementary data // just to make synchronized part small // NOTE: Local channels can use this as a "send" method public MessageEntry add(int buf[], int cnt) { MessageEntry m = new MessageEntry(buf,cnt); return add(m); } public MessageEntry add(int buf0, int buf[], int cnt) { MessageEntry m = new MessageEntry(buf0, buf,cnt); return add(m); } // deletes an entry from the list private synchronized void del(MessageEntry m) { MessageEntry n; for(n=first; (n.next != m) && (n.next != first); n = n.next); if(n.next == first) // not found return; if(m == last) last = n; n.next = m.next; } // useful for finding exact channels! // could be sped up if the first word in the message is also stored // in a separate attribute private synchronized MessageEntry find(int id) { MessageEntry n; for(n = first.next; (n != first) && (n.message0 != id); n = n.next); if(n == first) // not found return null; return n; } // this is the actual function that should be used by channels // returns null if no message is received // returns a table of int otherwise // used for POLLING public int[] receive(int adr) { MessageEntry m = find(adr); if(m == null) { return null; // not found } del(m); return m.message; } public void print(String m) { MessageEntry n; System.out.print(m+"["); System.out.print("("+first+"@ "+first.message0+" "+first.next+")"); for(n = first.next; (n != first); n = n.next) { System.out.print("("+n+"@ "+n.message0+" "+n.next+")"); } System.out.println("]"); } }