Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6148656

Browse files
committed
Use EVFILT_SIGNAL for kqueue latches.
Cut down on system calls and other overheads by waiting for SIGURGexplicitly with kqueue instead of using a signal handler and self-pipe.Affects *BSD and macOS systems.This leaves only the poll implementation with a signal handler and thetraditional self-pipe trick.Discussion:https://postgr.es/m/CA+hUKGJjxPDpzBE0a3hyUywBvaZuC89yx3jK9RFZgfv_KHU7gg@mail.gmail.com
1 parent6a2a70a commit6148656

File tree

1 file changed

+38
-17
lines changed

1 file changed

+38
-17
lines changed

‎src/backend/storage/ipc/latch.c

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
* don't need to register a signal handler or create our own self-pipe. We
1919
* assume that any system that has Linux epoll() also has Linux signalfd().
2020
*
21+
* The kqueue() implementation waits for SIGURG with EVFILT_SIGNAL.
22+
*
2123
* The Windows implementation uses Windows events that are inherited by all
2224
* postmaster child processes. There's no need for the self-pipe trick there.
2325
*
@@ -150,7 +152,7 @@ static volatile sig_atomic_t waiting = false;
150152
staticintsignal_fd=-1;
151153
#endif
152154

153-
#if defined(WAIT_USE_POLL)|| defined(WAIT_USE_KQUEUE)
155+
#if defined(WAIT_USE_POLL)
154156
/* Read and write ends of the self-pipe */
155157
staticintselfpipe_readfd=-1;
156158
staticintselfpipe_writefd=-1;
@@ -189,7 +191,7 @@ static inline int WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
189191
void
190192
InitializeLatchSupport(void)
191193
{
192-
#if defined(WAIT_USE_POLL)|| defined(WAIT_USE_KQUEUE)
194+
#if defined(WAIT_USE_POLL)
193195
intpipefd[2];
194196

195197
if (IsUnderPostmaster)
@@ -277,6 +279,11 @@ InitializeLatchSupport(void)
277279
elog(FATAL,"signalfd() failed");
278280
ReserveExternalFD();
279281
#endif
282+
283+
#ifdefWAIT_USE_KQUEUE
284+
/* Ignore SIGURG, because we'll receive it via kqueue. */
285+
pqsignal(SIGURG,SIG_IGN);
286+
#endif
280287
}
281288

282289
void
@@ -300,7 +307,7 @@ InitializeLatchWaitSet(void)
300307
void
301308
ShutdownLatchSupport(void)
302309
{
303-
#if defined(WAIT_USE_POLL)|| defined(WAIT_USE_KQUEUE)
310+
#if defined(WAIT_USE_POLL)
304311
pqsignal(SIGURG,SIG_IGN);
305312
#endif
306313

@@ -310,7 +317,7 @@ ShutdownLatchSupport(void)
310317
LatchWaitSet=NULL;
311318
}
312319

313-
#if defined(WAIT_USE_POLL)|| defined(WAIT_USE_KQUEUE)
320+
#if defined(WAIT_USE_POLL)
314321
close(selfpipe_readfd);
315322
close(selfpipe_writefd);
316323
selfpipe_readfd=-1;
@@ -335,7 +342,7 @@ InitLatch(Latch *latch)
335342
latch->owner_pid=MyProcPid;
336343
latch->is_shared= false;
337344

338-
#if defined(WAIT_USE_POLL)|| defined(WAIT_USE_KQUEUE)
345+
#if defined(WAIT_USE_POLL)
339346
/* Assert InitializeLatchSupport has been called in this process */
340347
Assert(selfpipe_readfd >=0&&selfpipe_owner_pid==MyProcPid);
341348
#elif defined(WAIT_USE_WIN32)
@@ -399,7 +406,7 @@ OwnLatch(Latch *latch)
399406
/* Sanity checks */
400407
Assert(latch->is_shared);
401408

402-
#if defined(WAIT_USE_POLL)|| defined(WAIT_USE_KQUEUE)
409+
#if defined(WAIT_USE_POLL)
403410
/* Assert InitializeLatchSupport has been called in this process */
404411
Assert(selfpipe_readfd >=0&&selfpipe_owner_pid==MyProcPid);
405412
#endif
@@ -611,7 +618,7 @@ SetLatch(Latch *latch)
611618
return;
612619
elseif (owner_pid==MyProcPid)
613620
{
614-
#if defined(WAIT_USE_POLL)|| defined(WAIT_USE_KQUEUE)
621+
#if defined(WAIT_USE_POLL)
615622
if (waiting)
616623
sendSelfPipeByte();
617624
#else
@@ -898,13 +905,15 @@ AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch,
898905
{
899906
set->latch=latch;
900907
set->latch_pos=event->pos;
901-
#if defined(WAIT_USE_POLL)|| defined(WAIT_USE_KQUEUE)
908+
#if defined(WAIT_USE_POLL)
902909
event->fd=selfpipe_readfd;
903910
#elif defined(WAIT_USE_EPOLL)
904911
event->fd=signal_fd;
905912
#else
906913
event->fd=PGINVALID_SOCKET;
914+
#ifdefWAIT_USE_EPOLL
907915
returnevent->pos;
916+
#endif
908917
#endif
909918
}
910919
elseif (events==WL_POSTMASTER_DEATH)
@@ -1125,6 +1134,18 @@ WaitEventAdjustKqueueAddPostmaster(struct kevent *k_ev, WaitEvent *event)
11251134
AccessWaitEvent(k_ev)=event;
11261135
}
11271136

1137+
staticinlinevoid
1138+
WaitEventAdjustKqueueAddLatch(structkevent*k_ev,WaitEvent*event)
1139+
{
1140+
/* For now latch can only be added, not removed. */
1141+
k_ev->ident=SIGURG;
1142+
k_ev->filter=EVFILT_SIGNAL;
1143+
k_ev->flags=EV_ADD;
1144+
k_ev->fflags=0;
1145+
k_ev->data=0;
1146+
AccessWaitEvent(k_ev)=event;
1147+
}
1148+
11281149
/*
11291150
* old_events is the previous event mask, used to compute what has changed.
11301151
*/
@@ -1156,18 +1177,21 @@ WaitEventAdjustKqueue(WaitEventSet *set, WaitEvent *event, int old_events)
11561177
*/
11571178
WaitEventAdjustKqueueAddPostmaster(&k_ev[count++],event);
11581179
}
1180+
elseif (event->events==WL_LATCH_SET)
1181+
{
1182+
/* We detect latch wakeup using a signal event. */
1183+
WaitEventAdjustKqueueAddLatch(&k_ev[count++],event);
1184+
}
11591185
else
11601186
{
11611187
/*
11621188
* We need to compute the adds and deletes required to get from the
11631189
* old event mask to the new event mask, since kevent treats readable
11641190
* and writable as separate events.
11651191
*/
1166-
if (old_events==WL_LATCH_SET||
1167-
(old_events&WL_SOCKET_READABLE))
1192+
if (old_events&WL_SOCKET_READABLE)
11681193
old_filt_read= true;
1169-
if (event->events==WL_LATCH_SET||
1170-
(event->events&WL_SOCKET_READABLE))
1194+
if (event->events&WL_SOCKET_READABLE)
11711195
new_filt_read= true;
11721196
if (old_events&WL_SOCKET_WRITEABLE)
11731197
old_filt_write= true;
@@ -1620,11 +1644,8 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
16201644
occurred_events->events=0;
16211645

16221646
if (cur_event->events==WL_LATCH_SET&&
1623-
cur_kqueue_event->filter==EVFILT_READ)
1647+
cur_kqueue_event->filter==EVFILT_SIGNAL)
16241648
{
1625-
/* There's data in the self-pipe, clear it. */
1626-
drain();
1627-
16281649
if (set->latch&&set->latch->is_set)
16291650
{
16301651
occurred_events->fd=PGINVALID_SOCKET;
@@ -1999,7 +2020,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
19992020
}
20002021
#endif
20012022

2002-
#if defined(WAIT_USE_POLL)|| defined(WAIT_USE_KQUEUE)
2023+
#if defined(WAIT_USE_POLL)
20032024

20042025
/*
20052026
* SetLatch uses SIGURG to wake up the process waiting on the latch.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp