Subversion Repositories shark

Rev

Rev 79 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
29 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
 *   (see the web pages for full authors list)
11
 *
12
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
13
 *
14
 * http://www.sssup.it
15
 * http://retis.sssup.it
16
 * http://shark.sssup.it
17
 */
18
 
19
/*
20
 ------------
21
 CVS :        $Id: iqueue.h,v 1.1 2002-11-11 08:36:01 pj Exp $
22
 
23
 File:        $File$
24
 Revision:    $Revision: 1.1 $
25
 Last update: $Date: 2002-11-11 08:36:01 $
26
 ------------
27
 
28
*/
29
 
30
/*
31
 * Copyright (C) 2002 Paolo Gai
32
 *
33
 * This program is free software; you can redistribute it and/or modify
34
 * it under the terms of the GNU General Public License as published by
35
 * the Free Software Foundation; either version 2 of the License, or
36
 * (at your option) any later version.
37
 *
38
 * This program is distributed in the hope that it will be useful,
39
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
40
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
41
 * GNU General Public License for more details.
42
 *
43
 * You should have received a copy of the GNU General Public License
44
 * along with this program; if not, write to the Free Software
45
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
46
 *
47
 */
48
 
49
 
50
/*
51
 IQUEUEs
52
 
53
 This file contains functions that helps to manage task queues.
54
 
55
 These functions are different from the functions that manages the
56
 QUEUE and QQUEUE types. In particular, these functions no more relies
57
 on the prev & next fields of the task descriptor. In that way, tasks
58
 can be inserted in more than one queue at a time.
59
 
60
 Basically, an IQUEUE has an "I"nternal prev/next structure, that may
61
 be shared between one or more queue. Of course, the user MUST
62
 guarantee that the same task will not be inserted in two IQUEUEs that
63
 share the same prev/next buffer.
64
 
65
 The queue insertion is made by the following functions:
66
 iq_insert          -> insertion based on the priority field.
67
 iq_timespec_insert -> same as above but use the timespec_priority field
68
 iq_insertfirst     -> insert in the first position of the queue
69
*/
70
 
71
#include <ll/ll.h>
72
#include <kernel/const.h>
73
#include <kernel/types.h>
74
 
75
#ifndef __KERNEL_IQUEUE_H__
76
#define __KERNEL_IQUEUE_H__
77
 
78
#define IQUEUE_NO_PRIORITY 1
79
#define IQUEUE_NO_TIMESPEC 2
80
 
81
struct IQUEUE_shared {
82
  PID prev[MAX_PROC];
83
  PID next[MAX_PROC];
84
  struct timespec *timespec_priority;
85
  DWORD *priority;
86
};
87
 
88
typedef struct {
89
  PID first;
90
  PID last;
91
  struct IQUEUE_shared *s;
92
} IQUEUE;
93
 
94
 
95
 
96
/* Internal queue initialization:
97
 
98
   share = &x -> the internal data structure of the IQUEUE x is used
99
                 to enqueue the tasks.  
100
 
101
   share = NULL -> an internal data structure to handle prev/next
102
                   pairs is dynamically allocated (The amount of
103
                   memory that is allocated can be reduced using the
104
                   flags).
105
 
106
   flags can be used to reduce the memory usage of an IQUEUE when share=NULL:
107
   IQUEUE_NO_PRIORITY -> the iqueue do not provide internally a priority field
108
   IQUEUE_NO_TIMESPEC -> the iqueue do not provide internally a timespec field
109
 
110
   - note that, if these flags are used, the corresponding insert
111
     functions will not work!
112
   - the default value for the flags is, of course, 0
113
*/
114
void iq_init (IQUEUE *q, IQUEUE *share, int flags);
115
 
116
/* Queue insert functions:
117
 
118
   - inserts a p into the q. p must not be already inserted into q.
119
   - four versions of the function;
120
     - iq_priority_insert -> ordered insertion using the priority field
121
     - iq_timespec_insert -> ordered insertion using the timespec field
122
     - iq_insertfirst     -> insert at the first position of the queue
123
     - iq_insertlast      -> insert at the last position of the queue
124
*/
125
void iq_priority_insert (PID p, IQUEUE *q);
126
void iq_timespec_insert (PID p, IQUEUE *q);
127
void iq_insertfirst     (PID p, IQUEUE *q);
128
void iq_insertlast      (PID p, IQUEUE *q);
129
 
130
/* Queue extract functions:
131
 
132
   - extracts a task p from the queue q.
133
   - three versions of the function;
134
     - iq_extract -> extracts given a task p
135
                     (that must be inserted in the queue)
136
 
137
     - iq_getfirst -> extracts the first task in the queue,
138
                      NIL if the queue is empty
139
 
140
     - iq_getlast -> extracts the last task in the queue,
141
                     NIL if the queue is empty
142
 
143
*/
144
void iq_extract         (PID p, IQUEUE *q);
145
PID  iq_getfirst        (       IQUEUE *q);
146
PID  iq_getlast         (       IQUEUE *q);
147
 
148
 
149
/* Queue query functions:
150
 
151
   The first two functions return the first and the last task in the queue,
152
   NIL if the queue is empty.
153
 
154
   The second two functions can be used to get/set the priority or the
155
   timespec field used when queuing.
156
*/
157
static __inline__ PID iq_query_first(IQUEUE *q)
158
{
159
  return q->first;
160
}
161
 
162
static __inline__ PID iq_query_last(IQUEUE *q)
163
{
164
  return q->last;
165
}
166
 
167
static __inline__ struct timespec *iq_query_timespec(PID p, IQUEUE *q)
168
{
169
  return &q->s->timespec_priority[p];
170
}
171
 
172
static __inline__ DWORD *iq_query_priority (PID p, IQUEUE *q)
173
{
174
  return &q->s->priority[p];
175
}
176
 
177
/* Queue iterators */
178
 
179
/* sometimes it is useful to go through the list. For that reason
180
   You can use the following two functions... */
181
static __inline__ PID iq_query_next (PID p, IQUEUE *q)
182
{
183
  return q->s->next[p];
184
}
185
 
186
static __inline__ PID iq_query_prev (PID p, IQUEUE *q)
187
{
188
  return q->s->prev[p];
189
}
190
 
191
/* Queue test functions */
192
static __inline__ int iq_isempty (IQUEUE *q)
193
{
194
  return q->first == NIL;
195
}
196
 
197
#endif