[aspectc-user] Problems with weaving C program

Olaf Spinczyk Olaf.Spinczyk at informatik.uni-erlangen.de
Wed Apr 21 13:22:24 CEST 2004


Hello Mikael,

Mikael Björk wrote:
> Hi
> 
> I'm working on a real-time embedded database system called COMET. In this project we are using aspectC++ to add functionality to the database.
> 
> Since it is an embedded system we are using C, but while there is no AspectC weaver, we use the AspectC++ weaver. Unfortunately this causes some difficulties.
> 
> In some instances we put all the arguments to a function into a struct. That way it is easy to add new arguments with aspects. A problem arises when we want to transfer the values of the introduced arguments on to another struct for another function call within the first function. I illustrate with a brief example:
> 
> struct structA
> {
>    int x;
> };
> 
> struct structB
> {
>    int x;
> };
> 
> int functionA(structA a)
> {
>    structB b;
>    b.x = a.x;
>    return functionB(b);
> }
> 
> If we for example extend structA and structB with "int y", we would like to weave "b.y = a.y" into the code before the call to functionB, so that our weaved changes to functionB can use the variable y.
> 
> As far as I have understood it after some experimentation, I believe that it is not possible to access the arguments of functionA in an advice which happens "before" functionB is "called".
> 
> Am I wrong? And if not, is there some nice way around this problem?
> 
> Regards,
> Mikael Björk

The first possible solution would be to initialize the structB 
explicitly, e.g. by calling "init(b, a);" after instantiating "structB 
b:". This would give your aspect a chance to add the copy operation for 
y to the execution of "void init(structB,structA)".

Another option is to have advice for the execution of functionA and the 
call to functionB within functionA. The first advice could save the 
argument a.y in an attribute of the aspect, the second advice could use 
this value to set b.y.

If your code runs in a multi-threaded environment the second solution is 
dangerous, because there is (by default) only one global instance of the 
aspect. Thus, a concurrent thread could destroy your value saved in the 
aspect attribute. To avoid this problem you would have to create your 
aspect instance per thread. This is done by defining your own aspectof() 
function for the aspect, which should allocate the aspect instance in a 
thread-local memory. At least the win32 API and POSIX threads offer 
thread local storage. Probably any kind of thread packages has a similar 
feature.

I am not sure about the real intention of your code, but I believe that 
you want to transfer values transparently through several layers of your 
system in a thread-safe way. So a third option might be to define advice 
for the joinpoint where the information is produced and a second advice 
for the joinpoint where the information is consumed. Instead of 
extending the argument lists you could pass the information as an aspect 
attribute of a thread-local aspect. Please note, if the joinpoint at 
which the information is produced is executed recursively you need a 
stack instead of a single attribute in the aspect.

In Aspect*J* a similar functionality is provided by the cflow pointcut 
function with context variables in the cflow argument. The AspectJ team 
calls this the "wormhole" pattern, which is really very useful. ac++ 
does not support this feature yet, but definitly will someday. Until 
this day it has to be simulated as described above.

Please tell me if this helps,

Olaf
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3142 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://www.aspectc.org/pipermail/aspectc-user/attachments/20040421/e59aed7c/attachment.bin>


More information about the aspectc-user mailing list