Previous: , Up: Random Number Generators   [Contents][Index]


6.1.3 Custom Random Number Generators

The type of custom random number generator is defined by a user-supplied function qsmm_proxy_func_t and its parameter. Instances of custom random number generator can be created by the function qsmm_rng_create_custom. The type of custom random number generator can be set as the default type of random number generator. Instances of default random number generator are created by the function qsmm_rng_create, which is implicitly called by the functions qsmm_actor_create and qsmm_create when the field rng of structure qsmm_actor_desc_s or qsmm_desc_s has the NULL value.

To retrieve or set a user-supplied function qsmm_proxy_func_t and its parameter, which define the type of default random number generator, the following functions can be used.

Function: void qsmm_get_rng_default (qsmm_proxy_func_t *rng_func_p, void **param_pp)

This function retrieves the type of default random number generator, which is defined by a user-supplied function qsmm_proxy_func_t and its parameter. If rng_func_p is not NULL, then *rng_func_p will be set to a pointer to the user-supplied function or to 0 if a standard random number generator, which type is defined when configuring the package, is used as a default random number generator. If param_pp is not NULL, then *param_pp will be set to a user parameter of function qsmm_proxy_func_t.

Function: void qsmm_set_rng_default (qsmm_proxy_func_t rng_func, void *paramp)

This function sets the type of default random number generator, which is defined by function rng_func and its parameter paramp. If rng_func is NULL, then a standard random number generator, which type is defined when configuring the package, will be used as a default random number generator.

A function, which along with its user parameter defines the type of random number generator, has a prototype of an abstract proxy function that in future versions of the package may be used to perform operations on other objects.

Data type: qsmm_proxy_func_t

This is the type of a pointer to an abstract proxy function. To this type the following declaration corresponds:

typedef int (*qsmm_proxy_func_t)(
    int cmd,
    int in_sz,
    int out_sz,
    const void *in_p,
    void *out_p,
    void *paramp);

A command identifier, which specifies an operation the proxy function should perform, is given via argument cmd. Input command parameters are given via buffer in_p of length in_sz bytes. Output command parameters, i.e. results of command invocation, should be written to buffer out_p of length out_sz (or updated in that buffer). A user parameter, specified when setting the proxy function, is passed via argument paramp.

Upon successful completion, the proxy function must return a non-negative value. In the case of error, the proxy function should return a negative value. Specific interpretation of a value returned depends on an object the function represents and on an operation performed by the function.

Possible values of cmd and expected input parameters and invocation results of commands of a proxy function that implements an interface for abstract random number generator are described below.

Macro: QSMM_RNG_CMD_CREATE

Create a random number generator. The pointer to an object that represents the random number generator should be written to buffer out_p. The value of out_sz is always equal to sizeof(void *). For example, to return pointer rng_state_p to an allocated instance of structure that holds the state of a created random number generator, use a line of code like this:

*((void **) out_p)=rng_state_p;

The proxy function is permitted to return negative error code QSMM_ERR_NOMEM, indicating that there was not enough memory to allocate an object, which represents the random number generator. This error code will be returned by the function qsmm_rng_create or qsmm_rng_create_custom called to create the random number generator.

Macro: QSMM_RNG_CMD_DESTROY

Destroy a random number generator. The pointer to an object that represents the random number generator is passed via buffer in_p. The value of in_sz is always equal to sizeof(void *). For example, to obtain pointer rng_state_p to an allocated instance of structure that holds the state of a random number generator for subsequent destruction of this instance, use the following line of code:

rng_state_p=*((void **) in_p);

The proxy function is only permitted to return a non-negative value.

Macro: QSMM_RNG_CMD_GENERATE

Generate a random number. The pointer to an object that represents a random number generator is passed via buffer in_p. The value of in_sz is always equal to sizeof(void *). A generated random number uniformly distributed in the range 0 (inclusive) to 1 (exclusive) must be written to buffer out_p. The value of out_sz is always equal to sizeof(double). For example, to return generated random number rnd, use a line of code like this:

*((double **) out_p)=rnd;

The proxy function is only permitted to return a non-negative value.

Macro: QSMM_RNG_CMD_SEED

Seed a pseudorandom number generator. An instance of structure qsmm_rng_cmd_seed_in_s (see below) that holds a random seed (the second argument of function qsmm_rng_seed) and the pointer to an object representing the pseudorandom number generator is passed via buffer in_p. The value of in_sz is always equal to sizeof(struct qsmm_rng_cmd_seed_in_s). To obtain seeding parameters, you can use lines of code like these:

const struct qsmm_rng_cmd_seed_in_s *cmd_in_p=in_p;
rng_state_p=cmd_in_p->rng_object_p;

When the pseudorandom number generator does not support the seeding operation, the proxy function is permitted to return negative error code QSMM_ERR_NOTSUP. However, this error code is currently ignored, because the function qsmm_rng_seed returns void.

The following structure is used to pass parameters of seeding operation.

Structure: qsmm_rng_cmd_seed_in_s

This structure is used to pass input parameters of operation of seeding a pseudorandom number generator. It contains the following fields.

Field: int seed

A random seed value.

Field: void * rng_object_p

The pointer to an object that represents the pseudorandom number generator.

Below is the example source code of a proxy function that implements the interface for abstract random number generator.

#include <stdlib.h>
#include <qsmm/qsmm.h>

static int rng_proxy(int cmd,
                     int in_sz,
                     int out_sz,
                     const void *in_p,
                     void *out_p,
                     void *paramp) {
    unsigned int *seed_p;
    switch (cmd) {
        case QSMM_RNG_CMD_CREATE:
            if (!(seed_p=malloc(sizeof(*seed_p)))) return QSMM_ERR_NOMEM;
            *seed_p=1;
            *((void **) out_p)=seed_p;
            break;
        case QSMM_RNG_CMD_DESTROY:
            free(*((void **) in_p));
            break;
        case QSMM_RNG_CMD_GENERATE:
            seed_p=*((void **) in_p);
            *seed_p=*seed_p*1103515245+12345;
            *((double *) out_p)=(*seed_p/65536)%32768/32768.0;
            break;
        case QSMM_RNG_CMD_SEED: {
            const struct qsmm_rng_cmd_seed_in_s *cmd_in_p=in_p;
            seed_p=cmd_in_p->rng_object_p;
            *seed_p=cmd_in_p->seed;
            break;
        }
    }
    return 0;
}

To set this proxy function as a default random number generator, use line of code

qsmm_set_rng_default(&rng_proxy,0);

Previous: , Up: Random Number Generators   [Contents][Index]