Skip to content

GC Config: initialization method does not need access to the outer scope - #23507

Open
denizzzka wants to merge 1 commit into
dlang:masterfrom
denizzzka:gc_cfg_init_changed
Open

GC Config: initialization method does not need access to the outer scope#23507
denizzzka wants to merge 1 commit into
dlang:masterfrom
denizzzka:gc_cfg_init_changed

Conversation

@denizzzka

@denizzzka denizzzka commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

I.e., Config isn't need to touch outer _initialized directly

Having such access prohibits replaceable configuration structs

@thewilsonator thewilsonator left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also would making _initialized a static member of Config help for what you want to do here?


private __gshared bool _initialized;

package(core) bool initialize(ref Config cfg) nothrow @nogc

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

marking this package(core) means regular users cannot call this function. Is this intended?

@denizzzka denizzzka Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes: by the time regular users can call it it's already been called and tryToInitialize() won't be executed a second time because _initialized == true

@nogc nothrow:

bool initialize()
private bool tryToInitialize()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made it private here because method name changed anyway.
If we need to be able initialize it somewhere externally (a second instance of Config, for example) we can change that in the future. But I think this is not needed

@denizzzka

denizzzka commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

@thewilsonator

also would making _initialized a static member of Config help for what you want to do here?

This is impossible, because adding static members to Config breaks compile-time directive:

src/core/internal/parseoptions.d(101): Error: variable `cfg` cannot be read at compile time
                        static if (hasUDA!(__traits(getMember, cfg, field), MemVal))

(Besides, I think it is architecturally correct to do it as I suggested in this PR)

@denizzzka

Copy link
Copy Markdown
Contributor Author

@schveiguy Hi! Tell your opinion about this PR?

@schveiguy

Copy link
Copy Markdown
Member

Having such access prohibits replaceable configuration structs

Can you elaborate on this? I.e. what is the problem this PR is fixing.

@denizzzka

denizzzka commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

Can you elaborate on this? I.e. what is the problem this PR is fixing.

I'm planning to add the ability to use other config structs (literally a different structs with the same field names) declared in other modules. This is necessary to be able to replace defaults, implement other ways to configure or remove configurability altogether because this is not necessary everywhere and may be incompatible with baremetal targets. But this access from struct itself to external _initialized prevents this.

@schveiguy

Copy link
Copy Markdown
Member

So is there a further plan to accept a config struct as a template parameter? I don't see how this change enables using a different config struct.

@denizzzka

Copy link
Copy Markdown
Contributor Author

So is there a further plan to accept a config struct as a template parameter?

I don't know yet, maybe. I used to make the switching by static if previously.

I don't see how this change enables using a different config struct.

Structure from another module haven't access to _initialized variable

@schveiguy

Copy link
Copy Markdown
Member

OK, but if you are are editing druntime to effect your fix anyway, then why not just make this change locally? And then when you want to make the change to druntime to allow alternative configuration structs, then you make this change at the same time.

I'm not saying we don't want to do this. What I'm saying is that this change by itself doesn't seem to give you any ability to change the Config structure to something else. So I'm not sure we need it by itself.

Structure from another module haven't access to _initialized variable

It still does not.

@denizzzka

denizzzka commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

And then when you want to make the change to druntime to allow alternative configuration structs, then you make this change at the same time.

Yes, I just decided to state my intentions: seems, there will be a lot tied to this change

It still does not.

If this PR is accepted, access to this variable will become unnecessary

@schveiguy

Copy link
Copy Markdown
Member

It's just that this change doesn't enable anything except a different editing of druntime.

What about a way to replace the tryToInitialize function with a custom one? Maybe via a weak symbol?

Something similar to

void* register_default_gcs() @weak

I'd suggest something like this:

@weak extern(C) bool initialize_gc_options(Config *config) {
    return config.tryToInitialize();
}

void initialize(ref Config config) {
    if (!_initialized)
        _initialized = initialize_gc_options(&config);

    return _initialized;
}

And then your change makes sense. Because now you can replace that call with your own. See if something like this works with your changes that you are trying (and makes it so you don't have to edit druntime).

@denizzzka

Copy link
Copy Markdown
Contributor Author

In my PR I can also replace tryToInitialize() struct member with my own if I create my own config struct, only without "magic" of weak symbols

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants