This is the mail archive of the cygwin-developers@sourceware.cygnus.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

tunable parameters idea



Some of the projects I'm thinking about starting on would benefit from
having some way of letting the user "tweak" some of their internal
parameters.  On Unix, this is done with kernel-tunable variables, so I
was thinking of adding something similar to Cygwin.  Here are my
initial thoughts, comments welcome.  I've dropped all the "__cygwin_*"
prefixes for clarity.

/**** public API ****/

struct tunable_parameter {
  /* This is the name of the parameter, like "NPROC" */
  char *name;
  /* The minimum and maximum legal values for this parameter */
  int min_value;
  int max_value;
  /* The source-defined default */
  int default_value;
  /* The current value, which may be equal to the default. */
  int current_value;
  /* Flags, see below */
  int flags;
};

/* If set, then changing the value doesn't take effect immediatly.
   Instead, the program or dll must be restarted.  This is advisory
   information, intended to be presented to the user by the application
   that lets the user set tunable parameters. */
#define TUNABLE_RESTART_NEEDED	0x0001
/* If set, the value is a per-process value.  When both this and the
   above are set, the program must be restarted to take effect.  If
   this is not set and the above is, then *all* cygwin programs must
   be exited for to take effect */
#define TUNABLE_PER_PROCESS	0x0002
/* If set, the current value was set from the default value.  This
   way, you can tell the difference between defaulting and the user
   specifying a value that happens to be the default value (in case
   the dll sources change, this determines if the current value
   changes to the new default or stays at the old default) */
#define TUNABLE_USING_DEFAULT	0x0004

/* This function returns a list of tunable parameters.  This list is
   effectively read-only, as the system will build it from other
   internal data (thus, you can't change the min/max values and get
   away with it).  The user should not free this list. The last entry in
   the list has a NULL where the name would be. */
tunable_parameter *get_tunable_parameter_list();

/* return values for the next two functions */
#define TUNABLE_NOERROR		0
#define TUNABLE_ERROR_UNKNOWN	1
#define TUNABLE_ERROR_BADNAME	2
#define TUNABLE_ERROR_BADVAL	3

/* This function changes the value of a tunable parameter.  The return
   value is zero if the parameter was changed, nonzero if the
   parameter is unknown or if the value is out of range.  Note that
   changes to parameters not needing a restart will still only affect
   the current process. */
int set_tunable_parameter(char *name, int value);

/* This removes any user-set value for the parameter, so it will use
   the default (even if the default changes) */
int unset_tunable_parameter(char *name);

/**** cygwin1.dll internal API ****/

For each tunable parameter, the developer adds a line to "tunelist.h"
like this:

TUNE(name, min, max, default, flags);

Example:

TUNE(NPROC, 1, 500, 20, TUNABLE_RESTART_NEEDED)

This file gets included twice by tune.cc, once to create all the
variables and once to build the parameter list.  The net result is
something like this (after pre-processing):

int tune_name;
int tune_NPROC;
struct {
  char *name;
  int min, max, default, flags;
  int *variable;
} tune_list[] = {
  { "name", min, max, default, flags, &tune_name },
  { "NPROC", min, max, default, flags, &tune_NPROC },
  { 0, 0, 0, 0, 0, 0 }
};

Thus, each module that *uses* a tunable parameter would just have a
line like this:

extern int tune_NPROC;

There would be some function (like initialize_tunable_parameters())
that sets up the values of the tunable parameters, which would be
called for each program start.  User-set values would be stored
in the registry under the cygwin key, say Cygwin\Program Options\Tuning
(but the mechanics of this would be hidden to the application).

While it is possible to use this system to change the dll's behavior
during the execution of an application (say, to change timings), it is
not the intent to support that feature robustly.  This eliminates the
need to store the current values in shared memory and coordinate
updates between applications.  Most values will be "restart needed"
type values.  The only planned application is the one that sets the
global list (registry), which would be run by the user to set personal
or system preferences.  It is not appropriate to use this mechanism
for application-specific values (they should use an init file or the
registry for that).  Also, cygwin developers should avoid using this
mechanism for values that should be dynamic or app-selectable.

Reading the tunable parameters from the registry should be one of the
first things the dll does, and thus should be independent of any other
dll initialization.

Only the first call to get_tunable_parameter_list() builds the
read-only list of parameters, but the values in this list are updated
whenever any parameter is changed.


/**** Questions ****/

Should we bother supporting parameters that aren't "restart
everything"?  Anything that can be per-process probably should be
process-settable also, not a user-defined constant.

Is there any need for non-integer values?

There are still some things that will require recompiling cygwin1.dll.
Should we make an effort to switch those to be tunable?  Or rather,
should we abandon this mechanism and rely on recompilation to do
tuning?


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]