resource.c
00001
00002 #include "resource.h"
00003 #include <mware/observer.h>
00004
00009 typedef struct ResourceWaiter
00010 {
00011 PriNode link;
00012 struct Observer *owner;
00013
00014 } ResourceWaiter;
00015
00016
00017 bool ResMan_Alloc(Resource *res, int pri, ResMan_time_t timeout, struct Observer *releaseRequest)
00018 {
00019 bool success = false;
00020
00021 ASSERT(releaseRequest);
00022
00023 sem_obtain(&res->lock);
00024
00025 if (res->owner == releaseRequest)
00026 {
00027
00028 res->pri = pri;
00029 success = true;
00030 }
00031 else if (!res->owner)
00032 {
00033
00034 res->pri = pri;
00035 res->owner = releaseRequest;
00036 success = true;
00037 }
00038 else
00039 {
00040 ResourceWaiter waiter;
00041
00042
00043 waiter.owner = releaseRequest;
00044 waiter.link.pri = pri;
00045 LIST_ENQUEUE(&res->queue, &waiter.link);
00046
00047
00048 if ((res->pri < pri) && res->owner->event)
00049 res->owner->event(EVENT_RELEASE, res);
00050
00051
00052 do
00053 {
00054 sem_release(&res->lock);
00055
00056 ResMan_sleep();
00057 sem_obtain(&res->lock);
00058
00059
00060 if (res->owner == releaseRequest)
00061 {
00062 success = true;
00063 break;
00064 }
00065 }
00066 while (timeout--);
00067
00068
00069 if (!success)
00070 REMOVE(&waiter.link.link);
00071 }
00072
00073 sem_release(&res->lock);
00074 return success;
00075 }
00076
00077 void ResMan_Free(Resource *res)
00078 {
00079 ResourceWaiter *waiter;
00080
00081 sem_obtain(&res->lock);
00082
00083
00084 ASSERT(res->owner);
00085
00086
00087
00088 if ((waiter = (ResourceWaiter *)list_remHead(&res->queue)))
00089 {
00090
00091 res->owner = waiter->owner;
00092 res->pri = waiter->link.pri;
00093
00094 }
00095 else
00096 {
00097
00098 res->owner = NULL;
00099 res->pri = -1;
00100 }
00101
00102 sem_release(&res->lock);
00103 }
00104
00105 void ResMan_Init(Resource *res)
00106 {
00107 res->owner = NULL;
00108 res->pri = -1;
00109
00110 sem_init(&res->lock);
00111 LIST_INIT(&res->queue);
00112 }
00113