AspeCt-oriented C (ACC) Hans-Arno Jacobsen ECE 297 Aspects in ACC An aspect is a file with .acc extension with C code helper function named pointcut before any function call, increase the counter after executing main, print result #include <stdio.h> counter int functionCounter; void printResult() { printf(“total functions called = %d\n”, functionCounter; } pointcut ExecMain(): execution (int main()) ; before(): ExecMain() { before executing functionCounter = 0; main, initialize counter } before() : call($ $(…)) { functionCounter ++; } after(): ExecMain() { Aspect counting # of printResult(); function calls } © 2009 Hans-Arno Jacobsen 2 Memory Profiling Aspect #include <stdio.h> #include <stdlib.h> size_t totalMem = 0; void print() { printf("total = %d \n", totalMem); } advice after(): execution(int main()) { print(); } pointcut before(size_t s): call($ malloc(...)) && args(s) { totalMem += s; } © 2009 Hans-Arno Jacobsen 3 Platform Support … #ifdef __MIPSEB__ /* For big-endian machines. */ #define va_arg(__AP, __type) \ ((__AP = (char *) ((__alignof__ (__type) > 4 \ ? ((int)__AP + 8 - 1) & -8 \ : ((int)__AP + 4 - 1) & -4) \ + __va_rounded_size (__type))), \ *(__type *) (void *) (__AP - __va_rounded_size (__type))) #else /* For little-endian machines. */ … • More of the above #endif • Hardware platform specific #endif customizations #endif /* ! defined (__mips_eabi) */ OS/161 Kernel: kern/arch/mips/include/stdarg.h © 2009 Hans-Arno Jacobsen 7 Error Checking Concern • Error checking code scatters across code base static int __init readonly(char *str) { • It cuts across core logic if (*str) return 0; root_mountflags |= MS_RDONLY; return 1; } static int __init readwrite(char *str) { if (*str) return 0; root_mountflags &= ~MS_RDONLY; return 1; } © 2009 Hans-Arno Jacobsen Linux Kernel 2.6: kernel initialization: do_mount.c … 8 Multiprocessor Support I static int try_to_wake_up(task_t *p, unsigned int state, int sync) { int cpu, this_cpu, success = 0; unsigned long flags; long old_state; runqueue_t *rq; #ifdef CONFIG_SMP unsigned long load, this_load; struct sched_domain *sd, *this_sd = NULL; int new_cpu; #endif … (next slide) © 2009 Hans-Arno Jacobsen Linux Kernel 2.6: kernel/sched.c 9 Multiprocessor Support II rq = task_rq_lock(p, &flags); old_state = p->state; if (!(old_state & state)) • pieces of multiprocessing concern tangled with core logic (1 CPU goto out; case) if (p->array) goto out_running; • not the same piece of code as in previous cases cpu = task_cpu(p); this_cpu = smp_processor_id(); #ifdef CONFIG_SMP if (unlikely(task_running(rq, p))) goto out_activate; new_cpu = cpu; schedstat_inc(rq, ttwu_cnt); … #endif © 2009 Hans-Arno Jacobsen 10 Summary Certain concerns crosscut the principal or core logic (a.k.a. crosscutting concerns) Similar concern code scatters across the code base Different pieces of concern code tangled with core logic Scattering, tangling, and crosscutting apparently leads to code that is hard to read and understand, let alone maintain where the design intent is not cleanly represented in the code where concerns are not well separated and modularized removing a concern is error-prone © 2009 Hans-Arno Jacobsen 11 Crosscutting in C void *NutHeapAlloc(size_t size) { #ifdef NUTDEBUG //code removed #endif NODE **fpp = 0; //code removed #if defined(__arm__) || defined(__m68k__) || defined(__H8300H__) || … while ((size & 0x03) != 0) size++; #endif if (size >= available) { #ifdef NUTDEBUG //code removed #endif return 0; } //code removed …(next column) while (node) { Nut/OS, heap.c //code removed if (fit) { //split the node if too big if (fit->hn_size > …) { //code removed *fpp = node; } else *fpp = fit->hn_next; …} //code removed debug concern } system-specific concern #ifdef NUTDEBUG //code removed optimization concern #endif main functionality return fit; } © 2009 Hans-Arno Jacobsen 12 Another Way to Visualize Crosscutting A file (a module) Red shows lines pertaining to the given concern Not in just one place (i.e., file, function) Not even in a small number of places (files or functions) Most code would show very similar footprints Is there a Solution? For separating crosscutting concerns from core code Pick and choose the concerns required (based on hardware platform etc.) © 2009 Hans-Arno Jacobsen 14 Yes ! © 2009 Hans-Arno Jacobsen 15 AOP Key Idea base/core program weaver final system aspect © 2009 Hans-Arno Jacobsen 16 Aspect-oriented Programming AOP is a programming paradigm that aims to support the modularization of crosscutting concerns in software complementary to existing paradigms Emerged about 10 years ago from different research efforts studying the separation of concerns in software Supported in industry today by IBM, BEA,… AOP support is available for Java, C++, C, PHP, … AspectJ, AspectC++, AspectC, AOPHP, … © 2009 Hans-Arno Jacobsen 17 AspeCt-oriented C (ACC) Designed by Michael Gong and Hans-Arno Jacobsen started around April 2006 as an effort by the Middleware Systems Research Group at the University of Toronto An aspect-oriented extension to C Highlights comprise ANSI-C and C99 compliance gcc source-compatibility Compiler and generated code portability Seamless Linux, Mac OSX, Solaris and Windows support Integration into existing build processes possible Code transparency through source-to-source transformations Open source license for ACC compiler © 2009 Hans-Arno Jacobsen 18 ACC Key Idea normal C files ACC compilation compilation normal C files executable C files with ACC extensions © 2009 Hans-Arno Jacobsen 20 Example: ACC Key Idea Join point declaration Pointcut before(): call ( $ $bootstrap$(...) ) declaration { printf("> Entering %s \n", this->funcName); } advice © 2009 Hans-Arno Jacobsen 21 Join Points Well-defined points in the execution of a program Examples for C The point a function is called The point a function is executed Function calls (before/after) Function execution (before/after) … (call site) (called site) Examples for Java Method calls & execution Field reads & writes Exceptions … © 2009 Hans-Arno Jacobsen 22 Pointcuts Declaratively define sets of join points Call pointcut (all join points associated with the call of a function) Execution pointcut (all join points associated with the execution of a function) Example call($ $bootstrap$(...)) All call join points involving functions that contain the word “bootstrap” in the function name With any list of input parameter types With any return value type © 2009 Hans-Arno Jacobsen 23 Advice The code executed when the associated pointcut matches a join point © 2009 Hans-Arno Jacobsen 24 Building Software Product Lines 16 instances of RBT core 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 rb-test.c test.c rb.c ACC thread pointer trace node count memory profiler aspects © 2009 Hans-Arno Jacobsen 16 28 Use of AOP in Practice Design aspects into systems right from the start (i.e., design with aspects in mind) Use aspects to aid in debugging, analyzing, profiling Development of software product lines Use aspects to refactor existing systems Tailoring and customization Adaptation Extension © 2009 Hans-Arno Jacobsen 29 AspeCtC Resources http://www.AspeCtC.net AspeCtC Tutorial on the web site AspeCtC Language Specification See the AspeCtC web site for submitting a bug report, if you think you found one © 2009 Hans-Arno Jacobsen 30 Other Resources on AOP Aspect-oriented Software Development Portal AspectJ http://www.eclipse.org/aspectj/ AspectC++ http://www.aosd.net http://www.aspectc.org AspeCtC http://www.AspeCtC.net © 2009 Hans-Arno Jacobsen 31 © 2009 Hans-Arno Jacobsen 32 ACC Work Flow © 2009 Hans-Arno Jacobsen 33 ACC Features join point: function call/execution, variable set/get advice: before, after , and around pointcut:call(), execution(), args(), infile(), infunc(), result() pointcut composition, named pointcut proceed() , cflow(), preturn() wildcard character matching through “$” and “…” exception handling: try() pointcut, catch() advice, throw() call reflective information about join points static crosscutting support : add new struct/union member intype() pointcut and introduce() advice support debugging on the original sources match join points inside aspects seemingly integration into existing building system: tacc © 2009 Hans-Arno Jacobsen 34 ACC Example: Nut/OS Ethernut project hardware and open source software project for building tiny embedded Ethernet devices. hardware http://www.ethernut.de/en/ ATmega128 CPU on-chip 128 kBytes of Flash memory external 32 kByte SRAM 10 MBit Ethernet interface software Nut/OS a simple real-time-operating-system ~110 KLOC © 2009 Hans-Arno Jacobsen 35 ACC Example: Tracing In Nut/OS © 2009 Hans-Arno Jacobsen 36 ACC Example: GCC Aspectized GCC 4 a tracing aspect for GCC GCC internal function calls during compilation: #include<stdio.h> void main(){ char *cool = "cool"; printf("%s\n",cool); } 1. main 2. xmalloc_set_program_name 3. unlock_std_streams 4. unlock_1 5. unlock_1 … 637925: delete_temp_files 637926: delete_if_ordinary 637927: stat 637928: delete_if_ordinary 637929: stat © 2009 Hans-Arno Jacobsen 37 www. aspectc © 2009 Hans-Arno Jacobsen .net 38 © 2009 Hans-Arno Jacobsen 39 Example: Memory Profiling I size_t totalMemoryAllocated; int totalAllocationFuncCalled; int totalFreeFuncCalled; void initProfiler(){ totalMemoryAllocated = 0; totalAllocationFuncCalled = 0; totalFreeFuncCalled = 0; } void printProfiler(){ printf("total memory allocated = %d bytes\n", totalMemoryAllocated); … totalAllocationFuncCalled); … totalFreeFuncCalled); } © 2009 Hans-Arno Jacobsen 40 Example: Memory Profiling II before(): execution(int main()) { initProfiler(); } after(): execution(int main()) { printProfiler(); } before(size_t s): call($ malloc(...)) && args(s) { totalMemoryAllocated += s; totalAllocationFuncCalled ++; } © 2009 Hans-Arno Jacobsen 41 Example: Memory Profiling III before(size_t n, size_t s): call($ calloc(...)) && args(n, s) { totalMemoryAllocated += n * s; totalAllocationFuncCalled ++; } before(size_t s): call($ realloc(...)) && args(void *, s) { totalMemoryAllocated += s; totalAllocationFuncCalled ++; } before() : call(void free(void *)) { totalFreeFuncCalled++; } © 2009 Hans-Arno Jacobsen 42 Example: Memory Profiling IV Is the code thread safe? Is thread-safety an aspect? Left as an exercise for the reader . © 2009 Hans-Arno Jacobsen 43