3 #include <mware/observer.h>
6 * Internal structure for building a priority queue
7 * of processes waiting for the resource to become free.
9 typedef struct ResourceWaiter
12 struct Observer *owner;
17 bool ResMan_Alloc(Resource *res, int pri, ResMan_time_t timeout, struct Observer *releaseRequest)
21 ASSERT(releaseRequest);
23 sem_obtain(&res->lock);
25 if (res->owner == releaseRequest)
33 // Trivial acquire: nobody was owning the resource
35 res->owner = releaseRequest;
40 ResourceWaiter waiter;
42 // Setup waiter structure and enqueue it to resource
43 waiter.owner = releaseRequest;
44 waiter.link.pri = pri;
45 LIST_ENQUEUE(&res->queue, &waiter.link);
47 // Resource busy: are we eligible for preemption?
48 if ((res->pri < pri) && res->owner->event)
49 res->owner->event(EVENT_RELEASE, res);
51 // Wait in the queue until the timeout occurs.
54 sem_release(&res->lock);
55 // TODO: use a semaphore here instead
57 sem_obtain(&res->lock);
59 // Check for ownership
60 if (res->owner == releaseRequest)
68 // Remove pending waiter
70 REMOVE(&waiter.link.link);
73 sem_release(&res->lock);
77 void ResMan_Free(Resource *res)
79 ResourceWaiter *waiter;
81 sem_obtain(&res->lock);
85 //TODO: check for real owner calling free
87 // Check for new owner candidates.
88 if ((waiter = (ResourceWaiter *)list_remHead(&res->queue)))
90 // Transfer ownership of the resource
91 res->owner = waiter->owner;
92 res->pri = waiter->link.pri;
93 //ResMan_wakeup(waiter);
97 // Nobody waiting, free the resource
102 sem_release(&res->lock);
105 void ResMan_Init(Resource *res)
110 sem_init(&res->lock);
111 LIST_INIT(&res->queue);