/* mp.h message-passing library for CS 537 project 2 You are required to implement the functions declared in this file. */ #ifndef SEEN_MP_H #define SEEN_MP_H 1 /* Type and constant definitions -- you may not modify any of these! */ /* An entity may send an empty message with tag type TAG_DONE to indicate that it has completed its work. If you follow this convention, the equivalent of join(id); would be mp_recv(id, TAG_DONE); */ #define TAG_DONE 1 #define MAIN_ENTITY 0 #define ANY_SENDER -1 #define ANY_TAG -1 typedef int entity_t; /* a communicating entity */ typedef int msgtag_t; /* a message tag */ typedef struct { entity_t sender; /* the entity sending this message */ entity_t recipient; /* the entity to whom this message is addressed */ msgtag_t tag; /* the "tag" ascribed to this message */ unsigned size; /* the size of the data associated with this message */ void* payload; /* the data payload of this message, if any */ } message_t; /* a message */ /* Function declarations -- you will have to implement functions with the following behaviors; DO NOT modify the declarations */ /* mp_next_id returns the next available entity ID. The first time you call this function, it should return 1 (since 0 is the entity ID for the "main thread"); the next, it should return 2; and so on. (Hint: use a "static" variable) Note: I have provided an implementation of this function for you. */ int mp_next_id(); /* mp_new_entity takes one parameter; an entity identifier. If id corresponds to a preexisting entity, mp_new_entity does nothing and returns -1 to indicate error. Otherwise, it initializes any data structures (mailboxes, etc.) necessary for a new entity with identifier "id" to communicate with other entities, returning 0 on success. Note that the first time you call mp_new_entity, it should also construct a mailbox with id 0, for the "main thread." */ entity_t mp_new_entity(entity_t id); /* mp_create takes five parameters, corresponding to the elements of message_t and returns a newly-allocated message_t structure with the provided values filled-in. Your mp_send function should call this function. */ message_t* mp_create(entity_t sender, entity_t recipient, msgtag_t tag, unsigned size, void* payload); /* mp_send constructs a new message with the specified recipient, tag, size, and payload, and places it in the recipient's mailbox. If the recipient's mailbox is full, mp_send blocks until the message can be delivered. */ int mp_send(entity_t recipient, msgtag_t tag, unsigned size, void* payload); /* The behavior of mp_recv depends on the values of sender and tag. 1. If sender and tag are both set to "-1" (ANY_SENDER and ANY_TAG), then mp_recv will return the first available message in the caller's mailbox, removing that message from the mailbox. If there are no available messages, mp_recv will block. 2. If sender is set to some value other than ANY_SENDER, then mp_recv will return the first available message from "sender" in the caller's mailbox. If there is no such message, mp_recv will block. 3. If tag is set to some value other than ANY_TAG, then mp_recv will return the first available message with tag "tag" in the caller's mailbox. If there is no such message, mp_recv will block. 4. If both tag and sender are set, then mp_recv will return the first available message satisfying both constraints, blocking if no such message is available. */ message_t* mp_recv(entity_t sender, msgtag_t tag); /* The arguments to mp_poll are to be interpreted in the same way as those to mp_recv, but mp_poll never blocks. Rather, it returns 1 if a call to mp_recv with the same arguments WOULD NOT BLOCK, and 0 if a call to mp_recv with the same arguments WOULD BLOCK. */ int mp_poll(entity_t sender, msgtag_t tag); /* mp_new_thread should create a new thread with the given entity ID, executing the given function with the given argument. Your thread function should NOT call pthread_exit -- it should simply return. Note that I have provided an implementation of mp_new_thread for you. */ int mp_new_thread(entity_t entity_id, void * (*func)(void *), void * arg); #endif /* SEEN_MP_H */