5
5
#include "postmaster/postmaster.h"
6
6
#include "postmaster/bgworker.h"
7
7
#include "storage/dsm.h"
8
- #include "storage/s_lock.h"
9
- #include "storage/spin.h"
8
+ #include "storage/lwlock.h"
10
9
#include "storage/proc.h"
11
10
#include "storage/pg_sema.h"
12
11
#include "storage/shmem.h"
@@ -42,7 +41,9 @@ void BgwPoolDynamicWorkerMainLoop(Datum arg);
42
41
void
43
42
BgwPoolInit (BgwPool * pool )
44
43
{
45
- SpinLockInit (& pool -> lock );
44
+ LWLockInitialize (& pool -> lock , LWLockNewTrancheId ());
45
+ LWLockRegisterTranche (pool -> lock .tranche , "BGWPOOL_LWLOCK" );
46
+
46
47
pool -> nWorkers = 0 ;
47
48
pool -> shutdown = false;
48
49
pool -> producerBlocked = false;
@@ -157,12 +158,12 @@ BgwPoolMainLoop(BgwPool* poolDesc)
157
158
}
158
159
159
160
// XXX: change to LWLock
160
- SpinLockAcquire (& poolDesc -> lock );
161
+ LWLockAcquire (& poolDesc -> lock , LW_EXCLUSIVE );
161
162
162
163
/* Worker caught the shutdown signal - release locks and return. */
163
164
if (poolDesc -> shutdown )
164
165
{
165
- SpinLockRelease (& poolDesc -> lock );
166
+ LWLockRelease (& poolDesc -> lock );
166
167
break ;
167
168
}
168
169
@@ -177,7 +178,7 @@ BgwPoolMainLoop(BgwPool* poolDesc)
177
178
* remain in opinion, that worker waked up and doing its work.
178
179
*/
179
180
ConditionVariablePrepareToSleep (& poolDesc -> available_cv );
180
- SpinLockRelease (& poolDesc -> lock );
181
+ LWLockRelease (& poolDesc -> lock );
181
182
182
183
ConditionVariableSleep (& poolDesc -> available_cv , PG_WAIT_EXTENSION );
183
184
continue ;
@@ -186,9 +187,9 @@ BgwPoolMainLoop(BgwPool* poolDesc)
186
187
/* Wait for end of the node joining operation */
187
188
while (poolDesc -> n_holders > 0 && !poolDesc -> shutdown )
188
189
{
189
- SpinLockRelease (& poolDesc -> lock );
190
+ LWLockRelease (& poolDesc -> lock );
190
191
ConditionVariableSleep (& Mtm -> receiver_barrier_cv , PG_WAIT_EXTENSION );
191
- SpinLockAcquire (& poolDesc -> lock );
192
+ LWLockAcquire (& poolDesc -> lock , LW_EXCLUSIVE );
192
193
}
193
194
194
195
size = * (int * ) & queue [poolDesc -> head ];
@@ -230,14 +231,14 @@ BgwPoolMainLoop(BgwPool* poolDesc)
230
231
ConditionVariableBroadcast (& poolDesc -> overflow_cv );
231
232
}
232
233
233
- SpinLockRelease (& poolDesc -> lock );
234
+ LWLockRelease (& poolDesc -> lock );
234
235
235
236
MtmExecutor (work , size , & ctx );
236
237
pfree (work );
237
238
238
- SpinLockAcquire (& poolDesc -> lock );
239
+ LWLockAcquire (& poolDesc -> lock , LW_EXCLUSIVE );
239
240
poolDesc -> active -= 1 ;
240
- SpinLockRelease (& poolDesc -> lock );
241
+ LWLockRelease (& poolDesc -> lock );
241
242
242
243
ConditionVariableBroadcast (& poolDesc -> syncpoint_cv );
243
244
}
@@ -287,15 +288,15 @@ static void BgwStartExtraWorker(BgwPool* pool)
287
288
* After return from routine work and ctx buffers can be reused safely.
288
289
*/
289
290
void
290
- BgwPoolExecute (BgwPool * pool , void * work , int size , MtmReceiverContext * ctx )
291
+ BgwPoolExecute (BgwPool * poolDesc , void * work , int size , MtmReceiverContext * ctx )
291
292
{
292
293
int payload = INTALIGN (sizeof (MtmReceiverContext ));
293
294
294
- Assert (pool != NULL );
295
+ Assert (poolDesc != NULL );
295
296
Assert (queue != NULL );
296
297
297
298
// XXX: align with spill size and assert that
298
- if (MSGLEN > pool -> size )
299
+ if (MSGLEN > poolDesc -> size )
299
300
{
300
301
/*
301
302
* Size of work is larger than size of shared buffer:
@@ -305,8 +306,8 @@ BgwPoolExecute(BgwPool* pool, void* work, int size, MtmReceiverContext *ctx)
305
306
return ;
306
307
}
307
308
308
- SpinLockAcquire ( & pool -> lock );
309
- while (!pool -> shutdown )
309
+ LWLockAcquire ( & poolDesc -> lock , LW_EXCLUSIVE );
310
+ while (!poolDesc -> shutdown )
310
311
{
311
312
/*
312
313
* If queue is not wrapped through the end of buffer (head <= tail) we can
@@ -316,87 +317,89 @@ BgwPoolExecute(BgwPool* pool, void* work, int size, MtmReceiverContext *ctx)
316
317
* If queue is wrapped through the end of buffer (tail < head) we can fit
317
318
* message only between head and tail.
318
319
*/
319
- if ((pool -> head <= pool -> tail &&
320
- (pool -> size - pool -> tail >= MSGLEN || pool -> head >= size + payload )) ||
321
- (pool -> head > pool -> tail && pool -> head - pool -> tail >= MSGLEN ))
320
+ if ((poolDesc -> head <= poolDesc -> tail &&
321
+ (poolDesc -> size - poolDesc -> tail >= MSGLEN ||
322
+ poolDesc -> head >= size + payload )) ||
323
+ (poolDesc -> head > poolDesc -> tail &&
324
+ poolDesc -> head - poolDesc -> tail >= MSGLEN ))
322
325
{
323
- pool -> pending += 1 ;
326
+ poolDesc -> pending += 1 ;
324
327
325
- if (pool -> active + pool -> pending > pool -> nWorkers )
326
- BgwStartExtraWorker (pool );
328
+ if (poolDesc -> active + poolDesc -> pending > poolDesc -> nWorkers )
329
+ BgwStartExtraWorker (poolDesc );
327
330
328
331
/*
329
332
* We always have free space for size at tail, as everything is
330
333
* int-aligned and when pool->tail becomes equal to pool->size it
331
334
* is switched to zero.
332
335
*/
333
- * (int * ) & queue [pool -> tail ] = size ;
336
+ * (int * ) & queue [poolDesc -> tail ] = size ;
334
337
335
- if (pool -> size - pool -> tail >= MSGLEN )
338
+ if (poolDesc -> size - poolDesc -> tail >= MSGLEN )
336
339
{
337
- memcpy (& queue [pool -> tail + sizeof (int )], ctx , payload );
338
- memcpy (& queue [pool -> tail + sizeof (int ) + payload ], work , size );
339
- pool -> tail += MSGLEN ;
340
+ memcpy (& queue [poolDesc -> tail + sizeof (int )], ctx , payload );
341
+ memcpy (& queue [poolDesc -> tail + sizeof (int ) + payload ], work , size );
342
+ poolDesc -> tail += MSGLEN ;
340
343
}
341
344
else
342
345
{
343
346
/* Message can't fit into the end of queue. */
344
347
memcpy (queue , ctx , payload );
345
348
memcpy (& queue [payload ], work , size );
346
- pool -> tail = MSGLEN - sizeof (int );
349
+ poolDesc -> tail = MSGLEN - sizeof (int );
347
350
}
348
351
349
- if (pool -> tail == pool -> size )
350
- pool -> tail = 0 ;
352
+ if (poolDesc -> tail == poolDesc -> size )
353
+ poolDesc -> tail = 0 ;
351
354
352
- ConditionVariableBroadcast (& pool -> available_cv );
355
+ ConditionVariableBroadcast (& poolDesc -> available_cv );
353
356
break ;
354
357
}
355
358
else
356
359
{
357
- pool -> producerBlocked = true;
360
+ poolDesc -> producerBlocked = true;
358
361
/* It is critical that the sleep preparation will stay here */
359
- ConditionVariablePrepareToSleep (& pool -> overflow_cv );
360
- SpinLockRelease ( & pool -> lock );
361
- ConditionVariableSleep (& pool -> overflow_cv , PG_WAIT_EXTENSION );
362
- SpinLockAcquire ( & pool -> lock );
362
+ ConditionVariablePrepareToSleep (& poolDesc -> overflow_cv );
363
+ LWLockRelease ( & poolDesc -> lock );
364
+ ConditionVariableSleep (& poolDesc -> overflow_cv , PG_WAIT_EXTENSION );
365
+ LWLockAcquire ( & poolDesc -> lock , LW_EXCLUSIVE );
363
366
}
364
367
}
365
- SpinLockRelease ( & pool -> lock );
368
+ LWLockRelease ( & poolDesc -> lock );
366
369
}
367
370
368
371
/*
369
372
* Initiate shutdown process of workers: set shutdown sign and wake up all
370
373
* workers.
371
374
*/
372
- void PoolStateShutdown (BgwPool * pool )
375
+ void PoolStateShutdown (BgwPool * poolDesc )
373
376
{
374
- SpinLockAcquire ( & pool -> lock );
375
- pool -> shutdown = true;
376
- ConditionVariableBroadcast (& pool -> available_cv );
377
- SpinLockRelease ( & pool -> lock );
377
+ LWLockAcquire ( & poolDesc -> lock , LW_EXCLUSIVE );
378
+ poolDesc -> shutdown = true;
379
+ ConditionVariableBroadcast (& poolDesc -> available_cv );
380
+ LWLockRelease ( & poolDesc -> lock );
378
381
}
379
382
380
383
/*
381
384
* Tell our lads to cancel currently active transactions.
382
385
*/
383
386
void
384
- BgwPoolCancel (BgwPool * pool )
387
+ BgwPoolCancel (BgwPool * poolDesc )
385
388
{
386
389
int i ;
387
390
388
- SpinLockAcquire ( & pool -> lock );
389
- for (i = 0 ; i < pool -> nWorkers ; i ++ )
391
+ LWLockAcquire ( & poolDesc -> lock , LW_EXCLUSIVE );
392
+ for (i = 0 ; i < poolDesc -> nWorkers ; i ++ )
390
393
{
391
394
BgwHandleStatus status ;
392
395
pid_t pid ;
393
396
394
- status = GetBackgroundWorkerPid (pool -> bgwhandles [i ], & pid );
397
+ status = GetBackgroundWorkerPid (poolDesc -> bgwhandles [i ], & pid );
395
398
if (status == BGWH_STARTED )
396
399
{
397
400
Assert (pid > 0 );
398
401
kill (pid , SIGINT );
399
402
}
400
403
}
401
- SpinLockRelease ( & pool -> lock );
404
+ LWLockRelease ( & poolDesc -> lock );
402
405
}
0 commit comments