• No se han encontrado resultados

Tradición y estudio del plagio en la tradición de Al-Ándalus

In document UNIVERSITÉ PARIS-SORBONNE (página 74-119)

1.3 Los Padres de la Iglesia. La acusación de plagio como arma ideológica

1.4.2 Tradición y estudio del plagio en la tradición de Al-Ándalus

To become familiar with working with Main Task and creating new entities and tasks, re-implement the Watchdog (previously re-implemented using a user-mode process) in OpenRG's Main Task architecture—entity and task. Create the file mt_watchdog.c under the task directory (rg/pkg/watchdog/task). As discussed previously, every entity is required to implement four functions—open, changed, reconf and close, in order to enable basic entity operations (see Section 16.3). Add these functions to the mt_watchdog.c:

rg/pkg/watchdog/task/mt_watchdog.c

#include <main/mt_main.h>

#include <watchdog/mgt/watchdog_mgt.h>

#include "watchdogt.h"

/* Free entity memory, close task and unregister entity */

static void mt_watchdog_close(rg_entity_t *e) {

mt_entity_remove(e);

free(e);

/* Standard OpenRG entity operations:

* - Changed: check if entity needs reconfiguring

* - Reconf: reconfigure the entity when one of its fields changes * - Close: close the entity, free all resources

*/

static mt_ops_t watchdog_ops = { mt_watchdog_reconf,

mt_watchdog_changed, mt_watchdog_close };

rg_entity_t *mt_watchdog_open(void) {

rg_entity_t *e = (rg_entity_t *)zalloc_e(sizeof(rg_entity_t));

mt_entity_add(e, &watchdog_ops, ENT_WATCHDOG);

rg_error(LCONSOLE, "Watchdog task opened");

return e;

}

Let's review the code:

mt_watchdog_open The open function: at this point, the new entity only allocates a context and registers itself with the entity management mechanism. For further information regarding contexts and task designs, refer to Chapter 12.

mt_watchdog_close The close function: frees the allocated resources if such exist, and unregisters the entity.

mt_watchdog_changed The changed function: since there is no implementation yet, this function returns "no reconf needed".

mt_watchdog_reconf The reconf function: there is no need for reconfiguration yet.

You can see that for now, the reconf and changed functions are empty. You will add content to them as you progress further into the example. The next step is to define the new entity ID in the entity enum in rg/pkg/main/entity.h.

/* This enum is used as an index to an array, so don't go wild

You have added the entity ENT_WATCHDOG enum definition as value 90. In case of adding a new entity, make sure it is added before ENT_COUNT, which is the marker for the last entry.

Note that the entry already exists, you do not need to add it. Since you are going to add a task controlled by this entity, there is a need for a structure to hold the configuration parameters passed to the task. In the Watchdog case, you need to pass two parameters:

1. boot message 2. margin

You may recall from the discussion above that a task is not allowed to access the rg_conf or other tasks–it is the entity's role. So you must provide the task with the means to trigger rg_conf changes as well as query its various fields. This is done by supplying the task with a callback function. The Watchdog task requires the is_watchdog_enabled callback, which queries the Watchdog mgt and returns 1 if the Watchdog sends the keep-alive signal, and 0 otherwise.

Create the task API header file called watchdogt.h (notice the 't' notation to mark task) under the task directory. This header file will serve as the API between the entity, the task, and Main Task.

rg/pkg/watchdog/task/watchdogt.h

#ifndef _WATCHDOGT_H_

#define _WATCHDOGT_H_

...

/* API parameters between the watchdog entity and the watchdog task */

typedef struct watchdog_params_t { int margin;

msg_t boot_msg;

} watchdog_params_t;

/* API callbacks provided by the watchdog entity to the watchdog task */

typedef struct watchdog_cb_t {

int (*is_enabled)(void); /* Is the watchdog task enabled? */

} watchdog_cb_t;

#endif

Now let's go back to Main Task. Since the task will need to query the configuration parameters in the open and reconf functions, define a function that reads the configuration database using mgt, and build the task parameter structure:

rg/pkg/watchdog/task/mt_watchdog.c

#include <watchdog/mgt/watchdog_mgt.h>

...

static void watchdog_param_get(watchdog_params_t *param) {

watchdog_conf_t conf;

watchdog_conf_get(&conf);

strncpy(param->boot_msg.msg, conf.boot_msg.msg, sizeof(msg_t));

param->margin = conf.margin;

}

The new task will need to implement the open, close and reconf functions as well. These functions will be called from the Watchdog entity when needed:

1. open—called when the task is initially opened.

2. close—called when the task is closed.

3. reconf—called when OpenRG needs to reconfigure the task due to parameter changes in the configuration database.

The watchdog_open function will need to return a handle to its private context. This so called 'task context' is saved in the Main Task entity. Add the needed declarations to the task header:

rg/pkg/watchdog/task/watchdogt.h

1 /* Handle for the watchdog task */

2 typedef struct watchdog_t watchdog_t;

3

4 watchdog_t *watchdog_open(watchdog_cb_t *cb);

5 void watchdog_close(watchdog_t *t);

6 void watchdog_reconf(watchdog_t *t, watchdog_params_t *param);

Line 4 is the task open function declaration and it gets the callback structure for future use.

Add the opening of the Watchdog task to the mt_watchdog entity:

rg/pkg/watchdog/task/mt_watchdog.c

6 rg_entity_t *mt_watchdog_open(void) 7 {

8 rg_entity_t *e = (rg_entity_t *)zalloc_e(sizeof(rg_entity_t));

9

10 e->t = watchdog_open(&cb);

11 if (!e->t) 12 goto Error;

13

14 mt_entity_add(e, &watchdog_ops, ENT_WATCHDOG);

15

16 return e;

17

18 Error:

19 free(e);

20 rg_error(LPANIC, "Failed opening watchdog task");

21 return NULL;

22 }

The entity opens the task on line 10 and saves the handle in the entity context (e-->t). All future references to the task will use this context. You may also note that when failing to open the task, you should go to the error handler where the entity is destroyed and a NULL is returned to signal an error.

Line 2 declares the callback structure that will be passed to the task. Note that the callback function used here to test if the Watchdog is enabled is the mgt function

is_watchdog_enabled. Sometimes, the API will not match, and you will have to write your own function that will call the mgt function.

The Main Task entity is almost complete. Remember that the changed and reconf functions are still empty. Add the needed code to the changed function:

1 /* Check if there was a change in one of the parameters:

2 * - margin 3 * - boot message 4 */

5 static reconf_type_t mt_watchdog_changed(rg_entity_t *e) 6 {

The Watchdog entity's relevant fields are only those under the rg_conf path of /watchdog.

Therefore, in line 9 you should recursively compare the new copy and the old copy of the rg_conf sets under the path. The function returns the value NEED_RECONF if the COMP_SET macro indicates that the sets are different, and NO_RECONF otherwise. If the sets are different, OpenRG will call the reconf function.

Implement the reconf function:

/* Get the new params from rg_conf and apply them to the task */

static void mt_watchdog_reconf(rg_entity_t *e) {

watchdog_params_t param;

watchdog_param_get(&param);

/* Reconfigure the task with new parameters */

watchdog_reconf(e->t, &param);

}

At this point, you have set up the ground for the task's functionality. Before going ahead and implementing the task, let's review all the functions that you implemented in the entity:

mt_watchdog_open Called when OpenRG loads, allocates resources, registers and opens the task.

mt_watchdog_close Called when OpenRG goes down, frees resources, closes the task and unregisters.

mt_watchdog_changed Invoked when a change is triggered in OpenRG, and checks if the relevant fields in OpenRG have changed.

mt_watchdog_reconf Invoked if the changed function returned a NEED_RECONF value. If so, it loads the new configuration parameters from rg_conf and calls the task re-configuration function.

In document UNIVERSITÉ PARIS-SORBONNE (página 74-119)