Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT sourceware DOT cygnus DOT com Delivered-To: mailing list cygwin-developers AT sourceware DOT cygnus DOT com Date: Tue, 4 Jan 2000 11:09:34 -0500 Message-Id: <200001041609.LAA06345@envy.delorie.com> From: DJ Delorie To: cygwin-developers AT sourceware DOT cygnus DOT com Subject: 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?