#include <ubixos/message.h> #include <lib/kmalloc.h> static int inited = 0; #define __MESSAGE_CONNECTION_COUNT 4 static const int connectionCount = __MESSAGE_CONNECTION_COUNT; static int messageCount = 0; static connection_t * connections; static void messageInit() { int i; if (inited) return; connections = (connection_t *) kmalloc(connectionCount * sizeof(connection_t), -1); for (i = 0; i < connectionCount; i++) { kmemset(&connections[i], '\0', sizeof(connection_t)); waitQueueInit(&connections[i].message_queue, 0); waitQueueInit(&connections[i].old_queue, 0); } inited = 1; } int connectionCreate(char * cname, uInt32 * cid, uInt8 flags) { int i; if (!inited) messageInit(); for (i = 0; i < connectionCount; i++) if (connections[i].used == 0) break; if (connections[i].used != 0) return -1; connections[i].used = 1; kstrncpy(connections[i].unique_string, cname, 256); connections[i].owning_pid = _current->id; *cid = i; return 0; } int kstrncmp(const char * a, const char * b, int c) { int i = 0; while (i < c) { if ((a[i] != b[i]) || (a[i] == '\0') || (b[i] == '\0')) return a[i] - b[i]; i++; } return 0; } int connectionOpen(char * cname, uInt32 * cid) { int i; if (!inited) messageInit(); for (i = 0; i < connectionCount; i++) if (connections[i].used == 1) if (0 == kstrncmp(connections[i].unique_string, cname, 256)) break; if (connections[i].used == 0) return -1; if (0 != kstrncmp(connections[i].unique_string, cname, 256)) return -1; *cid = i; return 0; } int messageRecv(uInt32 cid, uInt32 * sender, uInt32 * cmd, uInt32 * size, uInt8 * data) { message_t * temp = NULL; int notUsed; if (!inited) return -1; if (cid >= connectionCount) return -1; //if (connections[cid].used == 0); // return -1; if (connections[cid].owning_pid != _current->id) return -1; do { temp = waitQueueRemove(&connections[cid].message_queue, ¬Used); if (temp == NULL) { setTaskStatus_task(_current, MSGWAIT); schedule(); } } while(temp == NULL); kmemcpy(data, temp->data, temp->size); *cmd = temp->cmd; *size = temp->size; *sender = temp->send_taskId; waitQueueInsert(&connections[cid].old_queue, temp, temp->id); return temp->id; } int messageSend(uInt32 cid, uInt32 * cmd, uInt32 * size, uInt8 * data) { volatile message_t * temp; kTask_t * task; if (!inited) return -1; if (cid >= connectionCount) return -1; if (connections[cid].used == 0) return -1; temp = (message_t *) kmalloc(sizeof(message_t), -1); temp->cmd = *cmd; temp->size = *size; kmemcpy((void *) temp->data, (void *) data, *size); temp->send_taskId = _current->id; temp->id = messageCount; messageCount++; temp->flags = MSG_SEND; waitQueueInsert(&connections[cid].message_queue, (void *) temp, temp->id); task = getTask(connections[cid].owning_pid); if (task != NULL) { if (task->status == MSGWAIT) setTaskStatus_task(task, READY); } while((temp->flags & MSG_REPLY) != MSG_REPLY) { setTaskStatus_task(_current, MSGREPLY); schedule(); } *cmd = temp->cmd; *size= temp->size; kmemcpy((void *) data, (void *) temp->data, *size); kfree((void *)temp); return 0; } int messageReply(uInt32 cid, uInt32 mid, uInt32 cmd, uInt32 size, uInt8 * data) { message_t * temp = NULL; if (!inited) return -1; if (cid >= connectionCount) return -1; if (connections[cid].used == 0) return -1; temp = waitQueueFind(&connections[cid].old_queue, mid); if (temp == NULL) return -1; temp->flags |= MSG_REPLY; temp->size = size; temp->cmd = cmd; kmemcpy(temp->data, data, cmd); setTaskStatus(temp->send_taskId, READY); return 0; }