8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmqueue.c,v 1.13 2000 /01/26 05:56:58 momjian Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmqueue.c,v 1.14 2001 /01/22 22:30:06 tgl Exp $
12
12
*
13
13
* NOTES
14
14
*
15
15
* Package for managing doubly-linked lists in shared memory.
16
16
* The only tricky thing is that SHM_QUEUE will usually be a field
17
- * in a larger record. SHMQueueGetFirst has to return a pointer
17
+ * in a larger record. SHMQueueNext has to return a pointer
18
18
* to the record itself instead of a pointer to the SHMQueue field
19
- * of the record. It takes an extra pointer and does some extra
19
+ * of the record. It takes an extra parameter and does some extra
20
20
* pointer arithmetic to do this correctly.
21
21
*
22
22
* NOTE: These are set up so they can be turned into macros some day.
23
23
*
24
24
*-------------------------------------------------------------------------
25
25
*/
26
-
27
26
#include "postgres.h"
27
+
28
28
#include "storage/shmem.h"
29
29
30
30
/*#define SHMQUEUE_DEBUG*/
31
31
#ifdef SHMQUEUE_DEBUG
32
- #define SHMQUEUE_DEBUG_DEL /* deletions */
33
- #define SHMQUEUE_DEBUG_HD /* head inserts */
34
- #define SHMQUEUE_DEBUG_TL /* tail inserts */
32
+
35
33
#define SHMQUEUE_DEBUG_ELOG NOTICE
36
- #endif /* SHMQUEUE_DEBUG */
34
+
35
+ static void dumpQ (SHM_QUEUE * q , char * s );
36
+
37
+ #endif
38
+
37
39
38
40
/*
39
41
* ShmemQueueInit -- make the head of a new queue point
@@ -84,160 +86,108 @@ SHMQueueDelete(SHM_QUEUE *queue)
84
86
Assert (SHM_PTR_VALID (nextElem ));
85
87
Assert (SHM_PTR_VALID (prevElem ));
86
88
87
- #ifdef SHMQUEUE_DEBUG_DEL
89
+ #ifdef SHMQUEUE_DEBUG
88
90
dumpQ (queue , "in SHMQueueDelete: begin" );
89
- #endif /* SHMQUEUE_DEBUG_DEL */
91
+ #endif
90
92
91
93
prevElem -> next = (queue )-> next ;
92
94
nextElem -> prev = (queue )-> prev ;
93
95
94
- #ifdef SHMQUEUE_DEBUG_DEL
95
- dumpQ ((SHM_QUEUE * ) MAKE_PTR (queue -> prev ), "in SHMQueueDelete: end" );
96
- #endif /* SHMQUEUE_DEBUG_DEL */
97
- }
98
-
99
- #ifdef SHMQUEUE_DEBUG
100
- void
101
- dumpQ (SHM_QUEUE * q , char * s )
102
- {
103
- char elem [NAMEDATALEN ];
104
- char buf [1024 ];
105
- SHM_QUEUE * start = q ;
106
- int count = 0 ;
107
-
108
- sprintf (buf , "q prevs: %x" , MAKE_OFFSET (q ));
109
- q = (SHM_QUEUE * ) MAKE_PTR (q -> prev );
110
- while (q != start )
111
- {
112
- sprintf (elem , "--->%x" , MAKE_OFFSET (q ));
113
- strcat (buf , elem );
114
- q = (SHM_QUEUE * ) MAKE_PTR (q -> prev );
115
- if (q -> prev == MAKE_OFFSET (q ))
116
- break ;
117
- if (count ++ > 40 )
118
- {
119
- strcat (buf , "BAD PREV QUEUE!!" );
120
- break ;
121
- }
122
- }
123
- sprintf (elem , "--->%x" , MAKE_OFFSET (q ));
124
- strcat (buf , elem );
125
- elog (SHMQUEUE_DEBUG_ELOG , "%s: %s" , s , buf );
126
-
127
- sprintf (buf , "q nexts: %x" , MAKE_OFFSET (q ));
128
- count = 0 ;
129
- q = (SHM_QUEUE * ) MAKE_PTR (q -> next );
130
- while (q != start )
131
- {
132
- sprintf (elem , "--->%x" , MAKE_OFFSET (q ));
133
- strcat (buf , elem );
134
- q = (SHM_QUEUE * ) MAKE_PTR (q -> next );
135
- if (q -> next == MAKE_OFFSET (q ))
136
- break ;
137
- if (count ++ > 10 )
138
- {
139
- strcat (buf , "BAD NEXT QUEUE!!" );
140
- break ;
141
- }
142
- }
143
- sprintf (elem , "--->%x" , MAKE_OFFSET (q ));
144
- strcat (buf , elem );
145
- elog (SHMQUEUE_DEBUG_ELOG , "%s: %s" , s , buf );
96
+ (queue )-> prev = (queue )-> next = INVALID_OFFSET ;
146
97
}
147
98
148
- #endif /* SHMQUEUE_DEBUG */
149
-
150
99
/*
151
- * SHMQueueInsertHD -- put elem in queue between the queue head
152
- * and its "prev" element.
100
+ * SHMQueueInsertBefore -- put elem in queue before the given queue
101
+ * element. Inserting "before" the queue head puts the elem
102
+ * at the tail of the queue.
153
103
*/
154
- #ifdef NOT_USED
155
104
void
156
- SHMQueueInsertHD (SHM_QUEUE * queue , SHM_QUEUE * elem )
105
+ SHMQueueInsertBefore (SHM_QUEUE * queue , SHM_QUEUE * elem )
157
106
{
158
107
SHM_QUEUE * prevPtr = (SHM_QUEUE * ) MAKE_PTR ((queue )-> prev );
159
108
SHMEM_OFFSET elemOffset = MAKE_OFFSET (elem );
160
109
161
110
Assert (SHM_PTR_VALID (queue ));
162
111
Assert (SHM_PTR_VALID (elem ));
163
112
164
- #ifdef SHMQUEUE_DEBUG_HD
165
- dumpQ (queue , "in SHMQueueInsertHD : begin" );
166
- #endif /* SHMQUEUE_DEBUG_HD */
113
+ #ifdef SHMQUEUE_DEBUG
114
+ dumpQ (queue , "in SHMQueueInsertBefore : begin" );
115
+ #endif
167
116
168
117
(elem )-> next = prevPtr -> next ;
169
118
(elem )-> prev = queue -> prev ;
170
119
(queue )-> prev = elemOffset ;
171
120
prevPtr -> next = elemOffset ;
172
121
173
- #ifdef SHMQUEUE_DEBUG_HD
174
- dumpQ (queue , "in SHMQueueInsertHD: end" );
175
- #endif /* SHMQUEUE_DEBUG_HD */
176
- }
177
-
122
+ #ifdef SHMQUEUE_DEBUG
123
+ dumpQ (queue , "in SHMQueueInsertBefore: end" );
178
124
#endif
125
+ }
179
126
127
+ /*
128
+ * SHMQueueInsertAfter -- put elem in queue after the given queue
129
+ * element. Inserting "after" the queue head puts the elem
130
+ * at the head of the queue.
131
+ */
132
+ #ifdef NOT_USED
180
133
void
181
- SHMQueueInsertTL (SHM_QUEUE * queue , SHM_QUEUE * elem )
134
+ SHMQueueInsertAfter (SHM_QUEUE * queue , SHM_QUEUE * elem )
182
135
{
183
136
SHM_QUEUE * nextPtr = (SHM_QUEUE * ) MAKE_PTR ((queue )-> next );
184
137
SHMEM_OFFSET elemOffset = MAKE_OFFSET (elem );
185
138
186
139
Assert (SHM_PTR_VALID (queue ));
187
140
Assert (SHM_PTR_VALID (elem ));
188
141
189
- #ifdef SHMQUEUE_DEBUG_TL
190
- dumpQ (queue , "in SHMQueueInsertTL : begin" );
191
- #endif /* SHMQUEUE_DEBUG_TL */
142
+ #ifdef SHMQUEUE_DEBUG
143
+ dumpQ (queue , "in SHMQueueInsertAfter : begin" );
144
+ #endif
192
145
193
146
(elem )-> prev = nextPtr -> prev ;
194
147
(elem )-> next = queue -> next ;
195
148
(queue )-> next = elemOffset ;
196
149
nextPtr -> prev = elemOffset ;
197
150
198
- #ifdef SHMQUEUE_DEBUG_TL
199
- dumpQ (queue , "in SHMQueueInsertTL : end" );
200
- #endif /* SHMQUEUE_DEBUG_TL */
151
+ #ifdef SHMQUEUE_DEBUG
152
+ dumpQ (queue , "in SHMQueueInsertAfter : end" );
153
+ #endif
201
154
}
155
+ #endif /* NOT_USED */
202
156
203
- /*
204
- * SHMQueueFirst -- Get the first element from a queue
157
+ /*--------------------
158
+ * SHMQueueNext -- Get the next element from a queue
205
159
*
206
- * First element is queue->next. If SHMQueue is part of
160
+ * To start the iteration, pass the queue head as both queue and curElem.
161
+ * Returns NULL if no more elements.
162
+ *
163
+ * Next element is at curElem->next. If SHMQueue is part of
207
164
* a larger structure, we want to return a pointer to the
208
165
* whole structure rather than a pointer to its SHMQueue field.
209
166
* I.E. struct {
210
167
* int stuff;
211
168
* SHMQueue elem;
212
169
* } ELEMType;
213
- * when this element is in a queue (queue->next) is struct.elem.
214
- * nextQueue allows us to calculate the offset of the SHMQueue
215
- * field in the structure.
216
- *
217
- * call to SHMQueueFirst should take these parameters:
170
+ * When this element is in a queue, (prevElem->next) is struct.elem.
171
+ * We subtract linkOffset to get the correct start address of the structure.
218
172
*
219
- * &(queueHead),&firstElem,&(firstElem->next)
173
+ * calls to SHMQueueNext should take these parameters:
220
174
*
221
- * Note that firstElem may well be uninitialized. if firstElem
222
- * is initially K, &(firstElem->next) will be K+ the offset to
223
- * next.
175
+ * &(queueHead), &(queueHead), offsetof(ELEMType, elem)
176
+ * or
177
+ * &(queueHead), &(curElem->elem), offsetof(ELEMType, elem)
178
+ *--------------------
224
179
*/
225
- void
226
- SHMQueueFirst (SHM_QUEUE * queue , Pointer * nextPtrPtr , SHM_QUEUE * nextQueue )
180
+ Pointer
181
+ SHMQueueNext (SHM_QUEUE * queue , SHM_QUEUE * curElem , Size linkOffset )
227
182
{
228
- SHM_QUEUE * elemPtr = (SHM_QUEUE * ) MAKE_PTR ((queue )-> next );
183
+ SHM_QUEUE * elemPtr = (SHM_QUEUE * ) MAKE_PTR ((curElem )-> next );
229
184
230
- Assert (SHM_PTR_VALID (queue ));
231
- * nextPtrPtr = (Pointer ) (((unsigned long ) * nextPtrPtr ) +
232
- ((unsigned long ) elemPtr ) - ((unsigned long ) nextQueue ));
233
-
234
- /*
235
- * nextPtrPtr a ptr to a structure linked in the queue nextQueue is
236
- * the SHMQueue field of the structure nextPtrPtr - nextQueue is 0
237
- * minus the offset of the queue field n the record elemPtr +
238
- * (*nextPtrPtr - nexQueue) is the start of the structure containing
239
- * elemPtr.
240
- */
185
+ Assert (SHM_PTR_VALID (curElem ));
186
+
187
+ if (elemPtr == queue ) /* back to the queue head? */
188
+ return NULL ;
189
+
190
+ return (Pointer ) (((char * ) elemPtr ) - linkOffset );
241
191
}
242
192
243
193
/*
@@ -255,3 +205,55 @@ SHMQueueEmpty(SHM_QUEUE *queue)
255
205
}
256
206
return FALSE;
257
207
}
208
+
209
+ #ifdef SHMQUEUE_DEBUG
210
+
211
+ static void
212
+ dumpQ (SHM_QUEUE * q , char * s )
213
+ {
214
+ char elem [NAMEDATALEN ];
215
+ char buf [1024 ];
216
+ SHM_QUEUE * start = q ;
217
+ int count = 0 ;
218
+
219
+ sprintf (buf , "q prevs: %lx" , MAKE_OFFSET (q ));
220
+ q = (SHM_QUEUE * ) MAKE_PTR (q -> prev );
221
+ while (q != start )
222
+ {
223
+ sprintf (elem , "--->%lx" , MAKE_OFFSET (q ));
224
+ strcat (buf , elem );
225
+ q = (SHM_QUEUE * ) MAKE_PTR (q -> prev );
226
+ if (q -> prev == MAKE_OFFSET (q ))
227
+ break ;
228
+ if (count ++ > 40 )
229
+ {
230
+ strcat (buf , "BAD PREV QUEUE!!" );
231
+ break ;
232
+ }
233
+ }
234
+ sprintf (elem , "--->%lx" , MAKE_OFFSET (q ));
235
+ strcat (buf , elem );
236
+ elog (SHMQUEUE_DEBUG_ELOG , "%s: %s" , s , buf );
237
+
238
+ sprintf (buf , "q nexts: %lx" , MAKE_OFFSET (q ));
239
+ count = 0 ;
240
+ q = (SHM_QUEUE * ) MAKE_PTR (q -> next );
241
+ while (q != start )
242
+ {
243
+ sprintf (elem , "--->%lx" , MAKE_OFFSET (q ));
244
+ strcat (buf , elem );
245
+ q = (SHM_QUEUE * ) MAKE_PTR (q -> next );
246
+ if (q -> next == MAKE_OFFSET (q ))
247
+ break ;
248
+ if (count ++ > 10 )
249
+ {
250
+ strcat (buf , "BAD NEXT QUEUE!!" );
251
+ break ;
252
+ }
253
+ }
254
+ sprintf (elem , "--->%lx" , MAKE_OFFSET (q ));
255
+ strcat (buf , elem );
256
+ elog (SHMQUEUE_DEBUG_ELOG , "%s: %s" , s , buf );
257
+ }
258
+
259
+ #endif /* SHMQUEUE_DEBUG */
0 commit comments