]> rtime.felk.cvut.cz Git - arc.git/blob - system/kernel/resource.c
Again, changes to generator macro. GEN_RESOURCE, GEN_ETASK, GEN_BTASK have changed
[arc.git] / system / kernel / resource.c
1 /* -------------------------------- Arctic Core ------------------------------
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com
3  *
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>
5  *
6  * This source code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 as published by the
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * for more details.
14  * -------------------------------- Arctic Core ------------------------------*/
15
16 #include "Os.h"
17 #include "internal.h"
18
19 /* INFO
20  * - If OsTaskSchedule = NON, Task it not preemptable, no internal resource may be assigned to a task
21  *                       (cause it already have one of prio 32)
22  *                       FULL, Task is preemptable
23  * - On Schedule() .... This service has no influence on tasks with no internal resource
24  *                      assigned (preemptable tasks).
25  *
26  * OSEK on internal resources:
27  * - Non preemptable tasks are a special group with an internal resource of the
28  *   same priority as RES_SCHEDULER assigned
29  *
30  *
31  * Assign RES_SCHEDULER with prio 32.
32  * Assign internal resources to NON preemptable task.
33  *
34  * So that leaves us with:
35  * - NON
36  *   - Cannot assign internal resource.
37  *     It automatically gets internal resource with same prio as RES_SCHEDULER
38  *
39  * - FULL
40  *   - Assigned. Used for grouping tasks.
41  *   - No assigned.
42  *
43  * What does that mean?
44  * - It's probably OK to do a GetResource(RES_SCHEDULER) from a NON task (although pointless)
45  * - GetResource(<any>) from a NON task is wrong
46  *
47  * Generation/Implementation:
48  * - Resources to 32. Alloc with .resourceAlloc = ((1<<RES_1) |(1<<RES_2));
49  * - Keep allocated resources as stack to comply with LIFO order.
50  * - A linked resource is just another name for an existing resource. See OsResource in Autosar SWS OS.
51  *   This means that no resource object should be generated, just the define in Os_Cfg.h
52  * - A task with Scheduling=NON have priority (although it's internal priority is 32)
53  *
54  */
55
56 #define valid_standard_id() (rPtr->nr < Oil_GetResourceCnt()) //&& !(rPtr->type == RESOURCE_TYPE_INTERNAL) )
57 #define valid_internal_id() (rPtr->nr < Oil_GetResourceCnt()) //&& (rPtr->type == RESOURCE_TYPE_INTERNAL) )
58
59
60 static StatusType GetResource_( OsResourceType * );
61 StatusType ReleaseResource_( OsResourceType * );
62
63 StatusType GetResource( ResourceType ResID ) {
64         OsResourceType *rPtr = Oil_GetResource(ResID);
65         StatusType rv = GetResource_(rPtr);
66
67         if (rv != E_OK)
68             goto err;
69
70         OS_STD_END_1(OSServiceId_GetResource,ResID);
71 }
72
73 static StatusType GetResource_( OsResourceType * rPtr ) {
74         StatusType rv = E_OK;
75
76         if( rPtr->nr == RES_SCHEDULER ) {
77                 // Lock the scheduler
78                 os_sys.scheduler_lock = 1;
79         }
80
81         /* Check if valid resource */
82         if( !valid_standard_id() ) {
83                 rv = E_OS_ID;
84                 goto err;
85         }
86
87         /* @req OSEK
88          * Attempt to get a resource which is already occupied by any task
89      * or ISR, or the statically assigned priority of the calling task or
90      * interrupt routine is higher than the calculated ceiling priority,
91      * E_OS_ACCESS
92          */
93         if( (Os_TaskGetCurrent()->prio > rPtr->ceiling_priority )
94 #if ( OS_SC3 == STD_ON ) || ( OS_SC4 == STD_ON )
95                 || ( get_curr_application_id() !=  rPtr->application_owner_id)
96 #endif
97                 || ( rPtr->owner != (TaskType)(-1)))
98         {
99                 rv = E_OS_ACCESS;
100                 goto err;
101         }
102
103         rPtr->owner = get_curr_pid();
104         rPtr->old_task_prio = os_pcb_set_prio(Os_TaskGetCurrent() ,rPtr->ceiling_priority);
105
106         if( rPtr->type != RESOURCE_TYPE_INTERNAL ) {
107                 TAILQ_INSERT_TAIL(&Os_TaskGetCurrent()->resource_head, rPtr, listEntry);
108         }
109
110         goto ok;
111 err:
112         ERRORHOOK(rv);
113 ok:
114         return rv;
115 }
116
117 StatusType ReleaseResource( ResourceType ResID) {
118     StatusType rv = E_OK;
119         if( ResID == RES_SCHEDULER ) {
120                 os_sys.scheduler_lock=0;
121         } else {
122             OsResourceType *rPtr = Oil_GetResource(ResID);
123             rv = ReleaseResource_(rPtr);
124         }
125
126         if (rv != E_OK)
127             goto err;
128
129         OS_STD_END_1(OSServiceId_ReleaseResource,ResID);
130 }
131
132 StatusType ReleaseResource_( OsResourceType * rPtr ) {
133         if (!valid_standard_id()) {
134                 return E_OS_ID;
135         } else {
136
137         // Release it...
138         rPtr->owner = (TaskType) (-1);
139         TAILQ_REMOVE(&Os_TaskGetCurrent()->resource_head, rPtr, listEntry);
140         os_pcb_set_prio(Os_TaskGetCurrent(), rPtr->old_task_prio);
141         return E_OK;
142         }
143 }
144
145
146 void Os_ResourceReleaseAll( uint32_t mask ) {
147
148 }
149
150 //
151 void Os_ResourceGetInternal( void ) {
152         OsResourceType *rt = os_get_resource_int_p();
153
154         if( rt != NULL ) {
155                 //simple_printf("Get IR proc:%s prio:%d old_task_prio:%d\n",get_curr_pcb()->name, rt->ceiling_priority,rt->old_task_prio);
156                 GetResource_(rt);
157         }
158         //GetResourceInternal(Os_TaskGetCurrent()->resource_internal);
159 }
160
161 void Os_ResourceReleaseInternal( void ) {
162         OsResourceType *rt = os_get_resource_int_p();
163
164         if(  rt != NULL ) {
165                 //simple_printf("Rel IR proc:%s prio:%d old_task_prio:%d\n",get_curr_pcb()->name,rt->ceiling_priority,rt->old_task_prio);
166                 ReleaseResource_(rt);
167         }
168         //ReleaseResource(Os_TaskGetCurrent()->resource_internal);
169 }