Skip to content

Commit 2cb82e2

Browse files
committed
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 de2aca2 commit 2cb82e2

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)