Sharing Data Between UALs

From OC Systems Wiki!
Jump to: navigation, search

There are at least two ways to share data between UALs so they can coordinate actions:

  • exporting a data from one UAL to another
  • using the Aprobe UAL data API

Sharing by Export

You can share data (and functions) from one UAL to reference in another UAL. To do this you will export the data (or function) symbols from one UAL and link the second UAL with the first UAL. This creates a dependency from the second UAL to the first and requires that both UALs be run together or runtime symbol linking errors will occur.

This is an example of sharing data by export/linking. This is the main program code:

#include <stdio.h>

int proc1(int i)
{
   return 5 * i;
}

int proc2(int i)
{
   return 7 * i;
}

int main(int argc, char **argv)
{
   printf("proc1 = %d\n", proc1(5));
   printf("proc2 = %d\n", proc2(5));

   return 0;
}

Here is the first UAL which defines the flag and sets it on entry to proc1:

int flag = 0;

probe thread
{
   probe "proc1"
   {
      on_entry
      {
         flag = 1;
      }
   }   
}

Here is the second UAL which references the flag flag in the probe on proc2:

extern int flag;

probe thread
{
   probe "proc2"
   {
      on_entry
      {
         if (flag) $i = 8;
      }
   }   
}

Here is the script used to build the program main.exe and the two UALs t1.ual and t2.ual. Notice that the -e option is used to export the data object flag from t1.ual and that the UAL t1.ual is included as an argument when compiling UAL t2.ual.

#!/bin/sh

apc -x main.exe -e flag t1.apc
apc -x main.exe -o t2.ual t1.ual t2.apc

aprobe -u t1 -u t2 main.exe

Again, notice that to use UAL t2.ual you must load UAL t1.ual or you will get symbol resolution errors for flag.

Sharing with the Data Key API

Aprobe includes an API through which UALs can share data using unique keys. UALs can create data keys by name and set and get data associated with those keys independent of the presences of other UALs.

This is an example of using data keys using the same program as above.

Here is the common data key name definition (in common.h):

#define UAL_DATA_KEY "MyDataKey"

Here is the first UAL t1.ual which is going to set the flag value:

#include "common.h"

ap_UalDataKeyT DataKey;

probe program
{
   on_entry
   {
      DataKey = ap_UalDataKeyInit(UAL_DATA_KEY, FALSE);
   }
}

probe thread
{
   probe "proc1"
   {
      on_entry
      {
         ap_UalDataSet(DataKey, (void *)1);
      }
   }   
}

Here is the second UAL t2.ual which will get the value of the flag:

#include "common.h"

ap_UalDataKeyT DataKey;

probe program
{
   on_entry
   {
      DataKey = ap_UalDataKeyInit(UAL_DATA_KEY, FALSE);
   }
}

probe thread
{
   probe "proc2"
   {
      on_entry
      {
         if (ap_UalDataGet(DataKey)) $i = 8;
      }
   }   
}

Notice that both UALs initialize their handle to the data key at program start and then use it to set or get the data value. It is up to the user to coordinate the timing between the UALs.

Here is the script to compile the UALs and run the test:

#!/bin/sh

apc -x main.exe t1.apc
apc -x main.exe t2.apc

aprobe -u t1 -u t2 main.exe

Notice that there is no compilation/link dependency between the two UALs. Again, the UALs must coordinate their access to the shared data.