// semlib.c #include <912d60.h> #include "kernel.h" #include "semlib.h" // GLOBAL VARIABLES extern unsigned int current; // current task id number // task control block extern struct task_block { void (*address)(); // Address of the task unsigned char id; // ID of task char name[9]; // Name enum task_state state; // State unsigned char priority; // Priority unsigned int period_tick; // for determining if deadline is up unsigned int interrupt_msg_box; // flags for pending interrupts enum message_box message; // misc flags unsigned char message_data[2]; // data for misc_msg_box flags unsigned char *heap_ptr; // heap addr while not current task unsigned int heap_size; // heap size unsigned char *frame_ptr; // CCR pointer }; // resource control block extern struct resource_block { unsigned char id; // ID of resource char name[5]; // Name of resource enum resource_state state; // State (busy, free...) unsigned char owner; // Current resource owner signed char queue[3]; // Tasks waiting on resource unsigned char queue_ptr; // Next free spot in queue }; extern struct task_block *task[NUMTASKS]; extern struct resource_block resource[NUMRESOURCES]; extern char error_msg[8][25]; extern char error_src[5][18]; int sem_get(char rid) { /* Gives a resource to a requesting task. returns the resource id number (0,1,2,...) if free. otherwise returns -1. At this point, semaphores are a procedural control that the tasks have to follow to avoid resource contention. There is no kernel control over resources yet. */ // critical section INTR_OFF(); // GET SEMAPHORE // give semaphore to task if (resource[rid].state == NOTBUSY) { resource[rid].state = BUSY; resource[rid].owner = current; INTR_ON(); return rid; } // resource is taken/busy so make task wait else { task[current]->message |= STATE_FLAG; task[current]->message_data[STATE_BOX] = WAITING; // put waiting task into the resources queue if there's space if (resource[rid].queue_ptr < 3) { resource[rid].queue[resource[rid].queue_ptr] = current; resource[rid].queue_ptr++; } INTR_ON(); return -1; } } int sem_give(char rid) { /* Takes a resource back from a task. will (eventually) pass a message to a waiting task. At this point, semaphores are a procedural control that the tasks have to follow to avoid resource contention. There is no kernel control over resources yet. */ // critical section INTR_OFF(); // return the resource resource[rid].state = NOTBUSY; INTR_ON(); return 0; }