Dynamic feature switches¶
A ProFeat model describes a family of systems where each member of the family corresponds to a feature combination. These feature combinations are static, i.e., once a feature combination has been selected it remains fixed. However, ProFeat also supports dynamic switches between feature combinations. This is especially useful for modeling adaptive systems or dynamic software product lines.
Feature controller¶
The rules for switching between different configurations are specified by a
feature controller, which is an automata-based component and defined similarly
to feature modules. A controller is defined
using a controller
block and may contain variables and commands. Consider
the following example:
root feature
all of Producer, Consumers, Buffer;
endfeature
feature Consumers
some of Consumer[3];
endfeature
feature Consumer
// ...
endfeature
controller
[] buffer_full & !active(Consumer[2]) -> activate(Consumer[2]);
[] buffer_low & active(Consumer[2]) -> deactivate(Consumer[2]);
endcontroller
Here, the controller activates an additional Consumer
in case
the buffer is full. Once the buffer is almost empty again, the additional
Consumer
is deactivated.
Inside a controller
block, the special activate
and deactivate
updates can be used to activate or deactivate a feature, respectively. There
may be multiple activate
and deactivate
updates in a single command.
However, activate
and deactivate
cannot be used in stochastic updates.
Furthermore, command containing updates to the feature combination can only be
executed if it does not violate any of the constraints imposed by the
feature model.
Note
The feature controller is optional, but there can be at most one feature controller in a ProFeat model.
Synchronization¶
A feature module can synchronize with the feature controller on the active
and deactivate
updates using the special activate
and deactivate
actions. In the following example, the feature module implementing the
Consumer
feature uses the deactivate
action to block the controller
from deactivating it if it is not idle:
module consumer_impl
work : [0..MAX_WORK] init 0;
// ...
[deactivate] work = 0 -> true;
endmodule
The module will only synchronize with the feature controller if no further work must be processed.
Synchronization with the activate
action can, for example, be used to
initialize the module’s state upon activation.