next up previous contents index
Next: List of available commands Up: Programming with threads Previous: How to retrieve the   Contents   Index


How to define thread-specific parameters

The flow_data structure has a member which can be used to define thread-specific properties :

    char           **extra;

When a thread is created, an array of 100 character strings is allocated but all the strings are NULL, except the first one which is used in the command interpreter. The second string, flow_interp->extra[1] is kept for further use by the command interpreter. The next 98 strings can be used in applications.

We will now explain how flow_interp->extra[0] is used, assuming that flow_interp is a pointer to the current flow_data structure.


flow_interp->extra[0] is a pointer to a Misc_Func structure. This structure has 3 members which are functions :

typedef void    (*pfi_print)(flow_data *, char *);
typedef int     (*pfi_ev)(char *, double *, int *, flow_data *);
typedef double  (*pfi_conv)(char *, flow_data *);

typedef struct MISC_FUNC {
    pfi_print    Print;
    pfi_ev       Ev;
    pfi_conv     Conv;
} Misc_Func;

The default Misc_Func structure that flow_interp->extra[0] points to has the following members : NULL, Evaluate and convert_float. Let

Mi = (Misc_Func *) flow\_interp->extra[0];

If Mi->Print is not NULL then the function print that is used by the interpreter to print messages will send its output to this function instead of using printf. Recall that this function must be a pfi_print as defined in interp.h :

typedef void    (*pfi_print)(flow_data *, char *);

This can be for instance a function that prints the char* in argument on some window. Assume that we use

void My_print_function(flow_data *flow_interp, char *pr);

Then a command that tells the interpreter to print using this function would contain something like this :

    Misc_Func      *Mi;    

    Mi = (Misc_Func *) flow\_interp->extra[0];
    Mi->Print =  My_print_function;

Then the output of all the subsequent commands (in the thread) will be sent to
My_print_function (provided that print is used to produce messages).


The member Mi->Ev is used in the function convert_float in interp.c. Its default value is

int  Evaluate(char *h, double *res, int *dum, flow_data *flow_interp)

This function sends the character string h in the expression evaluator and the result of the evaluation is stored in res. The main reason to change Mi->Ev would be to use another expression evaluator.


The member Mi->conv is used when the instruction [ is used (cf. 4.3.4). In this case all subsequent instructions are sent directly to the expression evaluator, until the instruction ] is reached. The default value of Mi->conv is

double  convert_float(char *arg, flow_data *flow_interp)

The main reason to change Mi->conv would be to use another expression evaluator or even a new interpreter between the instructions [ and ].


Now we explain how to define thread-specific parameters in applications. For this the strings flow_interp[2] to flow_interp[98] can be used. They are initially NULL. The user of the command interpreter library must provide two functions :

void  init_thread_param(flow_data *);
void  clean_thread_param(flow_data *);

The first one is called each time a new thread is created (in particular the main thread). The second one is called when the thread is finished. The argument is the corresponding thread.

If the application needs no thread-specific parameters, these functions can be empty (see the file test/main.c) but they must be defined somewhere.

Now we give an example. Suppose that in our application we need a thread-specific array of 4 integers. We can do like this :

void
init_thread_param(flow_data *flow_interp)
{
    int    *I;
    
    I = (int *) malloc((size_t) 4 * sizeof(int));
    flow_interp->extra[2] = (char *) I;
    
 /* Now could be given some initialization of the array I */
    .
    .
    .
}

void
clean_thread_param(flow_data *flow_interp)
{
    int    *I;

    I = (int *) flow_interp->extra[2];
    free(I);
}

In a command, the thread-specific array can be retrieved as follows :

int
Xcom(int argc, char *argv[])
{
    int         *I;
    flow_data   *flow_interp;
    
    flow_interp = (flow_data *) argv[-1];
    I = (int *) flow_interp->extra[2];
    .
    .
    .
}


next up previous contents index
Next: List of available commands Up: Programming with threads Previous: How to retrieve the   Contents   Index
2009-11-12