agora inbox for [email protected]help / color / mirror / Atom feed
[PATCH v2] WIP: Evaluate arguments of correlated SubPlans in the referencing ExprState 383+ messages / 5 participants [nested] [flat]
* [PATCH v1] WIP: Evaluate arguments of correlated SubPlans in the referencing ExprState @ 2023-02-25 21:39 Andres Freund <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Andres Freund @ 2023-02-25 21:39 UTC (permalink / raw) --- src/include/nodes/execnodes.h | 1 - src/backend/executor/execExpr.c | 81 +++++++++++++++++------------ src/backend/executor/execProcnode.c | 5 ++ src/backend/executor/nodeSubplan.c | 30 +++++------ 4 files changed, 66 insertions(+), 51 deletions(-) diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 20f4c8b35f3..437cf8b5a02 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -947,7 +947,6 @@ typedef struct SubPlanState struct PlanState *planstate; /* subselect plan's state tree */ struct PlanState *parent; /* parent plan node's state tree */ ExprState *testexpr; /* state of combining expression */ - List *args; /* states of argument expression(s) */ HeapTuple curTuple; /* copy of most recent tuple from subplan */ Datum curArray; /* most recent array from ARRAY() subplan */ /* these are used when hashing the subselect's output: */ diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c index c61f23c6c18..7a9d5729b4b 100644 --- a/src/backend/executor/execExpr.c +++ b/src/backend/executor/execExpr.c @@ -87,6 +87,9 @@ static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate, FunctionCallInfo fcinfo, AggStatePerTrans pertrans, int transno, int setno, int setoff, bool ishash, bool nullcheck); +static void ExecInitSubPlanExpr(SubPlan *subplan, + ExprState *state, + Datum *resv, bool *resnull); /* @@ -1388,7 +1391,6 @@ ExecInitExprRec(Expr *node, ExprState *state, case T_SubPlan: { SubPlan *subplan = (SubPlan *) node; - SubPlanState *sstate; /* * Real execution of a MULTIEXPR SubPlan has already been @@ -1405,19 +1407,7 @@ ExecInitExprRec(Expr *node, ExprState *state, break; } - if (!state->parent) - elog(ERROR, "SubPlan found with no parent plan"); - - sstate = ExecInitSubPlan(subplan, state->parent); - - /* add SubPlanState nodes to state->parent->subPlan */ - state->parent->subPlan = lappend(state->parent->subPlan, - sstate); - - scratch.opcode = EEOP_SUBPLAN; - scratch.d.subplan.sstate = sstate; - - ExprEvalPushStep(state, &scratch); + ExecInitSubPlanExpr(subplan, state, resv, resnull); break; } @@ -2618,29 +2608,12 @@ ExecPushExprSetupSteps(ExprState *state, ExprSetupInfo *info) foreach(lc, info->multiexpr_subplans) { SubPlan *subplan = (SubPlan *) lfirst(lc); - SubPlanState *sstate; Assert(subplan->subLinkType == MULTIEXPR_SUBLINK); - /* This should match what ExecInitExprRec does for other SubPlans: */ - - if (!state->parent) - elog(ERROR, "SubPlan found with no parent plan"); - - sstate = ExecInitSubPlan(subplan, state->parent); - - /* add SubPlanState nodes to state->parent->subPlan */ - state->parent->subPlan = lappend(state->parent->subPlan, - sstate); - - scratch.opcode = EEOP_SUBPLAN; - scratch.d.subplan.sstate = sstate; - /* The result can be ignored, but we better put it somewhere */ - scratch.resvalue = &state->resvalue; - scratch.resnull = &state->resnull; - - ExprEvalPushStep(state, &scratch); + ExecInitSubPlanExpr(subplan, state, + &state->resvalue, &state->resnull); } } @@ -4040,3 +4013,45 @@ ExecBuildParamSetEqual(TupleDesc desc, return state; } + +static void +ExecInitSubPlanExpr(SubPlan *subplan, + ExprState *state, + Datum *resv, bool *resnull) +{ + ExprEvalStep scratch = {0}; + SubPlanState *sstate; + ListCell *pvar; + ListCell *l; + EState *estate = state->parent->state; + + if (!state->parent) + elog(ERROR, "SubPlan found with no parent plan"); + + /* + * Generate steps to evaluate input arguments for the subplan. + * + * Any calculation we have to do can be done in the parent econtext, since + * the Param values don't need to have per-query lifetime. + */ + forboth(l, subplan->parParam, pvar, subplan->args) + { + int paramid = lfirst_int(l); + ParamExecData *prm = &estate->es_param_exec_vals[paramid]; + + ExecInitExprRec(lfirst(pvar), state, &prm->value, &prm->isnull); + } + + sstate = ExecInitSubPlan(subplan, state->parent); + + /* add SubPlanState nodes to state->parent->subPlan */ + state->parent->subPlan = lappend(state->parent->subPlan, + sstate); + + scratch.opcode = EEOP_SUBPLAN; + scratch.resvalue = resv; + scratch.resnull = resnull; + scratch.d.subplan.sstate = sstate; + + ExprEvalPushStep(state, &scratch); +} diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c index 4d288bc8d41..f62bb28140f 100644 --- a/src/backend/executor/execProcnode.c +++ b/src/backend/executor/execProcnode.c @@ -393,6 +393,10 @@ ExecInitNode(Plan *node, EState *estate, int eflags) /* * Initialize any initPlans present in this node. The planner put them in * a separate list for us. + * + * The defining characteristic of initplans is that they don't have + * arguments, so we don't need to evaluate them (in contrast to + * ExecInitSubPlanExpr()). */ subps = NIL; foreach(l, node->initPlan) @@ -401,6 +405,7 @@ ExecInitNode(Plan *node, EState *estate, int eflags) SubPlanState *sstate; Assert(IsA(subplan, SubPlan)); + Assert(subplan->args == NIL); sstate = ExecInitSubPlan(subplan, result); subps = lappend(subps, sstate); } diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c index c136f75ac24..3458ac007cd 100644 --- a/src/backend/executor/nodeSubplan.c +++ b/src/backend/executor/nodeSubplan.c @@ -107,7 +107,7 @@ ExecHashSubPlan(SubPlanState *node, TupleTableSlot *slot; /* Shouldn't have any direct correlation Vars */ - if (subplan->parParam != NIL || node->args != NIL) + if (subplan->parParam != NIL || subplan->args != NIL) elog(ERROR, "hashed subplan with direct correlation not supported"); /* @@ -231,7 +231,6 @@ ExecScanSubPlan(SubPlanState *node, TupleTableSlot *slot; Datum result; bool found = false; /* true if got at least one subplan tuple */ - ListCell *pvar; ListCell *l; ArrayBuildStateAny *astate = NULL; @@ -248,26 +247,20 @@ ExecScanSubPlan(SubPlanState *node, oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory); /* - * Set Params of this plan from parent plan correlation values. (Any - * calculation we have to do is done in the parent econtext, since the - * Param values don't need to have per-query lifetime.) + * We rely on the caller to evaluate plan correlation values, if + * necessary. However we still need to record the fact that the values + * (might have) changed, otherwise the ExecReScan() below won't know that + * nodes need to be rescanned. */ - Assert(list_length(subplan->parParam) == list_length(node->args)); - - forboth(l, subplan->parParam, pvar, node->args) + Assert(list_length(subplan->parParam) == list_length(subplan->args)); + foreach(l, subplan->parParam) { int paramid = lfirst_int(l); - ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]); - prm->value = ExecEvalExprSwitchContext((ExprState *) lfirst(pvar), - econtext, - &(prm->isnull)); planstate->chgParam = bms_add_member(planstate->chgParam, paramid); } - /* - * Now that we've set up its parameters, we can reset the subplan. - */ + /* with that done, we can reset the subplan */ ExecReScan(planstate); /* @@ -817,6 +810,10 @@ slotNoNulls(TupleTableSlot *slot) * as well as regular SubPlans. Note that we don't link the SubPlan into * the parent's subPlan list, because that shouldn't happen for InitPlans. * Instead, ExecInitExpr() does that one part. + * + * We also rely on ExecInitExpr(), more precisely ExecInitSubPlanExpr(), to + * evaluate input parameters, as that allows them to be evaluated as part of + * the expression referencing the SubPlan. * ---------------------------------------------------------------- */ SubPlanState * @@ -844,7 +841,6 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) /* Initialize subexpressions */ sstate->testexpr = ExecInitExpr((Expr *) subplan->testexpr, parent); - sstate->args = ExecInitExprList(subplan->args, parent); /* * initialize my state @@ -1107,7 +1103,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext) elog(ERROR, "ANY/ALL subselect unsupported as initplan"); if (subLinkType == CTE_SUBLINK) elog(ERROR, "CTE subplans should not be executed via ExecSetParamPlan"); - if (subplan->parParam || node->args) + if (subplan->parParam || subplan->args) elog(ERROR, "correlated subplans should not be executed via ExecSetParamPlan"); /* -- 2.38.0 --6ir4gcdcv6d4j3qy-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2] WIP: Evaluate arguments of correlated SubPlans in the referencing ExprState @ 2023-02-25 21:39 Andres Freund <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Andres Freund @ 2023-02-25 21:39 UTC (permalink / raw) --- src/include/executor/execExpr.h | 6 +- src/include/nodes/execnodes.h | 1 - src/backend/executor/execExpr.c | 93 +++++++++++++++++---------- src/backend/executor/execExprInterp.c | 22 +++++++ src/backend/executor/execProcnode.c | 5 ++ src/backend/executor/nodeSubplan.c | 30 ++++----- src/backend/jit/llvm/llvmjit_expr.c | 6 ++ src/backend/jit/llvm/llvmjit_types.c | 1 + 8 files changed, 112 insertions(+), 52 deletions(-) diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h index 06c3adc0a19..ca2b7306cd0 100644 --- a/src/include/executor/execExpr.h +++ b/src/include/executor/execExpr.h @@ -158,6 +158,8 @@ typedef enum ExprEvalOp EEOP_PARAM_EXEC, EEOP_PARAM_EXTERN, EEOP_PARAM_CALLBACK, + /* set PARAM_EXEC value */ + EEOP_PARAM_SET, /* return CaseTestExpr value */ EEOP_CASE_TESTVAL, @@ -374,7 +376,7 @@ typedef struct ExprEvalStep ExprEvalRowtypeCache rowcache; } nulltest_row; - /* for EEOP_PARAM_EXEC/EXTERN */ + /* for EEOP_PARAM_EXEC/EXTERN and EEOP_PARAM_SET */ struct { int paramid; /* numeric ID for parameter */ @@ -738,6 +740,8 @@ extern void ExecEvalParamExec(ExprState *state, ExprEvalStep *op, ExprContext *econtext); extern void ExecEvalParamExtern(ExprState *state, ExprEvalStep *op, ExprContext *econtext); +extern void ExecEvalParamSet(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); extern void ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op); extern void ExecEvalNextValueExpr(ExprState *state, ExprEvalStep *op); extern void ExecEvalRowNull(ExprState *state, ExprEvalStep *op, diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index e7eb1e666ff..16e95e4cb48 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -947,7 +947,6 @@ typedef struct SubPlanState struct PlanState *planstate; /* subselect plan's state tree */ struct PlanState *parent; /* parent plan node's state tree */ ExprState *testexpr; /* state of combining expression */ - List *args; /* states of argument expression(s) */ HeapTuple curTuple; /* copy of most recent tuple from subplan */ Datum curArray; /* most recent array from ARRAY() subplan */ /* these are used when hashing the subselect's output: */ diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c index c61f23c6c18..002f2a0091f 100644 --- a/src/backend/executor/execExpr.c +++ b/src/backend/executor/execExpr.c @@ -87,6 +87,9 @@ static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate, FunctionCallInfo fcinfo, AggStatePerTrans pertrans, int transno, int setno, int setoff, bool ishash, bool nullcheck); +static void ExecInitSubPlanExpr(SubPlan *subplan, + ExprState *state, + Datum *resv, bool *resnull); /* @@ -1388,7 +1391,6 @@ ExecInitExprRec(Expr *node, ExprState *state, case T_SubPlan: { SubPlan *subplan = (SubPlan *) node; - SubPlanState *sstate; /* * Real execution of a MULTIEXPR SubPlan has already been @@ -1405,19 +1407,7 @@ ExecInitExprRec(Expr *node, ExprState *state, break; } - if (!state->parent) - elog(ERROR, "SubPlan found with no parent plan"); - - sstate = ExecInitSubPlan(subplan, state->parent); - - /* add SubPlanState nodes to state->parent->subPlan */ - state->parent->subPlan = lappend(state->parent->subPlan, - sstate); - - scratch.opcode = EEOP_SUBPLAN; - scratch.d.subplan.sstate = sstate; - - ExprEvalPushStep(state, &scratch); + ExecInitSubPlanExpr(subplan, state, resv, resnull); break; } @@ -2618,29 +2608,12 @@ ExecPushExprSetupSteps(ExprState *state, ExprSetupInfo *info) foreach(lc, info->multiexpr_subplans) { SubPlan *subplan = (SubPlan *) lfirst(lc); - SubPlanState *sstate; Assert(subplan->subLinkType == MULTIEXPR_SUBLINK); - /* This should match what ExecInitExprRec does for other SubPlans: */ - - if (!state->parent) - elog(ERROR, "SubPlan found with no parent plan"); - - sstate = ExecInitSubPlan(subplan, state->parent); - - /* add SubPlanState nodes to state->parent->subPlan */ - state->parent->subPlan = lappend(state->parent->subPlan, - sstate); - - scratch.opcode = EEOP_SUBPLAN; - scratch.d.subplan.sstate = sstate; - /* The result can be ignored, but we better put it somewhere */ - scratch.resvalue = &state->resvalue; - scratch.resnull = &state->resnull; - - ExprEvalPushStep(state, &scratch); + ExecInitSubPlanExpr(subplan, state, + &state->resvalue, &state->resnull); } } @@ -4040,3 +4013,57 @@ ExecBuildParamSetEqual(TupleDesc desc, return state; } + +static void +ExecInitSubPlanExpr(SubPlan *subplan, + ExprState *state, + Datum *resv, bool *resnull) +{ + ExprEvalStep scratch = {0}; + SubPlanState *sstate; + ListCell *pvar; + ListCell *l; + + if (!state->parent) + elog(ERROR, "SubPlan found with no parent plan"); + + /* + * Generate steps to evaluate input arguments for the subplan. + * + * We evaluate the argument expressions into ExprState's resvalue/resnull, + * and then use PARAM_SET to update the parameter. We do that, instead of + * evaluating directly into the param, to avoid depending on the pointer + * value remaining stable / being included in the generated expression. No + * danger of conflicts with other uses of resvalue/resnull as storing and + * using the value always is in subsequent steps. + * + * Any calculation we have to do can be done in the parent econtext, since + * the Param values don't need to have per-query lifetime. + */ + forboth(l, subplan->parParam, pvar, subplan->args) + { + int paramid = lfirst_int(l); + + ExecInitExprRec(lfirst(pvar), state, + &state->resvalue, &state->resnull); + + scratch.opcode = EEOP_PARAM_SET; + scratch.d.param.paramid = paramid; + /* type isn't needed, but an old value could be confusing */ + scratch.d.param.paramtype = InvalidOid; + ExprEvalPushStep(state, &scratch); + } + + sstate = ExecInitSubPlan(subplan, state->parent); + + /* add SubPlanState nodes to state->parent->subPlan */ + state->parent->subPlan = lappend(state->parent->subPlan, + sstate); + + scratch.opcode = EEOP_SUBPLAN; + scratch.resvalue = resv; + scratch.resnull = resnull; + scratch.d.subplan.sstate = sstate; + + ExprEvalPushStep(state, &scratch); +} diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index 19351fe34bf..3cab8a5cdae 100644 --- a/src/backend/executor/execExprInterp.c +++ b/src/backend/executor/execExprInterp.c @@ -446,6 +446,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) &&CASE_EEOP_PARAM_EXEC, &&CASE_EEOP_PARAM_EXTERN, &&CASE_EEOP_PARAM_CALLBACK, + &&CASE_EEOP_PARAM_SET, &&CASE_EEOP_CASE_TESTVAL, &&CASE_EEOP_MAKE_READONLY, &&CASE_EEOP_IOCOERCE, @@ -1081,6 +1082,13 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) EEO_NEXT(); } + EEO_CASE(EEOP_PARAM_SET) + { + /* out of line, unlikely to matter performancewise */ + ExecEvalParamSet(state, op, econtext); + EEO_NEXT(); + } + EEO_CASE(EEOP_CASE_TESTVAL) { /* @@ -2477,6 +2485,20 @@ ExecEvalParamExtern(ExprState *state, ExprEvalStep *op, ExprContext *econtext) errmsg("no value found for parameter %d", paramId))); } +/* + * Set value of a param (currently always PARAM_EXEC) from + * state->res{value,null}. + */ +void +ExecEvalParamSet(ExprState *state, ExprEvalStep *op, ExprContext *econtext) +{ + ParamExecData *prm; + + prm = &(econtext->ecxt_param_exec_vals[op->d.param.paramid]); + prm->value = state->resvalue; + prm->isnull = state->resnull; +} + /* * Raise error if a CURRENT OF expression is evaluated. * diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c index 4d288bc8d41..f62bb28140f 100644 --- a/src/backend/executor/execProcnode.c +++ b/src/backend/executor/execProcnode.c @@ -393,6 +393,10 @@ ExecInitNode(Plan *node, EState *estate, int eflags) /* * Initialize any initPlans present in this node. The planner put them in * a separate list for us. + * + * The defining characteristic of initplans is that they don't have + * arguments, so we don't need to evaluate them (in contrast to + * ExecInitSubPlanExpr()). */ subps = NIL; foreach(l, node->initPlan) @@ -401,6 +405,7 @@ ExecInitNode(Plan *node, EState *estate, int eflags) SubPlanState *sstate; Assert(IsA(subplan, SubPlan)); + Assert(subplan->args == NIL); sstate = ExecInitSubPlan(subplan, result); subps = lappend(subps, sstate); } diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c index c136f75ac24..3458ac007cd 100644 --- a/src/backend/executor/nodeSubplan.c +++ b/src/backend/executor/nodeSubplan.c @@ -107,7 +107,7 @@ ExecHashSubPlan(SubPlanState *node, TupleTableSlot *slot; /* Shouldn't have any direct correlation Vars */ - if (subplan->parParam != NIL || node->args != NIL) + if (subplan->parParam != NIL || subplan->args != NIL) elog(ERROR, "hashed subplan with direct correlation not supported"); /* @@ -231,7 +231,6 @@ ExecScanSubPlan(SubPlanState *node, TupleTableSlot *slot; Datum result; bool found = false; /* true if got at least one subplan tuple */ - ListCell *pvar; ListCell *l; ArrayBuildStateAny *astate = NULL; @@ -248,26 +247,20 @@ ExecScanSubPlan(SubPlanState *node, oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory); /* - * Set Params of this plan from parent plan correlation values. (Any - * calculation we have to do is done in the parent econtext, since the - * Param values don't need to have per-query lifetime.) + * We rely on the caller to evaluate plan correlation values, if + * necessary. However we still need to record the fact that the values + * (might have) changed, otherwise the ExecReScan() below won't know that + * nodes need to be rescanned. */ - Assert(list_length(subplan->parParam) == list_length(node->args)); - - forboth(l, subplan->parParam, pvar, node->args) + Assert(list_length(subplan->parParam) == list_length(subplan->args)); + foreach(l, subplan->parParam) { int paramid = lfirst_int(l); - ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]); - prm->value = ExecEvalExprSwitchContext((ExprState *) lfirst(pvar), - econtext, - &(prm->isnull)); planstate->chgParam = bms_add_member(planstate->chgParam, paramid); } - /* - * Now that we've set up its parameters, we can reset the subplan. - */ + /* with that done, we can reset the subplan */ ExecReScan(planstate); /* @@ -817,6 +810,10 @@ slotNoNulls(TupleTableSlot *slot) * as well as regular SubPlans. Note that we don't link the SubPlan into * the parent's subPlan list, because that shouldn't happen for InitPlans. * Instead, ExecInitExpr() does that one part. + * + * We also rely on ExecInitExpr(), more precisely ExecInitSubPlanExpr(), to + * evaluate input parameters, as that allows them to be evaluated as part of + * the expression referencing the SubPlan. * ---------------------------------------------------------------- */ SubPlanState * @@ -844,7 +841,6 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) /* Initialize subexpressions */ sstate->testexpr = ExecInitExpr((Expr *) subplan->testexpr, parent); - sstate->args = ExecInitExprList(subplan->args, parent); /* * initialize my state @@ -1107,7 +1103,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext) elog(ERROR, "ANY/ALL subselect unsupported as initplan"); if (subLinkType == CTE_SUBLINK) elog(ERROR, "CTE subplans should not be executed via ExecSetParamPlan"); - if (subplan->parParam || node->args) + if (subplan->parParam || subplan->args) elog(ERROR, "correlated subplans should not be executed via ExecSetParamPlan"); /* diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c index 1c722c79552..812f8758743 100644 --- a/src/backend/jit/llvm/llvmjit_expr.c +++ b/src/backend/jit/llvm/llvmjit_expr.c @@ -1094,6 +1094,12 @@ llvm_compile_expr(ExprState *state) break; } + case EEOP_PARAM_SET: + build_EvalXFunc(b, mod, "ExecEvalParamSet", + v_state, op, v_econtext); + LLVMBuildBr(b, opblocks[opno + 1]); + break; + case EEOP_SBSREF_SUBSCRIPTS: { int jumpdone = op->d.sbsref_subscript.jumpdone; diff --git a/src/backend/jit/llvm/llvmjit_types.c b/src/backend/jit/llvm/llvmjit_types.c index 876fb640294..0b1df3afe00 100644 --- a/src/backend/jit/llvm/llvmjit_types.c +++ b/src/backend/jit/llvm/llvmjit_types.c @@ -123,6 +123,7 @@ void *referenced_functions[] = ExecEvalNextValueExpr, ExecEvalParamExec, ExecEvalParamExtern, + ExecEvalParamSet, ExecEvalRow, ExecEvalRowNotNull, ExecEvalRowNull, -- 2.37.1.188.g71a8fab31b --2fo66m5ddj2bowyf-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v30 09/11] Add support for min/max aggregates for IVM @ 2023-05-31 11:58 Yugo Nagata <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Yugo Nagata @ 2023-05-31 11:58 UTC (permalink / raw) Supporting min and max is more complicated than count, sum, or avg. For an example of min, when tuples are inserted, the current min value in the view and the min value in the inseteted tuples are compared, then the smaller one is used as the latest min value. On the other hand, when tuples are deleted, if the current min value in the view equals to the min in the deleted tuples, we need re-computation the latest min value from base tables. Otherwise, the current value in the view remains. --- src/backend/commands/createas.c | 45 +++ src/backend/commands/matview.c | 644 +++++++++++++++++++++++++++++++- 2 files changed, 680 insertions(+), 9 deletions(-) diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index d93eec3eec..0536e44b9e 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -1312,6 +1312,51 @@ check_aggregate_supports_ivm(Oid aggfnoid) case F_AVG_FLOAT8: case F_AVG_INTERVAL: + /* min */ + case F_MIN_ANYARRAY: + case F_MIN_INT8: + case F_MIN_INT4: + case F_MIN_INT2: + case F_MIN_OID: + case F_MIN_FLOAT4: + case F_MIN_FLOAT8: + case F_MIN_DATE: + case F_MIN_TIME: + case F_MIN_TIMETZ: + case F_MIN_MONEY: + case F_MIN_TIMESTAMP: + case F_MIN_TIMESTAMPTZ: + case F_MIN_INTERVAL: + case F_MIN_TEXT: + case F_MIN_NUMERIC: + case F_MIN_BPCHAR: + case F_MIN_TID: + case F_MIN_ANYENUM: + case F_MIN_INET: + case F_MIN_PG_LSN: + + /* max */ + case F_MAX_ANYARRAY: + case F_MAX_INT8: + case F_MAX_INT4: + case F_MAX_INT2: + case F_MAX_OID: + case F_MAX_FLOAT4: + case F_MAX_FLOAT8: + case F_MAX_DATE: + case F_MAX_TIME: + case F_MAX_TIMETZ: + case F_MAX_MONEY: + case F_MAX_TIMESTAMP: + case F_MAX_TIMESTAMPTZ: + case F_MAX_INTERVAL: + case F_MAX_TEXT: + case F_MAX_NUMERIC: + case F_MAX_BPCHAR: + case F_MAX_TID: + case F_MAX_ANYENUM: + case F_MAX_INET: + case F_MAX_PG_LSN: return true; default: diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index 3c523991ed..e60f92226c 100644 --- a/src/backend/commands/matview.c +++ b/src/backend/commands/matview.c @@ -73,6 +73,34 @@ typedef struct #define MV_INIT_QUERYHASHSIZE 16 +/* MV query type codes */ +#define MV_PLAN_RECALC 1 +#define MV_PLAN_SET_VALUE 2 + +/* + * MI_QueryKey + * + * The key identifying a prepared SPI plan in our query hashtable + */ +typedef struct MV_QueryKey +{ + Oid matview_id; /* OID of materialized view */ + int32 query_type; /* query type ID, see MV_PLAN_XXX above */ +} MV_QueryKey; + +/* + * MV_QueryHashEntry + * + * Hash entry for cached plans used to maintain materialized views. + */ +typedef struct MV_QueryHashEntry +{ + MV_QueryKey key; + SPIPlanPtr plan; + SearchPathMatcher *search_path; /* search_path used for parsing + * and planning */ +} MV_QueryHashEntry; + /* * MV_TriggerHashEntry * @@ -109,6 +137,7 @@ typedef struct MV_TriggerTable TupleTableSlot *slot; /* for checking visibility in the pre-state table */ } MV_TriggerTable; +static HTAB *mv_query_cache = NULL; static HTAB *mv_trigger_info = NULL; static bool in_delta_calculation = false; @@ -169,6 +198,9 @@ static void append_set_clause_for_sum(const char *resname, StringInfo buf_old, static void append_set_clause_for_avg(const char *resname, StringInfo buf_old, StringInfo buf_new, StringInfo aggs_list, const char *aggtype); +static void append_set_clause_for_minmax(const char *resname, StringInfo buf_old, + StringInfo buf_new, StringInfo aggs_list, + bool is_min); static char *get_operation_string(IvmOp op, const char *col, const char *arg1, const char *arg2, const char* count_col, const char *castType); static char *get_null_condition_string(IvmOp op, const char *arg1, const char *arg2, @@ -177,17 +209,30 @@ static void apply_old_delta(const char *matviewname, const char *deltaname_old, List *keys); static void apply_old_delta_with_count(const char *matviewname, const char *deltaname_old, List *keys, StringInfo aggs_list, StringInfo aggs_set, - const char *count_colname); + List *minmax_list, List *is_min_list, + const char *count_colname, + SPITupleTable **tuptable_recalc, uint64 *num_recalc); static void apply_new_delta(const char *matviewname, const char *deltaname_new, StringInfo target_list); static void apply_new_delta_with_count(const char *matviewname, const char* deltaname_new, List *keys, StringInfo target_list, StringInfo aggs_set, const char* count_colname); static char *get_matching_condition_string(List *keys); +static char *get_returning_string(List *minmax_list, List *is_min_list, List *keys); +static char *get_minmax_recalc_condition_string(List *minmax_list, List *is_min_list); +static char *get_select_for_recalc_string(List *keys); +static void recalc_and_set_values(SPITupleTable *tuptable_recalc, int64 num_tuples, + List *namelist, List *keys, Relation matviewRel); +static SPIPlanPtr get_plan_for_recalc(Oid matviewOid, List *namelist, List *keys, Oid *keyTypes); +static SPIPlanPtr get_plan_for_set_values(Oid matviewOid, char *matviewname, List *namelist, + Oid *valTypes); static void generate_equal(StringInfo querybuf, Oid opttype, const char *leftop, const char *rightop); static void mv_InitHashTables(void); +static SPIPlanPtr mv_FetchPreparedPlan(MV_QueryKey *key); +static void mv_HashPreparedPlan(MV_QueryKey *key, SPIPlanPtr plan); +static void mv_BuildQueryKey(MV_QueryKey *key, Oid matview_id, int32 query_type); static void clean_up_IVM_hash_entry(MV_TriggerHashEntry *entry, bool is_abort); /* @@ -2123,6 +2168,8 @@ apply_delta(Oid matviewOid, Tuplestorestate *old_tuplestores, Tuplestorestate *n ListCell *lc; int i; List *keys = NIL; + List *minmax_list = NIL; + List *is_min_list = NIL; /* @@ -2204,6 +2251,17 @@ apply_delta(Oid matviewOid, Tuplestorestate *old_tuplestores, Tuplestorestate *n append_set_clause_for_avg(resname, aggs_set_old, aggs_set_new, aggs_list_buf, format_type_be(aggref->aggtype)); + /* min/max */ + else if (!strcmp(aggname, "min") || !strcmp(aggname, "max")) + { + bool is_min = (!strcmp(aggname, "min")); + + append_set_clause_for_minmax(resname, aggs_set_old, aggs_set_new, aggs_list_buf, is_min); + + /* make a resname list of min and max aggregates */ + minmax_list = lappend(minmax_list, resname); + is_min_list = lappend_int(is_min_list, is_min); + } else elog(ERROR, "unsupported aggregate function: %s", aggname); } @@ -2233,6 +2291,8 @@ apply_delta(Oid matviewOid, Tuplestorestate *old_tuplestores, Tuplestorestate *n if (old_tuplestores && tuplestore_tuple_count(old_tuplestores) > 0) { EphemeralNamedRelation enr = palloc(sizeof(EphemeralNamedRelationData)); + SPITupleTable *tuptable_recalc = NULL; + uint64 num_recalc; int rc; /* convert tuplestores to ENR, and register for SPI */ @@ -2251,10 +2311,18 @@ apply_delta(Oid matviewOid, Tuplestorestate *old_tuplestores, Tuplestorestate *n /* apply old delta and get rows to be recalculated */ apply_old_delta_with_count(matviewname, OLD_DELTA_ENRNAME, keys, aggs_list_buf, aggs_set_old, - count_colname); + minmax_list, is_min_list, + count_colname, &tuptable_recalc, &num_recalc); else apply_old_delta(matviewname, OLD_DELTA_ENRNAME, keys); + /* + * If we have min or max, we might have to recalculate aggregate values from base tables + * on some tuples. TIDs and keys such tuples are returned as a result of the above query. + */ + if (minmax_list && tuptable_recalc) + recalc_and_set_values(tuptable_recalc, num_recalc, minmax_list, keys, matviewRel); + } /* For tuple insertion */ if (new_tuplestores && tuplestore_tuple_count(new_tuplestores) > 0) @@ -2446,6 +2514,70 @@ append_set_clause_for_avg(const char *resname, StringInfo buf_old, ); } +/* + * append_set_clause_for_minmax + * + * Append SET clause string for min or max aggregation to given buffers. + * Also, append resnames required for calculating the aggregate value. + * is_min is true if this is min, false if not. + */ +static void +append_set_clause_for_minmax(const char *resname, StringInfo buf_old, + StringInfo buf_new, StringInfo aggs_list, + bool is_min) +{ + char *count_col = IVM_colname("count", resname); + + /* For tuple deletion */ + if (buf_old) + { + /* + * If the new value doesn't became NULL then use the value remaining + * in the view although this will be recomputated afterwords. + */ + appendStringInfo(buf_old, + ", %s = CASE WHEN %s THEN NULL ELSE %s END", + quote_qualified_identifier(NULL, resname), + get_null_condition_string(IVM_SUB, "mv", "t", count_col), + quote_qualified_identifier("mv", resname) + ); + /* count = mv.count - t.count */ + appendStringInfo(buf_old, + ", %s = %s", + quote_qualified_identifier(NULL, count_col), + get_operation_string(IVM_SUB, count_col, "mv", "t", NULL, NULL) + ); + } + /* For tuple insertion */ + if (buf_new) + { + /* + * min = LEAST(mv.min, diff.min) + * max = GREATEST(mv.max, diff.max) + */ + appendStringInfo(buf_new, + ", %s = CASE WHEN %s THEN NULL ELSE %s(%s,%s) END", + quote_qualified_identifier(NULL, resname), + get_null_condition_string(IVM_ADD, "mv", "diff", count_col), + + is_min ? "LEAST" : "GREATEST", + quote_qualified_identifier("mv", resname), + quote_qualified_identifier("diff", resname) + ); + /* count = mv.count + diff.count */ + appendStringInfo(buf_new, + ", %s = %s", + quote_qualified_identifier(NULL, count_col), + get_operation_string(IVM_ADD, count_col, "mv", "diff", NULL, NULL) + ); + } + + appendStringInfo(aggs_list, ", %s, %s", + quote_qualified_identifier("diff", resname), + quote_qualified_identifier("diff", IVM_colname("count", resname)) + ); +} + /* * get_operation_string * @@ -2548,19 +2680,44 @@ get_null_condition_string(IvmOp op, const char *arg1, const char *arg2, * list to identify a tuple in the view. If the view has aggregates, this * requires strings representing resnames of aggregates and SET clause for * updating aggregate values. + * + * If the view has min or max aggregate, this requires a list of resnames of + * min/max aggregates and a list of boolean which represents which entries in + * minmax_list is min. These are necessary to check if we need to recalculate + * min or max aggregate values. In this case, this query returns TID and keys + * of tuples which need to be recalculated. This result and the number of rows + * are stored in tuptables and num_recalc repectedly. + * */ static void apply_old_delta_with_count(const char *matviewname, const char *deltaname_old, List *keys, StringInfo aggs_list, StringInfo aggs_set, - const char *count_colname) + List *minmax_list, List *is_min_list, + const char *count_colname, + SPITupleTable **tuptable_recalc, uint64 *num_recalc) { StringInfoData querybuf; char *match_cond; + char *updt_returning = ""; + char *select_for_recalc = "SELECT"; bool agg_without_groupby = (list_length(keys) == 0); + Assert(tuptable_recalc != NULL); + Assert(num_recalc != NULL); + /* build WHERE condition for searching tuples to be deleted */ match_cond = get_matching_condition_string(keys); + /* + * We need a special RETURNING clause and SELECT statement for min/max to + * check which tuple needs re-calculation from base tables. + */ + if (minmax_list) + { + updt_returning = get_returning_string(minmax_list, is_min_list, keys); + select_for_recalc = get_select_for_recalc_string(keys); + } + /* Search for matching tuples from the view and update or delete if found. */ initStringInfo(&querybuf); appendStringInfo(&querybuf, @@ -2575,10 +2732,11 @@ apply_old_delta_with_count(const char *matviewname, const char *deltaname_old, "UPDATE %s AS mv SET %s = mv.%s OPERATOR(pg_catalog.-) t.%s " "%s" /* SET clauses for aggregates */ "FROM t WHERE mv.ctid OPERATOR(pg_catalog.=) t.ctid AND NOT for_dlt " - ")" - /* delete a tuple if this is to be deleted */ - "DELETE FROM %s AS mv USING t " - "WHERE mv.ctid OPERATOR(pg_catalog.=) t.ctid AND for_dlt", + "%s" /* RETURNING clause for recalc infomation */ + "), dlt AS (" /* delete a tuple if this is to be deleted */ + "DELETE FROM %s AS mv USING t " + "WHERE mv.ctid OPERATOR(pg_catalog.=) t.ctid AND for_dlt" + ") %s", /* SELECT returning which tuples need to be recalculated */ count_colname, count_colname, count_colname, (agg_without_groupby ? "false" : "true"), (aggs_list != NULL ? aggs_list->data : ""), @@ -2586,10 +2744,25 @@ apply_old_delta_with_count(const char *matviewname, const char *deltaname_old, match_cond, matviewname, count_colname, count_colname, count_colname, (aggs_set != NULL ? aggs_set->data : ""), - matviewname); + updt_returning, + matviewname, + select_for_recalc); - if (SPI_exec(querybuf.data, 0) != SPI_OK_DELETE) + if (SPI_exec(querybuf.data, 0) != SPI_OK_SELECT) elog(ERROR, "SPI_exec failed: %s", querybuf.data); + + + /* Return tuples to be recalculated. */ + if (minmax_list) + { + *tuptable_recalc = SPI_tuptable; + *num_recalc = SPI_processed; + } + else + { + *tuptable_recalc = NULL; + *num_recalc = 0; + } } /* @@ -2772,6 +2945,349 @@ get_matching_condition_string(List *keys) return match_cond.data; } +/* + * get_returning_string + * + * Build a string for RETURNING clause of UPDATE used in apply_old_delta_with_count. + * This clause returns ctid and a boolean value that indicates if we need to + * recalculate min or max value, for each updated row. + */ +static char * +get_returning_string(List *minmax_list, List *is_min_list, List *keys) +{ + StringInfoData returning; + char *recalc_cond; + ListCell *lc; + + Assert(minmax_list != NIL && is_min_list != NIL); + recalc_cond = get_minmax_recalc_condition_string(minmax_list, is_min_list); + + initStringInfo(&returning); + + appendStringInfo(&returning, "RETURNING mv.ctid AS tid, (%s) AS recalc", recalc_cond); + foreach (lc, keys) + { + Form_pg_attribute attr = (Form_pg_attribute) lfirst(lc); + char *resname = NameStr(attr->attname); + appendStringInfo(&returning, ", %s", quote_qualified_identifier("mv", resname)); + } + + return returning.data; +} + +/* + * get_minmax_recalc_condition_string + * + * Build a predicate string for checking if any min/max aggregate + * value needs to be recalculated. + */ +static char * +get_minmax_recalc_condition_string(List *minmax_list, List *is_min_list) +{ + StringInfoData recalc_cond; + ListCell *lc1, *lc2; + + initStringInfo(&recalc_cond); + + Assert (list_length(minmax_list) == list_length(is_min_list)); + + forboth (lc1, minmax_list, lc2, is_min_list) + { + char *resname = (char *) lfirst(lc1); + bool is_min = (bool) lfirst_int(lc2); + char *op_str = (is_min ? ">=" : "<="); + + appendStringInfo(&recalc_cond, "%s OPERATOR(pg_catalog.%s) %s", + quote_qualified_identifier("mv", resname), + op_str, + quote_qualified_identifier("t", resname) + ); + + if (lnext(minmax_list, lc1)) + appendStringInfo(&recalc_cond, " OR "); + } + + return recalc_cond.data; +} + +/* + * get_select_for_recalc_string + * + * Build a query to return tid and keys of tuples which need + * recalculation. This is used as the result of the query + * built by apply_old_delta. + */ +static char * +get_select_for_recalc_string(List *keys) +{ + StringInfoData qry; + ListCell *lc; + + initStringInfo(&qry); + + appendStringInfo(&qry, "SELECT tid"); + foreach (lc, keys) + { + Form_pg_attribute attr = (Form_pg_attribute) lfirst(lc); + appendStringInfo(&qry, ", %s", NameStr(attr->attname)); + } + + appendStringInfo(&qry, " FROM updt WHERE recalc"); + + return qry.data; +} + +/* + * recalc_and_set_values + * + * Recalculate tuples in a materialized from base tables and update these. + * The tuples which needs recalculation are specified by keys, and resnames + * of columns to be updated are specified by namelist. TIDs and key values + * are given by tuples in tuptable_recalc. Its first attribute must be TID + * and key values must be following this. + */ +static void +recalc_and_set_values(SPITupleTable *tuptable_recalc, int64 num_tuples, + List *namelist, List *keys, Relation matviewRel) +{ + TupleDesc tupdesc_recalc = tuptable_recalc->tupdesc; + Oid *keyTypes = NULL, *types = NULL; + char *keyNulls = NULL, *nulls = NULL; + Datum *keyVals = NULL, *vals = NULL; + int num_vals = list_length(namelist); + int num_keys = list_length(keys); + uint64 i; + Oid matviewOid; + char *matviewname; + + matviewOid = RelationGetRelid(matviewRel); + matviewname = quote_qualified_identifier(get_namespace_name(RelationGetNamespace(matviewRel)), + RelationGetRelationName(matviewRel)); + + /* If we have keys, initialize arrays for them. */ + if (keys) + { + keyTypes = palloc(sizeof(Oid) * num_keys); + keyNulls = palloc(sizeof(char) * num_keys); + keyVals = palloc(sizeof(Datum) * num_keys); + /* a tuple contains keys to be recalculated and ctid to be updated*/ + Assert(tupdesc_recalc->natts == num_keys + 1); + + /* Types of key attributes */ + for (i = 0; i < num_keys; i++) + keyTypes[i] = TupleDescAttr(tupdesc_recalc, i + 1)->atttypid; + } + + /* allocate memory for all attribute names and tid */ + types = palloc(sizeof(Oid) * (num_vals + 1)); + nulls = palloc(sizeof(char) * (num_vals + 1)); + vals = palloc(sizeof(Datum) * (num_vals + 1)); + + /* For each tuple which needs recalculation */ + for (i = 0; i < num_tuples; i++) + { + int j; + bool isnull; + SPIPlanPtr plan; + SPITupleTable *tuptable_newvals; + TupleDesc tupdesc_newvals; + + /* Set group key values as parameters if needed. */ + if (keys) + { + for (j = 0; j < num_keys; j++) + { + keyVals[j] = SPI_getbinval(tuptable_recalc->vals[i], tupdesc_recalc, j + 2, &isnull); + if (isnull) + keyNulls[j] = 'n'; + else + keyNulls[j] = ' '; + } + } + + /* + * Get recalculated values from base tables. The result must be + * only one tuple thich contains the new values for specified keys. + */ + plan = get_plan_for_recalc(matviewOid, namelist, keys, keyTypes); + if (SPI_execute_plan(plan, keyVals, keyNulls, false, 0) != SPI_OK_SELECT) + elog(ERROR, "SPI_execute_plan"); + if (SPI_processed != 1) + elog(ERROR, "SPI_execute_plan returned zero or more than one rows"); + + tuptable_newvals = SPI_tuptable; + tupdesc_newvals = tuptable_newvals->tupdesc; + + Assert(tupdesc_newvals->natts == num_vals); + + /* Set the new values as parameters */ + for (j = 0; j < tupdesc_newvals->natts; j++) + { + if (i == 0) + types[j] = TupleDescAttr(tupdesc_newvals, j)->atttypid; + + vals[j] = SPI_getbinval(tuptable_newvals->vals[0], tupdesc_newvals, j + 1, &isnull); + if (isnull) + nulls[j] = 'n'; + else + nulls[j] = ' '; + } + /* Set TID of the view tuple to be updated as a parameter */ + types[j] = TIDOID; + vals[j] = SPI_getbinval(tuptable_recalc->vals[i], tupdesc_recalc, 1, &isnull); + nulls[j] = ' '; + + /* Update the view tuple to the new values */ + plan = get_plan_for_set_values(matviewOid, matviewname, namelist, types); + if (SPI_execute_plan(plan, vals, nulls, false, 0) != SPI_OK_UPDATE) + elog(ERROR, "SPI_execute_plan"); + } +} + + +/* + * get_plan_for_recalc + * + * Create or fetch a plan for recalculating value in the view's target list + * from base tables using the definition query of materialized view specified + * by matviewOid. namelist is a list of resnames of values to be recalculated. + * + * keys is a list of keys to identify tuples to be recalculated if this is not + * empty. KeyTypes is an array of types of keys. + */ +static SPIPlanPtr +get_plan_for_recalc(Oid matviewOid, List *namelist, List *keys, Oid *keyTypes) +{ + MV_QueryKey hash_key; + SPIPlanPtr plan; + + /* Fetch or prepare a saved plan for the recalculation */ + mv_BuildQueryKey(&hash_key, matviewOid, MV_PLAN_RECALC); + if ((plan = mv_FetchPreparedPlan(&hash_key)) == NULL) + { + ListCell *lc; + StringInfoData str; + char *viewdef; + + /* get view definition of matview */ + viewdef = text_to_cstring((text *) DatumGetPointer( + DirectFunctionCall1(pg_get_viewdef, ObjectIdGetDatum(matviewOid)))); + /* get rid of trailing semi-colon */ + viewdef[strlen(viewdef)-1] = '\0'; + + /* + * Build a query string for recalculating values. This is like + * + * SELECT x1, x2, x3, ... FROM ( ... view definition query ...) mv + * WHERE (key1, key2, ...) = ($1, $2, ...); + */ + + initStringInfo(&str); + appendStringInfo(&str, "SELECT "); + foreach (lc, namelist) + { + appendStringInfo(&str, "%s", (char *) lfirst(lc)); + if (lnext(namelist, lc)) + appendStringInfoString(&str, ", "); + } + appendStringInfo(&str, " FROM (%s) mv", viewdef); + + if (keys) + { + int i = 1; + char paramname[16]; + + appendStringInfo(&str, " WHERE ("); + foreach (lc, keys) + { + Form_pg_attribute attr = (Form_pg_attribute) lfirst(lc); + char *resname = NameStr(attr->attname); + Oid typid = attr->atttypid; + + sprintf(paramname, "$%d", i); + appendStringInfo(&str, "("); + generate_equal(&str, typid, resname, paramname); + appendStringInfo(&str, " OR (%s IS NULL AND %s IS NULL))", + resname, paramname); + + if (lnext(keys, lc)) + appendStringInfoString(&str, " AND "); + i++; + } + appendStringInfo(&str, ")"); + } + else + keyTypes = NULL; + + plan = SPI_prepare(str.data, list_length(keys), keyTypes); + if (plan == NULL) + elog(ERROR, "SPI_prepare returned %s for %s", SPI_result_code_string(SPI_result), str.data); + + SPI_keepplan(plan); + mv_HashPreparedPlan(&hash_key, plan); + } + + return plan; +} + +/* + * get_plan_for_set_values + * + * Create or fetch a plan for applying new values calculated by + * get_plan_for_recalc to a materialized view specified by matviewOid. + * matviewname is the name of the view. namelist is a list of resnames + * of attributes to be updated, and valTypes is an array of types of the + * values. + */ +static SPIPlanPtr +get_plan_for_set_values(Oid matviewOid, char *matviewname, List *namelist, + Oid *valTypes) +{ + MV_QueryKey key; + SPIPlanPtr plan; + + /* Fetch or prepare a saved plan for the real check */ + mv_BuildQueryKey(&key, matviewOid, MV_PLAN_SET_VALUE); + if ((plan = mv_FetchPreparedPlan(&key)) == NULL) + { + ListCell *lc; + StringInfoData str; + int i; + + /* + * Build a query string for applying min/max values. This is like + * + * UPDATE matviewname AS mv + * SET (x1, x2, x3, x4) = ($1, $2, $3, $4) + * WHERE ctid = $5; + */ + + initStringInfo(&str); + appendStringInfo(&str, "UPDATE %s AS mv SET (", matviewname); + foreach (lc, namelist) + { + appendStringInfo(&str, "%s", (char *) lfirst(lc)); + if (lnext(namelist, lc)) + appendStringInfoString(&str, ", "); + } + appendStringInfo(&str, ") = ROW("); + + for (i = 1; i <= list_length(namelist); i++) + appendStringInfo(&str, "%s$%d", (i==1 ? "" : ", "), i); + + appendStringInfo(&str, ") WHERE ctid OPERATOR(pg_catalog.=) $%d", i); + + plan = SPI_prepare(str.data, list_length(namelist) + 1, valTypes); + if (plan == NULL) + elog(ERROR, "SPI_prepare returned %s for %s", SPI_result_code_string(SPI_result), str.data); + + SPI_keepplan(plan); + mv_HashPreparedPlan(&key, plan); + } + + return plan; +} + /* * generate_equals * @@ -2805,6 +3321,13 @@ mv_InitHashTables(void) { HASHCTL ctl; + memset(&ctl, 0, sizeof(ctl)); + ctl.keysize = sizeof(MV_QueryKey); + ctl.entrysize = sizeof(MV_QueryHashEntry); + mv_query_cache = hash_create("MV query cache", + MV_INIT_QUERYHASHSIZE, + &ctl, HASH_ELEM | HASH_BLOBS); + memset(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(MV_TriggerHashEntry); @@ -2813,6 +3336,109 @@ mv_InitHashTables(void) &ctl, HASH_ELEM | HASH_BLOBS); } +/* + * mv_FetchPreparedPlan + */ +static SPIPlanPtr +mv_FetchPreparedPlan(MV_QueryKey *key) +{ + MV_QueryHashEntry *entry; + SPIPlanPtr plan; + + /* + * On the first call initialize the hashtable + */ + if (!mv_query_cache) + mv_InitHashTables(); + + /* + * Lookup for the key + */ + entry = (MV_QueryHashEntry *) hash_search(mv_query_cache, + (void *) key, + HASH_FIND, NULL); + if (entry == NULL) + return NULL; + + /* + * Check whether the plan is still valid. If it isn't, we don't want to + * simply rely on plancache.c to regenerate it; rather we should start + * from scratch and rebuild the query text too. This is to cover cases + * such as table/column renames. We depend on the plancache machinery to + * detect possible invalidations, though. + * + * CAUTION: this check is only trustworthy if the caller has already + * locked both materialized views and base tables. + * + * Also, check whether the search_path is still the same as when we made it. + * If it isn't, we need to rebuild the query text because the result of + * pg_ivm_get_viewdef() will change. + */ + plan = entry->plan; + if (plan && SPI_plan_is_valid(plan) && + SearchPathMatchesCurrentEnvironment(entry->search_path)) + return plan; + + /* + * Otherwise we might as well flush the cached plan now, to free a little + * memory space before we make a new one. + */ + if (plan) + SPI_freeplan(plan); + if (entry->search_path) + pfree(entry->search_path); + + entry->plan = NULL; + entry->search_path = NULL; + + return NULL; +} + +/* + * mv_HashPreparedPlan + * + * Add another plan to our private SPI query plan hashtable. + */ +static void +mv_HashPreparedPlan(MV_QueryKey *key, SPIPlanPtr plan) +{ + MV_QueryHashEntry *entry; + bool found; + + /* + * On the first call initialize the hashtable + */ + if (!mv_query_cache) + mv_InitHashTables(); + + /* + * Add the new plan. We might be overwriting an entry previously found + * invalid by mv_FetchPreparedPlan. + */ + entry = (MV_QueryHashEntry *) hash_search(mv_query_cache, + (void *) key, + HASH_ENTER, &found); + Assert(!found || entry->plan == NULL); + entry->plan = plan; + entry->search_path = GetSearchPathMatcher(TopMemoryContext); +} + +/* + * mv_BuildQueryKey + * + * Construct a hashtable key for a prepared SPI plan for IVM. + */ +static void +mv_BuildQueryKey(MV_QueryKey *key, Oid matview_id, int32 query_type) +{ + /* + * We assume struct MV_QueryKey contains no padding bytes, else we'd need + * to use memset to clear them. + */ + key->matview_id = matview_id; + key->query_type = query_type; +} + /* * AtAbort_IVM * -- 2.25.1 --Multipart=_Mon__4_Mar_2024_11_58_46_+0900_UaponF/qQhQrVCFt Content-Type: text/x-diff; name="v30-0010-Add-regression-tests-for-Incremental-View-Mainte.patch" Content-Disposition: attachment; filename="v30-0010-Add-regression-tests-for-Incremental-View-Mainte.patch" Content-Transfer-Encoding: 7bit ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/3] Remove unnecessary volatile qualifiers. @ 2026-02-18 16:31 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-02-18 16:31 UTC (permalink / raw) --- src/backend/replication/syncrep.c | 19 ++++++++----------- src/backend/storage/ipc/procsignal.c | 4 ++-- src/backend/storage/lmgr/lock.c | 2 +- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index 7ea6001e9ad..045fd35786a 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -473,7 +473,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -548,19 +547,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -767,8 +766,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -905,7 +903,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -920,7 +917,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 5d33559926a..97791f979ef 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -283,7 +283,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -394,7 +394,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index e1168ad3837..718de1b5e98 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -309,7 +309,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; /* diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 579e5933d28..a1ec13d66b9 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -36,7 +36,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -256,7 +256,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index 368e4f3f234..14972f7e7cd 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -50,7 +50,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --J5cpktPts8HkLShw Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Remove-SpinLockFree-and-S_LOCK_FREE.patch ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers. @ 2026-06-30 21:41 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers to pg_atomic_* variables or local variables that hold a value returned by a pg_atomic_* function. The pointer arguments for the pg_atomic_* functions are volatile-qualified, so there's no need to mark the pointer volatile. Likewise, a local variable that just holds the result of a pg_atomic_* function gains nothing from volatile. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile when they were modified inside a PG_TRY block and used afterward, but the PG_TRY was later removed. --- src/backend/access/transam/clog.c | 2 +- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 10 ++++----- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..47975ba892f 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,7 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..4acef19e563 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - volatile uint32 flags; + uint32 flags; Assert(MyProcSignalSlot); @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --hE8tq9meMVMcgUcn-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* remove unnecessary volatile qualifiers @ 2026-06-30 21:47 Nathan Bossart <[email protected]> 2026-07-06 11:58 ` Re: remove unnecessary volatile qualifiers Heikki Linnakangas <[email protected]> 0 siblings, 1 reply; 383+ messages in thread From: Nathan Bossart @ 2026-06-30 21:47 UTC (permalink / raw) To: pgsql-hackers I looked into some of these earlier [0], but ended up leaving them alone at the time. Here is a new patch that removes all of the volatile markers in the tree that seemed obviously unnecessary to me. [0] https://postgr.es/m/aZX2oUcKf7IzHnnK%40nathan -- nathan ^ permalink raw reply [nested|flat] 383+ messages in thread
* Re: remove unnecessary volatile qualifiers 2026-06-30 21:47 remove unnecessary volatile qualifiers Nathan Bossart <[email protected]> @ 2026-07-06 11:58 ` Heikki Linnakangas <[email protected]> 2026-07-06 15:47 ` Re: remove unnecessary volatile qualifiers Nathan Bossart <[email protected]> 0 siblings, 1 reply; 383+ messages in thread From: Heikki Linnakangas @ 2026-07-06 11:58 UTC (permalink / raw) To: Nathan Bossart <[email protected]>; pgsql-hackers On 01/07/2026 00:47, Nathan Bossart wrote: > I looked into some of these earlier [0], but ended up leaving them alone at > the time. Here is a new patch that removes all of the volatile markers in > the tree that seemed obviously unnecessary to me. Thanks! > --- a/src/backend/access/transam/clog.c > +++ b/src/backend/access/transam/clog.c > @@ -450,7 +450,7 @@ static bool > TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, > XLogRecPtr lsn, int64 pageno) > { > - volatile PROC_HDR *procglobal = ProcGlobal; > + PROC_HDR *procglobal = ProcGlobal; > PGPROC *proc = MyProc; > uint32 nextidx; > uint32 wakeidx; You might want to get rid of the local variable altogether and just refer to ProcGlobal directly.. > @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) > { > uint64 local_gen; > uint64 shared_gen; > - volatile uint32 flags; > + uint32 flags; > > Assert(MyProcSignalSlot); > Are you sure about this one? 'flags' is used in the PG_TRY/CATCH block that follows. It is modified in the PG_TRY(), here: > > /* > * To avoid an infinite loop, we must always unset the bit in > * flags. > */ > BARRIER_CLEAR_BIT(flags, type); and read later in the PG_CATCH() block. The rest looks OK to me. - Heikki ^ permalink raw reply [nested|flat] 383+ messages in thread
* Re: remove unnecessary volatile qualifiers 2026-06-30 21:47 remove unnecessary volatile qualifiers Nathan Bossart <[email protected]> 2026-07-06 11:58 ` Re: remove unnecessary volatile qualifiers Heikki Linnakangas <[email protected]> @ 2026-07-06 15:47 ` Nathan Bossart <[email protected]> 2026-07-07 16:03 ` Re: remove unnecessary volatile qualifiers Nathan Bossart <[email protected]> 0 siblings, 1 reply; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:47 UTC (permalink / raw) To: Heikki Linnakangas <[email protected]>; +Cc: pgsql-hackers On Mon, Jul 06, 2026 at 02:58:12PM +0300, Heikki Linnakangas wrote: > On 01/07/2026 00:47, Nathan Bossart wrote: >> I looked into some of these earlier [0], but ended up leaving them alone at >> the time. Here is a new patch that removes all of the volatile markers in >> the tree that seemed obviously unnecessary to me. > > Thanks! Thanks for reviewing. >> --- a/src/backend/access/transam/clog.c >> +++ b/src/backend/access/transam/clog.c >> @@ -450,7 +450,7 @@ static bool >> TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, >> XLogRecPtr lsn, int64 pageno) >> { >> - volatile PROC_HDR *procglobal = ProcGlobal; >> + PROC_HDR *procglobal = ProcGlobal; >> PGPROC *proc = MyProc; >> uint32 nextidx; >> uint32 wakeidx; > > You might want to get rid of the local variable altogether and just refer to > ProcGlobal directly.. Done. >> @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void) >> { >> uint64 local_gen; >> uint64 shared_gen; >> - volatile uint32 flags; >> + uint32 flags; >> Assert(MyProcSignalSlot); > > Are you sure about this one? 'flags' is used in the PG_TRY/CATCH block that > follows. It is modified in the PG_TRY(), here: > >> >> /* >> * To avoid an infinite loop, we must always unset the bit in >> * flags. >> */ >> BARRIER_CLEAR_BIT(flags, type); > > and read later in the PG_CATCH() block. Whoops. You are right. I reverted this part. -- nathan ^ permalink raw reply [nested|flat] 383+ messages in thread
* Re: remove unnecessary volatile qualifiers 2026-06-30 21:47 remove unnecessary volatile qualifiers Nathan Bossart <[email protected]> 2026-07-06 11:58 ` Re: remove unnecessary volatile qualifiers Heikki Linnakangas <[email protected]> 2026-07-06 15:47 ` Re: remove unnecessary volatile qualifiers Nathan Bossart <[email protected]> @ 2026-07-07 16:03 ` Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-07 16:03 UTC (permalink / raw) To: Heikki Linnakangas <[email protected]>; +Cc: pgsql-hackers Committed. -- nathan ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers. @ 2026-07-06 15:24 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 383+ messages in thread From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw) This commit cleans up volatile qualifiers that fit the below criteria: * Accesses to shared memory protected by a spinlock or LWLock. Before commit 0709b7ee72, callers had to use volatile when accessing spinlock-protected shared memory. Since spinlock acquire/release became compiler barriers, and because LWLocks provide the same guarantee, that is no longer necessary. These either predate that change or were cargo-culted from code that did. * Pointers used only to find the address of a member. The volatile qualifier only affects accesses made by dereferencing the pointer, so it is unnecessary there. * Accesses to struct members that are marked volatile in the struct definition. There's no need to mark these pointers volatile, either. * Leftovers from removed PG_TRY blocks. These were marked volatile to protect a value that is modified inside a PG_TRY block and used afterward, but the PG_TRY has since been removed. --- src/backend/access/transam/clog.c | 7 +++--- src/backend/catalog/index.c | 2 +- src/backend/commands/async.c | 4 ++-- src/backend/replication/syncrep.c | 19 +++++++--------- src/backend/storage/ipc/procsignal.c | 8 +++---- src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++--------------- src/backend/storage/lmgr/lock.c | 2 +- src/backend/storage/lmgr/proc.c | 3 +-- src/test/modules/test_shm_mq/setup.c | 4 ++-- src/test/modules/test_shm_mq/worker.c | 2 +- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 75012d4b8f0..6f7f6b86eb6 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -450,7 +450,6 @@ static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno) { - volatile PROC_HDR *procglobal = ProcGlobal; PGPROC *proc = MyProc; uint32 nextidx; uint32 wakeidx; @@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * different from ours. If another group starts to update a page in the * same bank as ours, they wait until we release the lock. */ - nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst); + nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst); while (true) { @@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, pg_atomic_write_u32(&proc->clogGroupNext, nextidx); - if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst, + if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst, &nextidx, (uint32) MyProcNumber)) break; @@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, * At this point, any processes trying to do this would create a separate * group. */ - nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst, + nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); /* Remember head of list so we can perform wakeups after dropping lock. */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..81bba4beac7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId, int save_sec_context; int save_nestlevel; IndexInfo *indexInfo; - volatile bool skipped_constraint = false; + bool skipped_constraint = false; PGRUsage ru0; bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); bool set_tablespace = false; diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index eee8bc29f38..2799f989b96 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void); static bool IsListeningOn(const char *channel); static void asyncQueueUnregister(void); static bool asyncQueueIsFull(void); -static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength); +static bool asyncQueueAdvance(QueuePosition *position, int entryLength); static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); @@ -1968,7 +1968,7 @@ asyncQueueIsFull(void) * returns true, else false. */ static bool -asyncQueueAdvance(volatile QueuePosition *position, int entryLength) +asyncQueueAdvance(QueuePosition *position, int entryLength) { int64 pageno = QUEUE_POS_PAGE(*position); int offset = QUEUE_POS_OFFSET(*position); diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index e0e30579c59..d870f09e0a0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -483,7 +483,6 @@ SyncRepInitConfig(void) void SyncRepReleaseWaiters(void) { - volatile WalSndCtlData *walsndctl = WalSndCtl; XLogRecPtr writePtr; XLogRecPtr flushPtr; XLogRecPtr applyPtr; @@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void) * Set the lsn first so that when we wake backends they will release up to * this location. */ - if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr) { - walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; + WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr; numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE); } - if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr) { - walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr; numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH); } - if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) + if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr) { - walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; + WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr; numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY); } @@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys) n = 0; for (i = 0; i < max_wal_senders; i++) { - volatile WalSnd *walsnd; /* Use volatile pointer to prevent code - * rearrangement */ + WalSnd *walsnd; SyncRepStandbyData *stby; WalSndState state; /* not included in SyncRepStandbyData */ @@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void) static int SyncRepWakeQueue(bool all, int mode) { - volatile WalSndCtlData *walsndctl = WalSndCtl; int numprocs = 0; dlist_mutable_iter iter; @@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode) /* * Assume the queue is ordered by LSN */ - if (!all && walsndctl->lsn[mode] < proc->waitLSN) + if (!all && WalSndCtl->lsn[mode] < proc->waitLSN) return numprocs; /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 1397f65f67b..21a77f98c1d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg) int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; if (procNumber != INVALID_PROC_NUMBER) { @@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = 0; i < NumProcSignalSlots; i++) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit); } @@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) */ for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; pid_t pid = pg_atomic_read_u32(&slot->pss_pid); if (pid != 0) @@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags) static bool CheckProcSignal(ProcSignalReason reason) { - volatile ProcSignalSlot *slot = MyProcSignalSlot; + ProcSignalSlot *slot = MyProcSignalSlot; if (slot != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index 2f9fbb0a519..2217d48c3d9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address) void * shm_toc_allocate(shm_toc *toc, Size nbytes) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) + allocated_bytes; @@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); } - vtoc->toc_allocated_bytes += nbytes; + toc->toc_allocated_bytes += nbytes; SpinLockRelease(&toc->toc_mutex); @@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes) Size shm_toc_freespace(shm_toc *toc) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; Size toc_bytes; SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; SpinLockRelease(&toc->toc_mutex); toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry); @@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc) void shm_toc_insert(shm_toc *toc, uint64 key, void *address) { - volatile shm_toc *vtoc = toc; Size total_bytes; Size allocated_bytes; Size nentry; @@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) SpinLockAcquire(&toc->toc_mutex); - total_bytes = vtoc->toc_total_bytes; - allocated_bytes = vtoc->toc_allocated_bytes; - nentry = vtoc->toc_nentry; + total_bytes = toc->toc_total_bytes; + allocated_bytes = toc->toc_allocated_bytes; + nentry = toc->toc_nentry; #ifdef USE_ASSERT_CHECKING /* Verify no duplicate keys */ for (Size i = 0; i < nentry; i++) - Assert(vtoc->toc_entry[i].key != key); + Assert(toc->toc_entry[i].key != key); #endif toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry) @@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) } Assert(offset < total_bytes); - vtoc->toc_entry[nentry].key = key; - vtoc->toc_entry[nentry].offset = offset; + toc->toc_entry[nentry].key = key; + toc->toc_entry[nentry].offset = offset; /* * By placing a write barrier after filling in the entry and before @@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address) */ pg_write_barrier(); - vtoc->toc_nentry++; + toc->toc_nentry++; SpinLockRelease(&toc->toc_mutex); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 8d246ed5a4e..5ee80c7632e 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -312,7 +312,7 @@ typedef struct uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; } FastPathStrongRelationLockData; -static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static FastPathStrongRelationLockData *FastPathStrongRelationLocks; static void LockManagerShmemRequest(void *arg); static void LockManagerShmemInit(void *arg); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..87dd289f626 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -660,8 +660,7 @@ InitAuxiliaryProcess(void) } /* Mark auxiliary proc as in use by me */ - /* use volatile pointer to prevent code rearrangement */ - ((volatile PGPROC *) auxproc)->pid = MyProcPid; + auxproc->pid = MyProcPid; SpinLockRelease(&ProcGlobal->freeProcsLock); diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 4f40a61e3d9..991fe27a7fa 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers, dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* value cached, fetched from shared memory */ @@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg) static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr) + test_shm_mq_header *hdr) { bool result = false; diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index e13c05ae5c7..0ba1cfcac47 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg) shm_toc *toc; shm_mq_handle *inqh; shm_mq_handle *outqh; - volatile test_shm_mq_header *hdr; + test_shm_mq_header *hdr; int myworkernumber; PGPROC *registrant; -- 2.50.1 (Apple Git-155) --z39t9WErpHrlykOW-- ^ permalink raw reply [nested|flat] 383+ messages in thread
end of thread, other threads:[~2026-07-07 16:03 UTC | newest] Thread overview: 383+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2023-02-25 21:39 [PATCH v1] WIP: Evaluate arguments of correlated SubPlans in the referencing ExprState Andres Freund <[email protected]> 2023-02-25 21:39 [PATCH v2] WIP: Evaluate arguments of correlated SubPlans in the referencing ExprState Andres Freund <[email protected]> 2023-05-31 11:58 [PATCH v30 09/11] Add support for min/max aggregates for IVM Yugo Nagata <[email protected]> 2026-02-18 16:31 [PATCH v1 1/3] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-06-30 21:47 remove unnecessary volatile qualifiers Nathan Bossart <[email protected]> 2026-07-06 11:58 ` Re: remove unnecessary volatile qualifiers Heikki Linnakangas <[email protected]> 2026-07-06 15:47 ` Re: remove unnecessary volatile qualifiers Nathan Bossart <[email protected]> 2026-07-07 16:03 ` Re: remove unnecessary volatile qualifiers Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]> 2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox