/* TCRSC.C - TCtask - Resource handling routines. V1.1 T.Wagner V1.2 TECON Ltd. */ #include #include "tsk.h" #include "tclocal.h" /* create resource - initialise resource. */ resourceptr create_resource (resourceptr rsc #if (TSK_NAMEPAR) ,charptr name #endif ) { #if (TSK_DYNAMIC) if (rsc == NULL) { if ((rsc = tsk_alloc (sizeof (resource))) == NULL) return NULL; rsc->flags = F_TEMP; } else rsc->flags = 0; #endif rsc->waiting = NULL; rsc->state = 1; rsc->owner = NULL; #if (TSK_NAMED) tsk_add_name (&rsc->name, name, TYP_RESOURCE, rsc); #endif return rsc; } /* delete_resource - Kill all tasks waiting for the resource. */ void delete_resource (resourceptr rsc) { CRITICAL; C_ENTER; tsk_kill_queue (&(rsc->waiting)); rsc->owner = NULL; rsc->state = 0; C_LEAVE; #if (TSK_NAMED) tsk_del_name (&rsc->name); #endif #if (TSK_DYNAMIC) if (rsc->flags & F_TEMP) tsk_free (rsc); #endif } /* request_resource - Wait until resource is available. If the resource is free on entry, it is assigned to the task, and the task continues to run. If the task requesting the resource already owns it, this routine returns 0. */ word_s request_resource (resourceptr rsc, dword timeout) { CRITICAL; C_ENTER; if (rsc->state || rsc->owner == tsk_current) { rsc->state = 0; rsc->owner = tsk_current; C_LEAVE; return 0; } tsk_current->retptr = NULL; tsk_wait (&rsc->waiting, timeout); return (word_s)tsk_current->retptr; } /* c_request_resource - If the resource is free on entry, it is assigned to the task, otherwise an error status is returned. */ word_s c_request_resource (resourceptr rsc) { word_s rv; CRITICAL; C_ENTER; if (rv = rsc->state) { rsc->state = 0; rsc->owner = tsk_current; } C_LEAVE; return (rv) ? 0 : -1; } /* release_resource - Release the resource. If there are tasks waiting for the resource, it is assigned to the first waiting task, and the task is made eligible. */ void release_resource (resourceptr rsc) { tcbptr curr; CRITICAL; if (rsc->owner != tsk_current) return; C_ENTER; if ((curr = rsc->waiting) == NULL) { rsc->state = 1; rsc->owner = NULL; C_LEAVE; return; } rsc->waiting = tsk_runable (curr); rsc->owner = curr; C_LEAVE; } /* check_resource - returns 1 if the resource is available. */ word_s check_resource (resourceptr rsc) { return rsc->state; }