Subversion Repositories shark

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   Massimiliano Giorgi <massy@gandalf.sssup.it>
11
 *   Luca Abeni          <luca@gandalf.sssup.it>
12
 *   (see the web pages for full authors list)
13
 *
14
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
15
 *
16
 * http://www.sssup.it
17
 * http://retis.sssup.it
18
 * http://shark.sssup.it
19
 */
20
 
21
/**
22
 ------------
23
 CVS :        $Id: npp.c,v 1.1.1.1 2002-03-29 14:12:52 pj Exp $
24
 
25
 File:        $File$
26
 Revision:    $Revision: 1.1.1.1 $
27
 Last update: $Date: 2002-03-29 14:12:52 $
28
 ------------
29
 
30
 Non Preemptive Protocol. see npp.h for more details...
31
 
32
**/
33
 
34
/*
35
 * Copyright (C) 2000 Paolo Gai
36
 *
37
 * This program is free software; you can redistribute it and/or modify
38
 * it under the terms of the GNU General Public License as published by
39
 * the Free Software Foundation; either version 2 of the License, or
40
 * (at your option) any later version.
41
 *
42
 * This program is distributed in the hope that it will be useful,
43
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
44
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
45
 * GNU General Public License for more details.
46
 *
47
 * You should have received a copy of the GNU General Public License
48
 * along with this program; if not, write to the Free Software
49
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
50
 *
51
 */
52
 
53
 
54
#include <modules/npp.h>
55
 
56
#include <ll/ll.h>
57
#include <ll/string.h>
58
#include <ll/stdio.h>
59
#include <modules/codes.h>
60
#include <kernel/const.h>
61
#include <sys/types.h>
62
#include <kernel/descr.h>
63
#include <kernel/var.h>
64
#include <kernel/func.h>
65
 
66
/* The NPP resource level descriptor */
67
typedef struct {
68
  mutex_resource_des m;   /*+ the mutex interface +*/
69
 
70
  int nlocked;  /*+ how many mutex a task currently locks +*/
71
} NPP_mutex_resource_des;
72
 
73
 
74
/*+ print resource protocol statistics...+*/
75
static void NPP_resource_status(RLEVEL r)
76
{
77
  NPP_mutex_resource_des *m = (NPP_mutex_resource_des *)(resource_table[r]);
78
 
79
  kern_printf("%d Resources owned by the tasks %d\n", m->nlocked, exec_shadow);
80
}
81
 
82
static int NPP_level_accept_resource_model(RLEVEL l, RES_MODEL *r)
83
{
84
  /* NPP works with all tasks without Resource parameters */
85
  return -1;
86
}
87
 
88
static void NPP_res_register(RLEVEL l, PID p, RES_MODEL *r)
89
{
90
  /* never called!!! */
91
}
92
 
93
static void NPP_res_detach(RLEVEL l, PID p)
94
{
95
  NPP_mutex_resource_des *m = (NPP_mutex_resource_des *)(resource_table[l]);
96
 
97
  if (m->nlocked)
98
    kern_raise(XMUTEX_OWNER_KILLED, p);
99
}
100
 
101
static int NPP_level_accept_mutexattr(RLEVEL l, const mutexattr_t *a)
102
{
103
  if (a->mclass == NPP_MCLASS || a->mclass == (NPP_MCLASS | l) )
104
    return 0;
105
  else
106
    return -1;
107
}
108
 
109
static int NPP_init(RLEVEL l, mutex_t *m, const mutexattr_t *a)
110
{
111
  m->mutexlevel = l;
112
  m->opt = (void *)NIL;
113
 
114
  return 0;
115
}
116
 
117
 
118
static int NPP_destroy(RLEVEL l, mutex_t *m)
119
{
120
//  NPP_mutex_resource_des *lev = (NPP_mutex_resource_des *)(resource_table[l]);
121
 
122
  if ( ((PID) m->opt) != NIL)
123
    return (EBUSY);
124
 
125
  return 0;
126
}
127
 
128
static int NPP_lock(RLEVEL l, mutex_t *m)
129
{
130
  NPP_mutex_resource_des *lev;
131
 
132
  kern_cli();
133
 
134
  if (((PID)m->opt) == exec_shadow) {
135
    /* the task already owns the mutex */
136
    kern_sti();
137
    return (EDEADLK);
138
  }
139
 
140
  /* p->opt == NIL (It can't be the case of p->opt != NIL and != exec_shadow
141
     because when a task lock a mutex it become unpreemptable */
142
 
143
  /* the mutex is free, We can lock it! */
144
  lev = (NPP_mutex_resource_des *)(resource_table[l]);
145
 
146
  if (!lev->nlocked) task_nopreempt();
147
  lev->nlocked++;
148
 
149
  m->opt = (void *)exec_shadow;
150
 
151
  kern_sti();
152
 
153
  return 0;
154
}
155
 
156
// static int NPP_trylock(RLEVEL l, mutex_t *m) is a non-sense!
157
 
158
static int NPP_unlock(RLEVEL l, mutex_t *m)
159
{
160
  NPP_mutex_resource_des *lev;
161
 
162
  /* the mutex is mine */
163
  lev = (NPP_mutex_resource_des *)(resource_table[l]);
164
  lev->nlocked--;
165
 
166
  m->opt = (void *)NIL;
167
 
168
  if (!lev->nlocked) task_preempt();
169
 
170
  return 0;
171
}
172
 
173
void NPP_register_module(void)
174
{
175
  RLEVEL l;                  /* the level that we register */
176
  NPP_mutex_resource_des *m;  /* for readableness only */
177
 
178
  printk("NPP_register_module\n");
179
 
180
  /* request an entry in the level_table */
181
  l = resource_alloc_descriptor();
182
 
183
  /* alloc the space needed for the EDF_level_des */
184
  m = (NPP_mutex_resource_des *)kern_alloc(sizeof(NPP_mutex_resource_des));
185
 
186
  /* update the level_table with the new entry */
187
  resource_table[l] = (resource_des *)m;
188
 
189
  /* fill the resource_des descriptor */
190
  strncpy(m->m.r.res_name, NPP_MODULENAME, MAX_MODULENAME);
191
  m->m.r.res_code                    = NPP_MODULE_CODE;
192
  m->m.r.res_version                 = NPP_MODULE_VERSION;
193
 
194
  m->m.r.rtype                       = MUTEX_RTYPE;
195
 
196
  m->m.r.resource_status             = NPP_resource_status;
197
  m->m.r.level_accept_resource_model = NPP_level_accept_resource_model;
198
  m->m.r.res_register                = NPP_res_register;
199
 
200
  m->m.r.res_detach                  = NPP_res_detach;
201
 
202
  /* fill the mutex_resource_des descriptor */
203
  m->m.level_accept_mutexattr        = NPP_level_accept_mutexattr;
204
  m->m.init                          = NPP_init;
205
  m->m.destroy                       = NPP_destroy;
206
  m->m.lock                          = NPP_lock;
207
  m->m.trylock                       = NPP_lock;   // !!!!!!!!!!!!
208
  m->m.unlock                        = NPP_unlock;
209
 
210
  /* fill the NPP_mutex_resource_des descriptor */
211
  m->nlocked = 0;
212
}
213