/* ---------- * wait_event.c * Wait event reporting infrastructure. * * Copyright (c) 2001-2023, PostgreSQL Global Development Group * * * IDENTIFICATION * src/backend/utils/activity/wait_event.c * * NOTES * * To make pgstat_report_wait_start() and pgstat_report_wait_end() as * lightweight as possible, they do not check if shared memory (MyProc * specifically, where the wait event is stored) is already available. Instead * we initially set my_wait_event_info to a process local variable, which then * is redirected to shared memory using pgstat_set_wait_event_storage(). For * the same reason pgstat_track_activities is not checked - the check adds * more work than it saves. * * ---------- */ #include "postgres.h" #include "storage/lmgr.h" /* for GetLockNameFromTagType */ #include "storage/lwlock.h" /* for GetLWLockIdentifier */ #include "utils/wait_event.h" static const char *pgstat_get_wait_activity(WaitEventActivity w); static const char *pgstat_get_wait_bufferpin(WaitEventBufferPin w); static const char *pgstat_get_wait_client(WaitEventClient w); static const char *pgstat_get_wait_extension(WaitEventExtension w); static const char *pgstat_get_wait_ipc(WaitEventIPC w); static const char *pgstat_get_wait_timeout(WaitEventTimeout w); static const char *pgstat_get_wait_io(WaitEventIO w); static uint32 local_my_wait_event_info; uint32 *my_wait_event_info = &local_my_wait_event_info; /* * Configure wait event reporting to report wait events to *wait_event_info. * *wait_event_info needs to be valid until pgstat_reset_wait_event_storage() * is called. * * Expected to be called during backend startup, to point my_wait_event_info * into shared memory. */ void pgstat_set_wait_event_storage(uint32 *wait_event_info) { my_wait_event_info = wait_event_info; } /* * Reset wait event storage location. * * Expected to be called during backend shutdown, before the location set up * pgstat_set_wait_event_storage() becomes invalid. */ void pgstat_reset_wait_event_storage(void) { my_wait_event_info = &local_my_wait_event_info; } /* ---------- * pgstat_get_wait_event_type() - * * Return a string representing the current wait event type, backend is * waiting on. */ const char * pgstat_get_wait_event_type(uint32 wait_event_info) { uint32 classId; const char *event_type; /* report process as not waiting. */ if (wait_event_info == 0) return NULL; classId = wait_event_info & 0xFF000000; switch (classId) { case PG_WAIT_LWLOCK: event_type = "LWLock"; break; case PG_WAIT_LOCK: event_type = "Lock"; break; case PG_WAIT_BUFFERPIN: event_type = "BufferPin"; break; case PG_WAIT_ACTIVITY: event_type = "Activity"; break; case PG_WAIT_CLIENT: event_type = "Client"; break; case PG_WAIT_EXTENSION: event_type = "Extension"; break; case PG_WAIT_IPC: event_type = "IPC"; break; case PG_WAIT_TIMEOUT: event_type = "Timeout"; break; case PG_WAIT_IO: event_type = "IO"; break; default: event_type = "???"; break; } return event_type; } /* ---------- * pgstat_get_wait_event() - * * Return a string representing the current wait event, backend is * waiting on. */ const char * pgstat_get_wait_event(uint32 wait_event_info) { uint32 classId; uint16 eventId; const char *event_name; /* report process as not waiting. */ if (wait_event_info == 0) return NULL; classId = wait_event_info & 0xFF000000; eventId = wait_event_info & 0x0000FFFF; switch (classId) { case PG_WAIT_LWLOCK: event_name = GetLWLockIdentifier(classId, eventId); break; case PG_WAIT_LOCK: event_name = GetLockNameFromTagType(eventId); break; case PG_WAIT_BUFFERPIN: { WaitEventBufferPin w = (WaitEventBufferPin) wait_event_info; event_name = pgstat_get_wait_bufferpin(w); break; } case PG_WAIT_ACTIVITY: { WaitEventActivity w = (WaitEventActivity) wait_event_info; event_name = pgstat_get_wait_activity(w); break; } case PG_WAIT_CLIENT: { WaitEventClient w = (WaitEventClient) wait_event_info; event_name = pgstat_get_wait_client(w); break; } case PG_WAIT_EXTENSION: { WaitEventExtension w = (WaitEventExtension) wait_event_info; event_name = pgstat_get_wait_extension(w); break; } case PG_WAIT_IPC: { WaitEventIPC w = (WaitEventIPC) wait_event_info; event_name = pgstat_get_wait_ipc(w); break; } case PG_WAIT_TIMEOUT: { WaitEventTimeout w = (WaitEventTimeout) wait_event_info; event_name = pgstat_get_wait_timeout(w); break; } case PG_WAIT_IO: { WaitEventIO w = (WaitEventIO) wait_event_info; event_name = pgstat_get_wait_io(w); break; } default: event_name = "unknown wait event"; break; } return event_name; } #include "pgstat_wait_event.c"