Sistema l'errore da me commesso in fase di conversione...
[bertos.git] / mware / resource.c
1
2 #include "resource.h"
3 #include <mware/observer.h>
4
5 /**
6  * Internal structure for building a priority queue
7  * of processes waiting for the resource to become free.
8  */
9 typedef struct ResourceWaiter
10 {
11         PriNode link;
12         struct Observer *owner;
13
14 } ResourceWaiter;
15
16
17 bool ResMan_Alloc(Resource *res, int pri, ResMan_time_t timeout, struct Observer *releaseRequest)
18 {
19         bool success = false;
20
21         ASSERT(releaseRequest);
22
23         sem_obtain(&res->lock);
24
25         if (res->owner == releaseRequest)
26         {
27                 // Already ours
28                 res->pri = pri;
29                 success = true;
30         }
31         else if (!res->owner)
32         {
33                 // Trivial acquire: nobody was owning the resource
34                 res->pri = pri;
35                 res->owner = releaseRequest;
36                 success = true;
37         }
38         else
39         {
40                 ResourceWaiter waiter;
41
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);
46
47                 // Resource busy: are we eligible for preemption?
48                 if ((res->pri < pri) && res->owner->event)
49                         res->owner->event(EVENT_RELEASE, res);
50
51                 // Wait in the queue until the timeout occurs.
52                 do
53                 {
54                         sem_release(&res->lock);
55                         // TODO: use a semaphore here instead
56                         ResMan_sleep();
57                         sem_obtain(&res->lock);
58
59                         // Check for ownership
60                         if (res->owner == releaseRequest)
61                         {
62                                 success = true;
63                                 break;
64                         }
65                 }
66                 while (timeout--);
67
68                 // Remove pending waiter
69                 if (!success)
70                         REMOVE(&waiter.link.link);
71         }
72
73         sem_release(&res->lock);
74         return success;
75 }
76
77 void ResMan_Free(Resource *res)
78 {
79         ResourceWaiter *waiter;
80
81         sem_obtain(&res->lock);
82
83
84         ASSERT(res->owner);
85         //TODO: check for real owner calling free
86
87         // Check for new owner candidates.
88         if ((waiter = (ResourceWaiter *)list_remHead(&res->queue)))
89         {
90                 // Transfer ownership of the resource
91                 res->owner = waiter->owner;
92                 res->pri = waiter->link.pri;
93                 //ResMan_wakeup(waiter);
94         }
95         else
96         {
97                 // Nobody waiting, free the resource
98                 res->owner = NULL;
99                 res->pri = -1;
100         }
101
102         sem_release(&res->lock);
103 }
104
105 void ResMan_Init(Resource *res)
106 {
107         res->owner = NULL;
108         res->pri = -1;
109
110         sem_init(&res->lock);
111         LIST_INIT(&res->queue);
112 }
113