[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