Subversion Repositories shark

Rev

Rev 3 | 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
 ------------
38 pj 23
 CVS :        $Id: npp.c,v 1.2 2003-01-07 17:07:50 pj Exp $
2 pj 24
 
25
 File:        $File$
38 pj 26
 Revision:    $Revision: 1.2 $
27
 Last update: $Date: 2003-01-07 17:07:50 $
2 pj 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 <kernel/const.h>
60
#include <sys/types.h>
61
#include <kernel/descr.h>
62
#include <kernel/var.h>
63
#include <kernel/func.h>
64
 
65
/* The NPP resource level descriptor */
66
typedef struct {
67
  mutex_resource_des m;   /*+ the mutex interface +*/
68
 
69
  int nlocked;  /*+ how many mutex a task currently locks +*/
70
} NPP_mutex_resource_des;
71
 
72
 
38 pj 73
#if 0
2 pj 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
}
38 pj 81
#endif
2 pj 82
 
38 pj 83
static int NPP_res_register(RLEVEL l, PID p, RES_MODEL *r)
2 pj 84
{
85
  /* NPP works with all tasks without Resource parameters */
86
  return -1;
87
}
88
 
89
static void NPP_res_detach(RLEVEL l, PID p)
90
{
91
  NPP_mutex_resource_des *m = (NPP_mutex_resource_des *)(resource_table[l]);
92
 
93
  if (m->nlocked)
94
    kern_raise(XMUTEX_OWNER_KILLED, p);
95
}
96
 
38 pj 97
static int NPP_init(RLEVEL l, mutex_t *m, const mutexattr_t *a)
2 pj 98
{
38 pj 99
  if (a->mclass != NPP_MCLASS)
2 pj 100
    return -1;
101
 
102
  m->mutexlevel = l;
103
  m->opt = (void *)NIL;
104
 
105
  return 0;
106
}
107
 
108
 
109
static int NPP_destroy(RLEVEL l, mutex_t *m)
110
{
111
//  NPP_mutex_resource_des *lev = (NPP_mutex_resource_des *)(resource_table[l]);
112
 
113
  if ( ((PID) m->opt) != NIL)
114
    return (EBUSY);
115
 
116
  return 0;
117
}
118
 
119
static int NPP_lock(RLEVEL l, mutex_t *m)
120
{
121
  NPP_mutex_resource_des *lev;
122
 
123
  kern_cli();
124
 
125
  if (((PID)m->opt) == exec_shadow) {
126
    /* the task already owns the mutex */
127
    kern_sti();
128
    return (EDEADLK);
129
  }
130
 
131
  /* p->opt == NIL (It can't be the case of p->opt != NIL and != exec_shadow
132
     because when a task lock a mutex it become unpreemptable */
133
 
134
  /* the mutex is free, We can lock it! */
135
  lev = (NPP_mutex_resource_des *)(resource_table[l]);
136
 
137
  if (!lev->nlocked) task_nopreempt();
138
  lev->nlocked++;
139
 
140
  m->opt = (void *)exec_shadow;
141
 
142
  kern_sti();
143
 
144
  return 0;
145
}
146
 
147
// static int NPP_trylock(RLEVEL l, mutex_t *m) is a non-sense!
148
 
149
static int NPP_unlock(RLEVEL l, mutex_t *m)
150
{
151
  NPP_mutex_resource_des *lev;
152
 
153
  /* the mutex is mine */
154
  lev = (NPP_mutex_resource_des *)(resource_table[l]);
155
  lev->nlocked--;
156
 
157
  m->opt = (void *)NIL;
158
 
159
  if (!lev->nlocked) task_preempt();
160
 
161
  return 0;
162
}
163
 
164
void NPP_register_module(void)
165
{
166
  RLEVEL l;                  /* the level that we register */
167
  NPP_mutex_resource_des *m;  /* for readableness only */
168
 
169
  printk("NPP_register_module\n");
170
 
171
  /* request an entry in the level_table */
172
  l = resource_alloc_descriptor();
173
 
174
  /* alloc the space needed for the EDF_level_des */
175
  m = (NPP_mutex_resource_des *)kern_alloc(sizeof(NPP_mutex_resource_des));
176
 
177
  /* update the level_table with the new entry */
178
  resource_table[l] = (resource_des *)m;
179
 
180
  /* fill the resource_des descriptor */
181
  m->m.r.rtype                       = MUTEX_RTYPE;
182
  m->m.r.res_register                = NPP_res_register;
183
  m->m.r.res_detach                  = NPP_res_detach;
184
 
185
  /* fill the mutex_resource_des descriptor */
186
  m->m.init                          = NPP_init;
187
  m->m.destroy                       = NPP_destroy;
188
  m->m.lock                          = NPP_lock;
189
  m->m.trylock                       = NPP_lock;   // !!!!!!!!!!!!
190
  m->m.unlock                        = NPP_unlock;
191
 
192
  /* fill the NPP_mutex_resource_des descriptor */
193
  m->nlocked = 0;
194
}
195