Skip to content

Commit 9ae72c5

Browse files
david-rowleypull[bot]
authored andcommitted
Speedup and increase usability of set proc title functions
The setting of the process title could be seen on profiles of very fast-to-execute queries. In many locations where we call set_ps_display() we pass along a string constant, the length of which is known during compilation. Here we effectively rename set_ps_display() to set_ps_display_with_len() and then add a static inline function named set_ps_display() which calls strlen() on the given string. This allows the compiler to optimize away the strlen() call when dealing with call sites passing a string constant. We can then also use memcpy() instead of strlcpy() to copy the string into the destination buffer. That's significantly faster than strlcpy's byte-at-a-time way of copying. Here we also take measures to improve some code which was adjusting the process title to add a " waiting" suffix to it. Call sites which require this can now just call set_ps_display_suffix() to add or adjust the suffix and call set_ps_display_remove_suffix() to remove it again. Reviewed-by: Andres Freund Discussion: https://postgr.es/m/CAApHDvocBvvk-0gWNA2Gohe+sv9fMcv+fK_G+siBKJrgDG4O7g@mail.gmail.com
1 parent bf17b4b commit 9ae72c5

File tree

7 files changed

+199
-95
lines changed

7 files changed

+199
-95
lines changed

src/backend/replication/syncrep.c

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,6 @@ static bool SyncRepQueueIsOrderedByLSN(int mode);
148148
void
149149
SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
150150
{
151-
char *new_status = NULL;
152-
const char *old_status;
153151
int mode;
154152

155153
/*
@@ -216,15 +214,10 @@ SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
216214
/* Alter ps display to show waiting for sync rep. */
217215
if (update_process_title)
218216
{
219-
int len;
220-
221-
old_status = get_ps_display(&len);
222-
new_status = (char *) palloc(len + 32 + 1);
223-
memcpy(new_status, old_status, len);
224-
sprintf(new_status + len, " waiting for %X/%X",
225-
LSN_FORMAT_ARGS(lsn));
226-
set_ps_display(new_status);
227-
new_status[len] = '\0'; /* truncate off " waiting ..." */
217+
char buffer[32];
218+
219+
sprintf(buffer, "waiting for %X/%X", LSN_FORMAT_ARGS(lsn));
220+
set_ps_display_suffix(buffer);
228221
}
229222

230223
/*
@@ -322,12 +315,9 @@ SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
322315
MyProc->syncRepState = SYNC_REP_NOT_WAITING;
323316
MyProc->waitLSN = 0;
324317

325-
if (new_status)
326-
{
327-
/* Reset ps display */
328-
set_ps_display(new_status);
329-
pfree(new_status);
330-
}
318+
/* reset ps display to remove the suffix */
319+
if (update_process_title)
320+
set_ps_display_remove_suffix();
331321
}
332322

333323
/*

src/backend/storage/buffer/bufmgr.c

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4302,8 +4302,8 @@ void
43024302
LockBufferForCleanup(Buffer buffer)
43034303
{
43044304
BufferDesc *bufHdr;
4305-
char *new_status = NULL;
43064305
TimestampTz waitStart = 0;
4306+
bool waiting = false;
43074307
bool logged_recovery_conflict = false;
43084308

43094309
Assert(BufferIsPinned(buffer));
@@ -4350,11 +4350,11 @@ LockBufferForCleanup(Buffer buffer)
43504350
waitStart, GetCurrentTimestamp(),
43514351
NULL, false);
43524352

4353-
/* Report change to non-waiting status */
4354-
if (new_status)
4353+
if (waiting)
43554354
{
4356-
set_ps_display(new_status);
4357-
pfree(new_status);
4355+
/* reset ps display to remove the suffix if we added one */
4356+
set_ps_display_remove_suffix();
4357+
waiting = false;
43584358
}
43594359
return;
43604360
}
@@ -4374,18 +4374,11 @@ LockBufferForCleanup(Buffer buffer)
43744374
/* Wait to be signaled by UnpinBuffer() */
43754375
if (InHotStandby)
43764376
{
4377-
/* Report change to waiting status */
4378-
if (update_process_title && new_status == NULL)
4377+
if (!waiting)
43794378
{
4380-
const char *old_status;
4381-
int len;
4382-
4383-
old_status = get_ps_display(&len);
4384-
new_status = (char *) palloc(len + 8 + 1);
4385-
memcpy(new_status, old_status, len);
4386-
strcpy(new_status + len, " waiting");
4387-
set_ps_display(new_status);
4388-
new_status[len] = '\0'; /* truncate off " waiting" */
4379+
/* adjust the process title to indicate that it's waiting */
4380+
set_ps_display_suffix("waiting");
4381+
waiting = true;
43894382
}
43904383

43914384
/*

src/backend/storage/ipc/standby.c

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
362362
bool report_waiting)
363363
{
364364
TimestampTz waitStart = 0;
365-
char *new_status = NULL;
365+
bool waiting = false;
366366
bool logged_recovery_conflict = false;
367367

368368
/* Fast exit, to avoid a kernel call if there's no work to be done. */
@@ -400,14 +400,14 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
400400
pg_usleep(5000L);
401401
}
402402

403-
if (waitStart != 0 && (!logged_recovery_conflict || new_status == NULL))
403+
if (waitStart != 0 && (!logged_recovery_conflict || !waiting))
404404
{
405405
TimestampTz now = 0;
406406
bool maybe_log_conflict;
407407
bool maybe_update_title;
408408

409409
maybe_log_conflict = (log_recovery_conflict_waits && !logged_recovery_conflict);
410-
maybe_update_title = (update_process_title && new_status == NULL);
410+
maybe_update_title = (update_process_title && !waiting);
411411

412412
/* Get the current timestamp if not report yet */
413413
if (maybe_log_conflict || maybe_update_title)
@@ -420,15 +420,8 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
420420
if (maybe_update_title &&
421421
TimestampDifferenceExceeds(waitStart, now, 500))
422422
{
423-
const char *old_status;
424-
int len;
425-
426-
old_status = get_ps_display(&len);
427-
new_status = (char *) palloc(len + 8 + 1);
428-
memcpy(new_status, old_status, len);
429-
strcpy(new_status + len, " waiting");
430-
set_ps_display(new_status);
431-
new_status[len] = '\0'; /* truncate off " waiting" */
423+
set_ps_display_suffix("waiting");
424+
waiting = true;
432425
}
433426

434427
/*
@@ -456,12 +449,10 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
456449
LogRecoveryConflict(reason, waitStart, GetCurrentTimestamp(),
457450
NULL, false);
458451

459-
/* Reset ps display if we changed it */
460-
if (new_status)
461-
{
462-
set_ps_display(new_status);
463-
pfree(new_status);
464-
}
452+
/* reset ps display to remove the suffix if we added one */
453+
if (waiting)
454+
set_ps_display_remove_suffix();
455+
465456
}
466457

467458
/*

src/backend/storage/lmgr/lock.c

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,24 +1810,12 @@ WaitOnLock(LOCALLOCK *locallock, ResourceOwner owner)
18101810
{
18111811
LOCKMETHODID lockmethodid = LOCALLOCK_LOCKMETHOD(*locallock);
18121812
LockMethod lockMethodTable = LockMethods[lockmethodid];
1813-
char *volatile new_status = NULL;
18141813

18151814
LOCK_PRINT("WaitOnLock: sleeping on lock",
18161815
locallock->lock, locallock->tag.mode);
18171816

1818-
/* Report change to waiting status */
1819-
if (update_process_title)
1820-
{
1821-
const char *old_status;
1822-
int len;
1823-
1824-
old_status = get_ps_display(&len);
1825-
new_status = (char *) palloc(len + 8 + 1);
1826-
memcpy(new_status, old_status, len);
1827-
strcpy(new_status + len, " waiting");
1828-
set_ps_display(new_status);
1829-
new_status[len] = '\0'; /* truncate off " waiting" */
1830-
}
1817+
/* adjust the process title to indicate that it's waiting */
1818+
set_ps_display_suffix("waiting");
18311819

18321820
awaitedLock = locallock;
18331821
awaitedOwner = owner;
@@ -1874,12 +1862,8 @@ WaitOnLock(LOCALLOCK *locallock, ResourceOwner owner)
18741862
{
18751863
/* In this path, awaitedLock remains set until LockErrorCleanup */
18761864

1877-
/* Report change to non-waiting status */
1878-
if (update_process_title)
1879-
{
1880-
set_ps_display(new_status);
1881-
pfree(new_status);
1882-
}
1865+
/* reset ps display to remove the suffix */
1866+
set_ps_display_remove_suffix();
18831867

18841868
/* and propagate the error */
18851869
PG_RE_THROW();
@@ -1888,12 +1872,8 @@ WaitOnLock(LOCALLOCK *locallock, ResourceOwner owner)
18881872

18891873
awaitedLock = NULL;
18901874

1891-
/* Report change to non-waiting status */
1892-
if (update_process_title)
1893-
{
1894-
set_ps_display(new_status);
1895-
pfree(new_status);
1896-
}
1875+
/* reset ps display to remove the suffix */
1876+
set_ps_display_remove_suffix();
18971877

18981878
LOCK_PRINT("WaitOnLock: wakeup on lock",
18991879
locallock->lock, locallock->tag.mode);

src/backend/tcop/postgres.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,6 +1071,8 @@ exec_simple_query(const char *query_string)
10711071
Portal portal;
10721072
DestReceiver *receiver;
10731073
int16 format;
1074+
const char *cmdtagname;
1075+
size_t cmdtaglen;
10741076

10751077
pgstat_report_query_id(0, true);
10761078

@@ -1081,8 +1083,9 @@ exec_simple_query(const char *query_string)
10811083
* destination.
10821084
*/
10831085
commandTag = CreateCommandTag(parsetree->stmt);
1086+
cmdtagname = GetCommandTagNameAndLen(commandTag, &cmdtaglen);
10841087

1085-
set_ps_display(GetCommandTagName(commandTag));
1088+
set_ps_display_with_len(cmdtagname, cmdtaglen);
10861089

10871090
BeginCommand(commandTag, dest);
10881091

@@ -2064,6 +2067,8 @@ exec_execute_message(const char *portal_name, long max_rows)
20642067
char msec_str[32];
20652068
ParamsErrorCbData params_data;
20662069
ErrorContextCallback params_errcxt;
2070+
const char *cmdtagname;
2071+
size_t cmdtaglen;
20672072

20682073
/* Adjust destination to tell printtup.c what to do */
20692074
dest = whereToSendOutput;
@@ -2110,7 +2115,9 @@ exec_execute_message(const char *portal_name, long max_rows)
21102115

21112116
pgstat_report_activity(STATE_RUNNING, sourceText);
21122117

2113-
set_ps_display(GetCommandTagName(portal->commandTag));
2118+
cmdtagname = GetCommandTagNameAndLen(portal->commandTag, &cmdtaglen);
2119+
2120+
set_ps_display_with_len(cmdtagname, cmdtaglen);
21142121

21152122
if (save_log_statement_stats)
21162123
ResetUsage();

0 commit comments

Comments
 (0)