Signed-off-by: Firas Yousfi <firas.yousfi@etu.univ-amu.fr>
Added support for CodeHooks w.r.t. Runnable/Tasks + updated instrumentation behaviour
diff --git a/load_generator/commons/plugins/org.eclipse.app4mc.slg.commons.m2t/src/org/eclipse/app4mc/slg/commons/m2t/generators/InstrumentationGenerator.xtend b/load_generator/commons/plugins/org.eclipse.app4mc.slg.commons.m2t/src/org/eclipse/app4mc/slg/commons/m2t/generators/InstrumentationGenerator.xtend
index c3f37fa..fb00995 100644
--- a/load_generator/commons/plugins/org.eclipse.app4mc.slg.commons.m2t/src/org/eclipse/app4mc/slg/commons/m2t/generators/InstrumentationGenerator.xtend
+++ b/load_generator/commons/plugins/org.eclipse.app4mc.slg.commons.m2t/src/org/eclipse/app4mc/slg/commons/m2t/generators/InstrumentationGenerator.xtend
@@ -33,258 +33,149 @@
 		#include <asm/unistd.h>
 		#include <inttypes.h>
 		
-		void instrument_start_measurement(int counter);
-		void instrument_stop_measurement(int counter);
-		int instrument_start(pid_t pid, uint64_t event_list[], int total_events, int counter);
-		void instrument_stop(int fd, int counter);
-		void instrument_read(int fd);
+		void instrument_start(int* fd, pid_t pid, uint64_t event_list[], int total_events);
+		void instrument_stop(int* fd);
+		void instrument_read(int* fd);
+		
+		void instr_start(void);
+		void instr_stop(void);
+
 	'''
 
 	static def String getSourceFileContent()
 	'''
-		#include "instrument.h"
-		#define LOGFILE "codesnippet.log"
+	#include "instrument.h"
+	#define LOGFILE "output.log"
+	int unique_global_fd[7];
+	
+	void instr_start(void){
+		uint64_t event_list[] = {0x08, 0x12, 0x04, 0x03, 0x16, 0x17};
+		int total_events =  sizeof(event_list)/sizeof(event_list[0]);
 		
-		//average
-		#define ROWLENGTH 80
-		#define FUNCTIONREPEATS 200
-		#define MAXCOUNTERS 7
-		#define MAXDEVIATION 0.01
+		instrument_start(unique_global_fd, 0, event_list, total_events);
+	}
+	
+	void instr_stop(void){
+		instrument_stop(unique_global_fd);
+	}
+	
+	
+	static int perf_event_define(pid_t proccess_id, int group_fd, uint64_t pinned, uint32_t event_type, uint64_t event)
+	{	
+		struct perf_event_attr hw_event;
+		pid_t pid = proccess_id; 	    // measure the current process/thread
+		int cpu = -1; 	                // measure on any cpu
+		unsigned long flags = 0;
+		int fd_current;
 		
+		memset(&hw_event, 0, sizeof(struct perf_event_attr));
+		hw_event.type = event_type;
+		hw_event.size = sizeof(struct perf_event_attr);
+		hw_event.config = event;
+		hw_event.disabled = 1;          // off by default. specifies whether the counter starts out disabled or enabled.
+		hw_event.exclude_kernel = 1; 	// excluding events that happen in the kernel-space
+		hw_event.exclude_hv = 1;      	// excluding events that happen in the hypervisor
+		hw_event.pinned = pinned;		// specifies the counter to be on the CPU if at all possible. applies only to hardware counters and only to group leaders.
+		hw_event.exclude_user = 0; 		//  excludes events that happen in user space
+		hw_event.exclude_callchain_kernel  = 1; // Do not include kernel callchains.
+		hw_event.exclude_callchain_user = 0;	// Do not include user callchains.
+		// hw_event.inherit = 1;		// Inherit does not work for some combinations of read_format values, such as PERF_FORMAT_GROUP.
+		//hw_event.exclusive = 1;		// not working for counters other than cycle counter
+		//hw_event.exclude_idle = 1; 	// doesn't work
 		
-		/* -------------------------------------------------------------------------------------------------------------------------------------- */
-		/* CONFIGURE EVENTS HERE                                                                                                                  */
-		/* -------------------------------------------------------------------------------------------------------------------------------------- */
+		hw_event.read_format = PERF_FORMAT_GROUP; // Allows all counter values in an event group to be read with one read
 		
-		#define NUM_EVENTS 6
-		// currently L1 Instruction Cache Access missing
-		// Events: {memory access, L1 Data Cache Access, LD_RETIRED, ST_RETIRED, L2 Data Cache Access, Linefill because of prefetch}
-		uint64_t eventlist[NUM_EVENTS] = {0x0006, 0x0007, 0x0016, 0x00E7, 0x00E8, 0x0003};
+		fd_current = syscall(__NR_perf_event_open, &hw_event, pid, cpu, group_fd, flags);
+		if (fd_current == -1) {
+		  printf("Error opening leader %llx\n", hw_event.config);
+		  exit(EXIT_FAILURE);
+		}
+	
+	   return fd_current;
+	}
+	
+	void instrument_start(int* fd, pid_t pid, uint64_t event_list[], int total_events){
+		int i;
+		fd[0] = perf_event_define(pid, -1, 1, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES);
+		for (i = 0; i < total_events; i++){
+			fd[i+1] = perf_event_define(pid, fd[0], 0, PERF_TYPE_RAW, event_list[i]);
+		}	
 		
+		/* Example usage:
 		
-		int fd = 0;
+		perf_event_define(fd, 0, PERF_TYPE_RAW, 0x0008);
+		perf_event_define(fd, 0, PERF_TYPE_RAW, 0x0012);
+		perf_event_define(fd, 0, PERF_TYPE_RAW, 0x0004);
+		perf_event_define(fd, 0, PERF_TYPE_RAW, 0x0003);
+		perf_event_define(fd, 0, PERF_TYPE_RAW, 0x0016);
+		perf_event_define(fd, 0, PERF_TYPE_RAW, 0x0017);
 		
-		void instrument_start_measurement(int counter){	
-		    fd = instrument_start(0, eventlist, NUM_EVENTS, counter);
+		int fd = perf_event_define(-1, 1, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES);
+		perf_event_define(fd, 0, PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS);
+		perf_event_define(fd, 0, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
+		perf_event_define(fd , 0, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES);
+		perf_event_define(fd , 0, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES);
+		perf_event_define(fd , 0, PERF_TYPE_HW_CACHE, (PERF_COUNT_HW_CACHE_LL) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16));
+		perf_event_define(fd , 0, PERF_TYPE_HW_CACHE, (PERF_COUNT_HW_CACHE_LL) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16));
+		
+		*/
+		
+		ioctl(fd[0], PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
+		ioctl(fd[0], PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP);
+	}
+	struct read_format {
+	    uint64_t nr; 		// The number of events
+	    struct {
+	        uint64_t value; // The value of the event
+	    } values[];
+	};
+	
+	void instrument_stop(int* fd){
+		ioctl(fd[0], PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP);
+		char buf[4096];
+		read(fd[0], buf, sizeof(buf));
+		
+		int i;	
+		struct read_format* rf = (struct read_format*) buf;
+		
+		for (i = 0; i < rf->nr+1; i++){
+			close(*(fd+i));
 		}
 		
-		void instrument_stop_measurement(int counter){
-			instrument_stop(fd, counter);
-		}
+		FILE * file_pointer;
+		file_pointer = fopen("output.log", "a");
 		
-		static long perf_event_define(pid_t proccess_id, int group_fd, uint64_t pinned, uint32_t event_type, uint64_t event)
-		{	
-			struct perf_event_attr hw_event;
-			pid_t pid = proccess_id; 	    // measure the current process/thread
-			int cpu = -1; 	                // measure on any cpu
-			unsigned long flags = 0;
-			int fd_current;
-			
-			memset(&hw_event, 0, sizeof(struct perf_event_attr));
-			hw_event.type = event_type;
-			hw_event.size = sizeof(struct perf_event_attr);
-			hw_event.config = event;
-			hw_event.disabled = 1;          // off by default. specifies whether the counter starts out disabled or enabled.
-			hw_event.exclude_kernel = 1; 	// excluding events that happen in the kernel-space
-			hw_event.exclude_hv = 1;      	// excluding events that happen in the hypervisor
-			hw_event.pinned = pinned;		// specifies the counter to be on the CPU if at all possible. applies only to hardware counters and only to group leaders.
-			hw_event.exclude_user = 0; 		//  excludes events that happen in user space
-			hw_event.exclude_callchain_kernel  = 1; // Do not include kernel callchains.
-			hw_event.exclude_callchain_user = 0;	// Do not include user callchains.
-			// hw_event.inherit = 1;		// Inherit does not work for some combinations of read_format values, such as PERF_FORMAT_GROUP.
-			//hw_event.exclusive = 1;		// not working for counters other than cycle counter
-			//hw_event.exclude_idle = 1; 	// doesn't work
-			
-			hw_event.read_format = PERF_FORMAT_GROUP; // Allows all counter values in an event group to be read with one read
-			fd_current = syscall(__NR_perf_event_open, &hw_event, pid, cpu, group_fd, flags);
-			if (fd_current == -1) {
-			  printf("Error opening leader %llx\n", hw_event.config);
-			  exit(EXIT_FAILURE);
-			}
-		
-		   return fd_current;
-		}
-		
-		int instrument_start(pid_t pid, uint64_t event_list[], int total_events, int counter){
-			int i;
-			if(counter==0){
-				FILE * file_pointer;
-				file_pointer = fopen(LOGFILE, "w+");
-				fprintf(file_pointer, "CPU cycles\t\t");
-				for (i = 0; i < total_events; i++){
-					switch(event_list[i]){
-						case 0x0001: fprintf(file_pointer, "L1 i refill\t\t"); break;
-						case 0x0002: fprintf(file_pointer, "L1 i tlb refill\t\t"); break;
-						case 0x0003: fprintf(file_pointer, "L1 d refill\t\t"); break;
-						case 0x0004: fprintf(file_pointer, "L1 d access\t\t"); break;
-						case 0x0005: fprintf(file_pointer, "L1 d tlb refill\t\t"); break;
-						case 0x0006: fprintf(file_pointer, "LD_RETIRED\t\t"); break;
-						case 0x0007: fprintf(file_pointer, "ST_RETIRED\t\t"); break;
-						case 0x0013: fprintf(file_pointer, "mem access\t\t"); break;
-						case 0x0014: fprintf(file_pointer, "L1 i access\t\t"); break;
-						case 0x0016: fprintf(file_pointer, "L2 d access\t\t"); break;
-						case 0x0017: fprintf(file_pointer, "L2 d refill\t\t"); break;
-						case 0x00C2: fprintf(file_pointer, "prefetch\t\t"); break;
-						case 0x00E7: fprintf(file_pointer, "_______E8\t\t"); break;
-						case 0x00E8: fprintf(file_pointer, "_______E7\t\t"); break;
-						default: fprintf(file_pointer, "%" PRId64 "\t\t", event_list[i]); break;
-					}
-				}
-				fprintf(file_pointer, "\n");
-				fclose(file_pointer);
-			}
-			fd = perf_event_define(pid, -1, 1, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES);
-			for (i = 0; i < total_events; i++)
-				perf_event_define(pid, fd, 0, PERF_TYPE_RAW, event_list[i]);
-			
-			/* Example usage:
-			
-			perf_event_define(fd, 0, PERF_TYPE_RAW, 0x0008);
-			perf_event_define(fd, 0, PERF_TYPE_RAW, 0x0012);
-			perf_event_define(fd, 0, PERF_TYPE_RAW, 0x0004);
-			perf_event_define(fd, 0, PERF_TYPE_RAW, 0x0003);
-			perf_event_define(fd, 0, PERF_TYPE_RAW, 0x0016);
-			perf_event_define(fd, 0, PERF_TYPE_RAW, 0x0017);
-			
-			int fd = perf_event_define(-1, 1, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES);
-			perf_event_define(fd, 0, PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS);
-			perf_event_define(fd, 0, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
-			perf_event_define(fd , 0, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES);
-			perf_event_define(fd , 0, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES);
-			perf_event_define(fd , 0, PERF_TYPE_HW_CACHE, (PERF_COUNT_HW_CACHE_LL) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16));
-			perf_event_define(fd , 0, PERF_TYPE_HW_CACHE, (PERF_COUNT_HW_CACHE_LL) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16));
-			
-			*/
-			
-			ioctl(fd, PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
-			ioctl(fd, PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP);
-		
-			return fd;
-		}
-		
-		struct read_format {
-		    uint64_t nr; 		// The number of events
-		    struct {
-		        uint64_t value; // The value of the event
-				//uint64_t id; 	// PERF_FORMAT_ID
-				  } values[];
-		};
-		
-		void instrument_stop(int fd, int counter){
-			ioctl(fd, PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP);
-			char buf[4096];
-			read(fd, buf, sizeof(buf));
-			
-			int i;
-			struct read_format* rf = (struct read_format*) buf;
-			
-			FILE * file_pointer;
-			file_pointer = fopen(LOGFILE, "a");
-			for (i = 0; i < rf->nr; i++){
-				if(i == (rf->nr - 1)){
-					fprintf(file_pointer, "%" PRId64, rf->values[i].value);
-					break;
-				}
-				fprintf(file_pointer, "%" PRId64 "\t\t\t", rf->values[i].value);
-				//fprintf(file_pointer, "id: %" PRId64 "\t", rf->values[i].id);
-			}
-			fprintf(file_pointer, "\n");
-			fclose(file_pointer);
-			close(fd);
-			if(counter == (FUNCTIONREPEATS-1)){
-				file_pointer = fopen(LOGFILE, "r");
-				char line[ROWLENGTH];
-				char * del = "\t\t\t";
-				char *ptr;
-				uint64_t help[MAXCOUNTERS] = {0};
-				uint64_t average[MAXCOUNTERS] = {0};
-				i = 0;
-				if(file_pointer != NULL){
-					fgets(line, sizeof(line), file_pointer); // first row should be ignored
-					fgets(line, sizeof(line), file_pointer); // second row does not make any sense
-					while(fgets(line, sizeof(line), file_pointer) != NULL){
-						ptr = strtok(line, del);
-						while(ptr != NULL){
-							help[i] = strtoul(ptr, NULL, 0);
-							i++;
-							//ptr = (char)ptr;
-							ptr = strtok(NULL, del);
-						}
-						for(i = 0; i < rf->nr; i++){
-							average[i] = average[i] + help[i];
-						}
-						i = 0;
-					}
-					for(i = 0; i < rf->nr; i++){
-						if(average[i] != 0){
-							average[i] /= FUNCTIONREPEATS;
-						}
-					}
-				}
-				fclose(file_pointer);
-				file_pointer = fopen(LOGFILE, "r");
-				i = 0;
-				int deviation[MAXCOUNTERS] = {0};
-				if(file_pointer != NULL){
-					fgets(line, sizeof(line), file_pointer); // first row should be ignored
-					fgets(line, sizeof(line), file_pointer); // second row does not make any sense
-					while(fgets(line, sizeof(line), file_pointer) != NULL){
-						ptr = strtok(line, del);
-						while(ptr != NULL){
-							help[i] = strtoul(ptr, NULL, 0);
-							i++;
-							//ptr = (char)ptr;
-							ptr = strtok(NULL, del);
-						}
-						for(i = 0; i < rf->nr; i++){
-							if(((average[i]*(1+MAXDEVIATION)) < help[i]) || ((average[i]*(1-MAXDEVIATION)) > help[i])){
-								deviation[i]++;
-							}
-						}
-						i = 0;
-					}
-				}
-				fclose(file_pointer);
-				file_pointer = fopen(LOGFILE, "a");
-				fprintf(file_pointer, "\nAVERAGES:\n");
-				for (i = 0; i < rf->nr; i++){
-					if(i == (rf->nr - 1)){
-						fprintf(file_pointer, "%" PRId64, average[i]);
-						break;
-					}
-					fprintf(file_pointer, "%" PRId64 "\t\t\t", average[i]);
-				}
-				fprintf(file_pointer, "\nDEVIATIONS:\n");
-				for (i = 0; i < rf->nr; i++){
-					if(i == (rf->nr - 1)){
-						fprintf(file_pointer, "%d", deviation[i]);
-						break;
-					}
-					fprintf(file_pointer, "%d\t\t\t\t", deviation[i]);
-				}
-				fclose(file_pointer);
-			}
-			
-		}
-		
-		void instrument_read(int fd){
-			char buf[4096];
-			read(fd, buf, sizeof(buf));
-		
-			int i;
-			struct read_format* rf = (struct read_format*) buf;
-			
-			FILE * file_pointer;
-			file_pointer = fopen(LOGFILE, "a");
-			
+		if (file_pointer != NULL) {
 			for (i = 0; i < rf->nr; i++)
 				fprintf(file_pointer, "%" PRId64 "\t", rf->values[i].value);
-				//fprintf(file_pointer, "ID: %" PRId64 "\t", rf->values[i].id);
 			fprintf(file_pointer, "\n");
-		
 			fclose(file_pointer);
-			ioctl(fd, PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
 		}
+		else{
+			printf("File Pointer Error");
+		}
+		
+	}
+	
+	void instrument_read(int* fd){
+		char buf[4096];
+		read(fd[0], buf, sizeof(buf));
+	
+		int i;
+		struct read_format* rf = (struct read_format*) buf;
+		
+		FILE * file_pointer;
+		file_pointer = fopen("output.log", "a");
+		
+		for (i = 0; i < rf->nr; i++)
+			fprintf(file_pointer, "%" PRId64 "\t", rf->values[i].value);
+		fprintf(file_pointer, "\n");
+	
+		fclose(file_pointer);
+		ioctl(fd[0], PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
+	}
+	
+
 		
 		
 	'''
diff --git a/load_generator/commons/plugins/org.eclipse.app4mc.slg.commons.m2t/src/org/eclipse/app4mc/slg/commons/m2t/transformers/sw/RunnableTransformer.java b/load_generator/commons/plugins/org.eclipse.app4mc.slg.commons.m2t/src/org/eclipse/app4mc/slg/commons/m2t/transformers/sw/RunnableTransformer.java
index 47adfc4..aaf67e0 100644
--- a/load_generator/commons/plugins/org.eclipse.app4mc.slg.commons.m2t/src/org/eclipse/app4mc/slg/commons/m2t/transformers/sw/RunnableTransformer.java
+++ b/load_generator/commons/plugins/org.eclipse.app4mc.slg.commons.m2t/src/org/eclipse/app4mc/slg/commons/m2t/transformers/sw/RunnableTransformer.java
@@ -15,6 +15,7 @@
 
 package org.eclipse.app4mc.slg.commons.m2t.transformers.sw;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -22,13 +23,23 @@
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 
+import org.eclipse.app4mc.amalthea.model.ActivityGraph;
 import org.eclipse.app4mc.amalthea.model.ActivityGraphItem;
 import org.eclipse.app4mc.amalthea.model.Runnable;
+import org.eclipse.app4mc.amalthea.model.StringObject;
+import org.eclipse.app4mc.amalthea.model.Value;
+import org.eclipse.app4mc.amalthea.model.impl.CustomPropertyImpl;
+import org.eclipse.app4mc.slg.commons.m2t.CustomObjectsStore;
 import org.eclipse.app4mc.slg.commons.m2t.generators.RunnableGenerator;
 import org.eclipse.app4mc.slg.commons.m2t.transformers.SLGBaseTransformer;
 import org.eclipse.app4mc.slg.commons.m2t.transformers.SLGTranslationUnit;
+import org.eclipse.app4mc.slg.config.CodehookType;
+import org.eclipse.app4mc.slg.config.ConfigModel;
+import org.eclipse.app4mc.slg.config.util.ConfigModelUtils;
 import org.eclipse.app4mc.transformation.util.OutputBuffer;
+import org.eclipse.emf.ecore.EObject;
 
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -38,6 +49,8 @@
 
 	@Inject private OutputBuffer outputBuffer;
 	@Inject private ActivityGraphItemTransformer activityGraphItemTransformer;
+	@Inject private CustomObjectsStore customObjsStore;
+	@Inject private Properties properties;
 
 	// ---------- generic part "def create new transform(...)" ----------
 
@@ -90,10 +103,14 @@
 			srcAppend(tu, "#include \"" + getIncFile(tu) + "\"\n");
 		}
 
+		boolean extOverwrite = false; 
 		final HashSet<String> includes = new LinkedHashSet<>();
 		final List<String> calls = new ArrayList<>();
+		final List<String> callsOverwrite = new ArrayList<>();
 		
 		if (runnable != null && runnable.getActivityGraph() != null) {
+			extOverwrite = processCustomProperties(extOverwrite, calls, callsOverwrite, runnable.getActivityGraph());
+
 			for (ActivityGraphItem item : runnable.getActivityGraph().getItems()) {
 
 				final SLGTranslationUnit tmpTU = activityGraphItemTransformer.transform(item);
@@ -110,19 +127,97 @@
 		}
 
 		incAppend(tu, "\n//Runnable " + runnable.getName() + "----\n");
-		toH(tu, includes);
+		toH(tu,runnable.getName(), includes);
 
 		srcAppend(tu, "\n//Runnable " + runnable.getName() + "----\n");
-		toCpp(tu, calls);
+		if (extOverwrite) {
+
+			srcAppend(tu, "void " + tu.getCall() + "{\n");
+
+			for (String call : callsOverwrite) {
+				srcAppend(tu, call + ";" + "\n");
+			}
+			srcAppend(tu, "\n" + "}" + "\n");
+		}
+		// ------------------------
+
+		else {
+			toCpp(tu, calls); // write body without overwriting the codehook function
+		}
+	}
+	
+	protected boolean processCustomProperties(boolean extOverwrite, final List<String> calls,
+			final List<String> callsOverwrite, final ActivityGraph activityGraph) {
+		
+		for(EObject item : activityGraph.eContents()) {
+			
+			if (item instanceof CustomPropertyImpl) // custom property:
+			{
+				boolean enableExtCode = Boolean.parseBoolean(properties.getProperty("enableExternalCode"));
+				if (enableExtCode) {
+					if (((CustomPropertyImpl) item).getKey().equals("codehook")) {
+						
+						Value value = ((CustomPropertyImpl) item).getValue();
+						
+						if (value instanceof StringObject) {
+							
+							calls.add(((StringObject) value).getValue());
+							
+						}
+					} else if (((CustomPropertyImpl) item).getKey().equals("codehook_overwrite")) {
+						extOverwrite = true;
+						Value value1 = ((CustomPropertyImpl) item).getValue();
+						
+						if (value1 instanceof StringObject) {
+							
+							callsOverwrite.add(((StringObject) value1).getValue());
+							
+						}
+						
+					}
+				}
+			}
+		}
+		return extOverwrite;
 	}
 
-	protected void toH(final SLGTranslationUnit tu, final HashSet<String> includes) {
-		for (String include : includes) {
-			incAppend(tu, "#include \"" + include + "\"\n");
+	protected void toH(final SLGTranslationUnit tu, final String runnableName, final HashSet<String> includes) {
+
+		if (isIncFileEmpty(tu)) {
+
+			final ConfigModel configModel = customObjsStore.<ConfigModel>getInstance(ConfigModel.class);
+			boolean enableExtCode = Boolean.parseBoolean(properties.getProperty("enableExternalCode"));
+
+			if (enableExtCode) // fetching the names of the external codehook files
+			{
+				for (String hDir : ConfigModelUtils.getHeaderFilesDirectories(configModel, CodehookType.RUNNABLE)) {
+					final File folder = new File(hDir.trim()); // fetching all the names in the headerfile directory.
+					String names = ConfigModelUtils.getHeaderFilesIncludeMultiString(folder, new StringBuffer());
+					incAppend(tu, names);
+				}
+
+			}
+
+			incAppend(tu, "#include <string.h>\n");
+			for (String include : includes) {
+				incAppend(tu, "#include \"" + include + "\"\n");
+			}
+
 		}
 
-		incAppend(tu, "void " + tu.getCall() + ";\n");
+		incAppend(tu, "\n//Runnable " + runnableName + "----\n");
+
+		incAppend(tu, "void " + tu.getCall() + "(char* coreName);\n");
+
 	}
+	
+	/*
+	 * protected void toH(final SLGTranslationUnit tu, final HashSet<String>
+	 * includes) { for (String include : includes) { incAppend(tu, "#include \"" +
+	 * include + "\"\n"); }
+	 * 
+	 * incAppend(tu, "void " + tu.getCall() + ";\n"); }
+	 */
 
 	protected void toCpp(final SLGTranslationUnit tu, final List<String> calls) {
 		srcAppend(tu, "void " + tu.getCall() + "{\n");
diff --git a/load_generator/commons/plugins/org.eclipse.app4mc.slg.commons.m2t/src/org/eclipse/app4mc/slg/commons/m2t/transformers/sw/TicksUtilsTransformer.java b/load_generator/commons/plugins/org.eclipse.app4mc.slg.commons.m2t/src/org/eclipse/app4mc/slg/commons/m2t/transformers/sw/TicksUtilsTransformer.java
index 260d187..0fabc6b 100644
--- a/load_generator/commons/plugins/org.eclipse.app4mc.slg.commons.m2t/src/org/eclipse/app4mc/slg/commons/m2t/transformers/sw/TicksUtilsTransformer.java
+++ b/load_generator/commons/plugins/org.eclipse.app4mc.slg.commons.m2t/src/org/eclipse/app4mc/slg/commons/m2t/transformers/sw/TicksUtilsTransformer.java
@@ -29,6 +29,7 @@
 import org.eclipse.app4mc.slg.commons.m2t.transformers.SLGBaseTransformer;
 import org.eclipse.app4mc.slg.commons.m2t.transformers.SLGTranslationUnit;
 import org.eclipse.app4mc.slg.config.ConfigModel;
+import org.eclipse.app4mc.slg.config.PlatformArchitecture;
 import org.eclipse.app4mc.transformation.util.OutputBuffer;
 import org.eclipse.emf.ecore.EClass;
 
@@ -108,8 +109,16 @@
 	protected void toCPP(SLGTranslationUnit tu) {
 		srcAppend(tu, "#include \"" + getIncFile(tu) + "\"\n");
 
+
+		
 		final ConfigModel configModel = customObjsStore.<ConfigModel>getInstance(ConfigModel.class);
 
+		PlatformArchitecture platformArchitectureType = configModel.getPlatformArchitectureType();
+		
+		if(platformArchitectureType!=null) {
+			
+			srcAppend(tu, "#define __" + platformArchitectureType.getName() + "__\n");
+		}
 		final String ticksCodeSnippet = configModel.getCustomTickImpl().getValue();
 		final boolean ticksCodeEnabled = configModel.getCustomTickImpl().isEnable();
 		
diff --git a/load_generator/commons/plugins/org.eclipse.app4mc.slg.config/src/org/eclipse/app4mc/slg/config/util/ConfigModelUtils.java b/load_generator/commons/plugins/org.eclipse.app4mc.slg.config/src/org/eclipse/app4mc/slg/config/util/ConfigModelUtils.java
new file mode 100644
index 0000000..c1baa0e
--- /dev/null
+++ b/load_generator/commons/plugins/org.eclipse.app4mc.slg.config/src/org/eclipse/app4mc/slg/config/util/ConfigModelUtils.java
@@ -0,0 +1,59 @@
+package org.eclipse.app4mc.slg.config.util;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.app4mc.slg.config.CodeHooks;
+import org.eclipse.app4mc.slg.config.CodehookType;
+import org.eclipse.app4mc.slg.config.ConfigModel;
+import org.eclipse.app4mc.slg.config.HeaderFiles;
+
+public class ConfigModelUtils {
+
+	public static List<String> getHeaderFilesDirectories(ConfigModel configModel, CodehookType codehookType) {
+
+		List<String> ls = new ArrayList<String>();
+
+		CodeHooks codeHooks = configModel.getCodeHooks();
+		if (codeHooks != null) {
+			for (HeaderFiles headerFile : codeHooks.getHeaderFiles()) {
+				if (headerFile.getCodehookType().getName().equals(codehookType.getName())) 
+				{
+					for (String hfileDir : headerFile.getHeaderFilesDirectories()) {
+						ls.add(hfileDir);
+					}
+
+				}
+				return ls;
+			}
+
+		}
+
+		return ls;
+	}
+	
+	public static String getHeaderFilesIncludeMultiString(File folder,StringBuffer sb) {
+		
+		if(folder.exists()&&folder.isDirectory()) {
+			
+			for ( File fileEntry : folder.listFiles()) {
+				if (!fileEntry.isDirectory()) {
+					if (fileEntry.getName().endsWith(".h"))
+					{
+						sb.append("#include \"");
+						sb.append(fileEntry.getName());
+						sb.append('\"');
+						sb.append(System.getProperty("line.separator"));
+					}
+					
+				}
+			}
+		}else {
+			System.err.println("Input header folder doesnot exist/it is not a directory : "+folder.getPath() );
+		}
+ 		
+	    return sb.toString();
+	
+	}
+}
diff --git a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/customization/CustomRunnableGenerator.xtend b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/customization/CustomRunnableGenerator.xtend
index 53e8759..1e83e7b 100644
--- a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/customization/CustomRunnableGenerator.xtend
+++ b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/customization/CustomRunnableGenerator.xtend
@@ -19,10 +19,17 @@
 import org.eclipse.app4mc.amalthea.model.Process
 import org.eclipse.app4mc.amalthea.model.Stimulus
 import org.eclipse.app4mc.amalthea.model.Task
+import org.eclipse.app4mc.slg.linux.generators.LinuxRunnableGenerator
 
-class CustomRunnableGenerator {
+class CustomRunnableGenerator extends LinuxRunnableGenerator {
+	
+	new(){
+		super();
+	}
 
-	static def handleInterProcessTrigger(Stimulus stimulus, List<Process> processedTasks) {
+	
+	static def handleInterProcessTrigger(Stimulus stimulus, List<Process> processedTasks) {	
+		
 		val StringBuilder builder = new StringBuilder
 
 		if (stimulus !== null) {
@@ -32,7 +39,7 @@
 
 				if (process instanceof Task) {
 					var codeSnippet = '''
-						
+
 						//interprocess trigger
 						«IF processedTasks.contains(process)==false»
 							pthread_t «process.name»_;
diff --git a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/customization/CustomRunnableTransformer.java b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/customization/CustomRunnableTransformer.java
index 48ef88f..7de1295 100644
--- a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/customization/CustomRunnableTransformer.java
+++ b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/customization/CustomRunnableTransformer.java
@@ -23,15 +23,18 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Properties;
 
 import org.eclipse.app4mc.amalthea.model.ActivityGraphItem;
 import org.eclipse.app4mc.amalthea.model.InterProcessTrigger;
 import org.eclipse.app4mc.amalthea.model.Process;
 import org.eclipse.app4mc.amalthea.model.Runnable;
 import org.eclipse.app4mc.amalthea.model.Ticks;
+import org.eclipse.app4mc.slg.commons.m2t.CustomObjectsStore;
 import org.eclipse.app4mc.slg.commons.m2t.transformers.SLGTranslationUnit;
 import org.eclipse.app4mc.slg.commons.m2t.transformers.sw.ActivityGraphItemTransformer;
 import org.eclipse.app4mc.slg.commons.m2t.transformers.sw.RunnableTransformer;
+import org.eclipse.emf.ecore.EObject;
 
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -40,11 +43,18 @@
 public class CustomRunnableTransformer extends RunnableTransformer {
 
 	@Inject private ActivityGraphItemTransformer activityGraphItemTransformer;
+	@Inject private CustomObjectsStore customObjsStore;
+	@Inject private Properties properties;
+
 
 	// ---------- generic part "def create new transform(...)" ----------
+	
+
+	
+	
 
 	private final Map<List<Object>, SLGTranslationUnit> transformCache = new HashMap<>();
-
+	
 	@Override
 	public Map<List<Object>, SLGTranslationUnit> getCache() {
 		return this.transformCache;
@@ -81,6 +91,9 @@
 			String basePath = "synthetic_gen";
 			String moduleName = "runnables";
 			String call = "run_" + runnable.getName();
+			
+			
+			
 			return new SLGTranslationUnit(basePath, moduleName, call);
 		}
 	}
@@ -92,6 +105,7 @@
 
 	@Override
 	protected void genFiles(final SLGTranslationUnit tu, final Runnable runnable) {
+		boolean extOverwrite = false; // enabling codehook overwriting
 		if (isSrcFileEmpty(tu)) {
 			srcAppend(tu, "#include \"" + getIncFile(tu) + "\"\n");
 			srcAppend(tu, "#include \"ticksUtils.h\"\n");
@@ -99,21 +113,28 @@
 
 		final HashSet<String> includes = new LinkedHashSet<>();
 		final List<String> calls = new ArrayList<>();
+		final List<String> callsOverwrite = new ArrayList<>(); //overwrite codehook fct
 		final List<Process> processedTasks = new ArrayList<>();
 
 		if (runnable != null && runnable.getActivityGraph() != null) {
-			for (final ActivityGraphItem item : runnable.getActivityGraph().getItems()) {
+
+			extOverwrite = processCustomProperties(extOverwrite, calls, callsOverwrite, runnable.getActivityGraph());
+
+			// ************ Looping through all the elements inside ActivityGraph object
+			for (final EObject item : runnable.getActivityGraph().eContents()) {
+
 				if (item instanceof Ticks) {
 					Ticks ticks = (Ticks) item;
-					final Map<String, SLGTranslationUnit> translationUnits = activityGraphItemTransformer.transformAllItems(ticks); // Mc: move method to TicksTransformer ?
-	
+					final Map<String, SLGTranslationUnit> translationUnits = activityGraphItemTransformer
+							.transformAllItems(ticks); // Mc: move method to TicksTransformer ?
+
 					SLGTranslationUnit defaultTicksTU = null;
 					boolean ticksAssociatedToPUs = false;
-					
+
 					for (final Entry<String, SLGTranslationUnit> entry : translationUnits.entrySet()) {
 						String puName = entry.getKey();
 						SLGTranslationUnit tmpTU = entry.getValue();
-						
+
 						if (puName.equals("default")) {
 							defaultTicksTU = tmpTU;
 						} else {
@@ -123,7 +144,8 @@
 							}
 							final String call = tmpTU.getCall();
 							if (call != null && !call.isEmpty()) {
-								calls.add(ticksAssociatedToPUs ? "else if(strcmp(coreName,\"" + puName + "\")==0){" : " if(strcmp(coreName,\"" + puName + "\")==0){");
+								calls.add(ticksAssociatedToPUs ? "else if(strcmp(coreName,\"" + puName + "\")==0){"
+										: " if(strcmp(coreName,\"" + puName + "\")==0){");
 								calls.add(call);
 								calls.add("}");
 								ticksAssociatedToPUs = true;
@@ -136,26 +158,30 @@
 							calls.add("else ");
 							calls.add("{");
 						}
-						
+
 						if (defaultTicksTU.getCall() != null && !defaultTicksTU.getCall().isEmpty()) {
 							calls.add(defaultTicksTU.getCall());
 						}
-						
+
 						if (ticksAssociatedToPUs) {
 							calls.add("}");
 						}
 
 					}
-				} else {
+				} else if (item instanceof ActivityGraphItem) {
 					if ((item instanceof InterProcessTrigger)) {
 						InterProcessTrigger trigger = (InterProcessTrigger) item;
-						final String value = CustomRunnableGenerator.handleInterProcessTrigger(trigger.getStimulus(), processedTasks);
+						// final ConfigModel configModel =
+						// customObjsStore.<ConfigModel>getInstance(ConfigModel.class);
+						final String value = CustomRunnableGenerator.handleInterProcessTrigger(trigger.getStimulus(),
+								processedTasks);
 						if (value != null && !value.trim().isEmpty()) {
 							calls.add(value);
 						}
 					} else {
-						final SLGTranslationUnit tmpTU = activityGraphItemTransformer.transform(item);
-						
+						final SLGTranslationUnit tmpTU = activityGraphItemTransformer
+								.transform((ActivityGraphItem) item);
+
 						final String tmpIncFile = getIncFile(tmpTU);
 						if (tmpIncFile != null && !tmpIncFile.isEmpty() && !getIncFile(tu).equals(tmpIncFile)) {
 							includes.add(tmpIncFile);
@@ -167,7 +193,7 @@
 					}
 				}
 			}
-		
+
 		}
 
 		String runnableName = runnable.getName();
@@ -177,25 +203,33 @@
 		
 		// write body
 		srcAppend(tu, "\n//Runnable " + runnableName + "----\n");
-		toCpp(tu, calls);
-	}
-
-	protected void toH(final SLGTranslationUnit tu, final String runnableName, final HashSet<String> includes) {
-		if (isIncFileEmpty(tu)) {
-			incAppend(tu, "#include <string.h>\n");
-		}
 		
-		for(String include : includes) {
-			incAppend(tu, "#include \"" + include + "\"\n");
+		//------------------------  write body with overwrite codehook  function 
+		
+		if (extOverwrite) {
+			String call_overwrite = "run_" + runnable.getName();
+
+			srcAppend(tu, "void " + call_overwrite + "(char* coreName){\n" + "\n");
+
+			for (String call : callsOverwrite) {
+				srcAppend(tu, call + ";" + "\n");
+			}
+			srcAppend(tu, "\n" + "}" + "\n");
 		}
+		// ------------------------
 
-		incAppend(tu, "\n//Runnable " + runnableName + "----\n");
-
-		incAppend(tu, "void " + tu.getCall() + "(char* coreName);\n");
+		else {
+			toCpp(tu, calls); // write body without overwriting the codehook function
+		}
 	}
 
+	
+
+
 	@Override
-	protected void toCpp(final SLGTranslationUnit tu, final List<String> calls) {
+	protected void toCpp(final SLGTranslationUnit tu, final List<String> calls) {  
+		
+	
 		srcAppend(tu, "void " + tu.getCall() + "(char* coreName){\n");
 		
 		for (String call : calls) {
@@ -203,6 +237,7 @@
 		}
 
 		srcAppend(tu, "}\n\n");
+		
 	}
 
 }
diff --git a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/artefacts/LinuxSLGTransformationDefinition.java b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/artefacts/LinuxSLGTransformationDefinition.java
index 0bcc289..43bb900 100644
--- a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/artefacts/LinuxSLGTransformationDefinition.java
+++ b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/artefacts/LinuxSLGTransformationDefinition.java
@@ -50,6 +50,9 @@
 		return Arrays.asList(
 				new TransformationParameter("SLG Settings", "configurationFile", "Configuration Model", File.class),
 				new TransformationParameter("Linux SLG Settings", "experimentalCodeSnippetMatching", "Experimental Code Snippet Matching", Boolean.class),
-				new TransformationParameter("Linux SLG Settings", "enableInstrumentation", "Enable Instrumentation", Boolean.class));
+				new TransformationParameter("Linux SLG Settings", "enableInstrumentation_Tasks", "Enable Instrumentation", Boolean.class),				
+				new TransformationParameter("Linux SLG Settings", "enableInstrumentation_Runnables", "Enable Instrumentation Runnables", Boolean.class),
+				new TransformationParameter("Linux SLG Settings", "enableExternalCode", "Enable External Code", Boolean.class));
+		
 	}
 }
diff --git a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/generators/LinuxMakeGenerator.xtend b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/generators/LinuxMakeGenerator.xtend
index 47853b3..a54dac1 100644
--- a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/generators/LinuxMakeGenerator.xtend
+++ b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/generators/LinuxMakeGenerator.xtend
@@ -15,6 +15,10 @@
 
 package org.eclipse.app4mc.slg.linux.generators
 
+import org.eclipse.app4mc.slg.config.ConfigModel
+import java.util.List
+import java.util.ArrayList
+
 class LinuxMakeGenerator {
 
 	// Suppress default constructor
@@ -22,18 +26,29 @@
 		throw new IllegalStateException("Utility class");
 	}
 
-	static def String getContent(boolean experimentalCodeMatching, boolean instrumentation) '''
-		synthetic: main.o tasks.o runnables.o «IF experimentalCodeMatching»codesnippets.o«ENDIF» «IF instrumentation»instrument.o«ENDIF» «IF !experimentalCodeMatching» labels.o ticksUtils.o«ENDIF»
-			gcc -o synthetic main.o tasks.o runnables.o «IF !experimentalCodeMatching» labels.o ticksUtils.o«ENDIF» «IF experimentalCodeMatching»codesnippets.o«ENDIF» «IF instrumentation»instrument.o«ENDIF» -pthread
+private static def String getHeaderFilesDirectory(ConfigModel configModel){
+	
+	val StringBuffer buffer=new StringBuffer
+	
+	for(headerFile : configModel?.codeHooks?.headerFiles){
+		for(hfileDir: headerFile.headerFilesDirectories){
+			buffer.append("-I"+hfileDir+ " ")
+		}
+	}
+	return buffer.toString.trim;
+}
+	static def String getContent(boolean experimentalCodeMatching, boolean instrumentation, boolean instrumentation_R, boolean externalCode, ConfigModel configModel) '''
+		synthetic: main.o tasks.o runnables.o «IF experimentalCodeMatching»codesnippets.o«ENDIF» «IF instrumentation»instrument.o «ELSEIF instrumentation_R»instrument.o«ENDIF» «IF !experimentalCodeMatching» labels.o ticksUtils.o«ENDIF»
+			gcc -o synthetic main.o tasks.o runnables.o «IF !experimentalCodeMatching» labels.o ticksUtils.o«ENDIF» «IF experimentalCodeMatching»codesnippets.o«ENDIF» «IF instrumentation_R»instrument.o «ELSEIF instrumentation»instrument.o«ENDIF» -pthread «IF externalCode»«FOR LibPath : configModel.codeHooks?.libLocations?.getLinkedLibraries()» «LibPath» «ENDFOR»«ENDIF»
 		
 		main.o: Executable/main/_src/main.c
-			gcc -c «IF !experimentalCodeMatching»-Isynthetic_gen/labels/_inc -Isynthetic_gen/ticksUtils/_inc«ENDIF»  -Isynthetic_gen/tasks/_inc -Isynthetic_gen/runnables/_inc -Isynthetic_gen «IF experimentalCodeMatching»-Isynthetic_gen/codesnippets/_inc«ENDIF» Executable/main/_src/main.c
+			gcc -c «IF !experimentalCodeMatching»-Isynthetic_gen/labels/_inc -Isynthetic_gen/ticksUtils/_inc«ENDIF»  -Isynthetic_gen/tasks/_inc -Isynthetic_gen/runnables/_inc -Isynthetic_gen «IF externalCode»«getHeaderFilesDirectory(configModel)»«ENDIF» «IF experimentalCodeMatching»-Isynthetic_gen/codesnippets/_inc «ENDIF»Executable/main/_src/main.c
 		
 		tasks.o: synthetic_gen/tasks/_src/tasks.c
-			gcc -c «IF !experimentalCodeMatching»-Isynthetic_gen/labels/_inc -Isynthetic_gen/ticksUtils/_inc«ENDIF»  -Isynthetic_gen/tasks/_inc -Isynthetic_gen/runnables/_inc «IF experimentalCodeMatching»-Isynthetic_gen/codesnippets/_inc«ENDIF» synthetic_gen/tasks/_src/tasks.c
+			gcc -c «IF !experimentalCodeMatching»-Isynthetic_gen/labels/_inc -Isynthetic_gen/ticksUtils/_inc«ENDIF»  -Isynthetic_gen/tasks/_inc -Isynthetic_gen/runnables/_inc «IF externalCode»«getHeaderFilesDirectory(configModel)»«ENDIF» «IF experimentalCodeMatching»-Isynthetic_gen/codesnippets/_inc «ENDIF»synthetic_gen/tasks/_src/tasks.c
 			
 		runnables.o: synthetic_gen/runnables/_src/runnables.c
-			gcc -c «IF !experimentalCodeMatching»-Isynthetic_gen/labels/_inc -Isynthetic_gen/ticksUtils/_inc«ENDIF»  -Isynthetic_gen/runnables/_inc  «IF experimentalCodeMatching»-Isynthetic_gen/codesnippets/_inc«ENDIF» synthetic_gen/runnables/_src/runnables.c -O2
+			gcc -c «IF !experimentalCodeMatching»-Isynthetic_gen/labels/_inc -Isynthetic_gen/ticksUtils/_inc«ENDIF»  -Isynthetic_gen/runnables/_inc «IF externalCode»«getHeaderFilesDirectory(configModel)»«ENDIF» «IF experimentalCodeMatching»-Isynthetic_gen/codesnippets/_inc «ENDIF»synthetic_gen/runnables/_src/runnables.c -O2
 		
 		
 		«IF !experimentalCodeMatching»
@@ -51,7 +66,11 @@
 		«IF instrumentation »	
 			instrument.o: synthetic_gen/instrument.c
 				gcc -c -Isynthetic_gen synthetic_gen/instrument.c
+		«ELSEIF instrumentation_R »	
+		instrument.o: synthetic_gen/tasks/_src/instrument.c
+				gcc -c -Isynthetic_gen synthetic_gen/tasks/_src/instrument.c
 		«ENDIF»
+		
 	'''
 
 }
diff --git a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/generators/LinuxRunnableGenerator.xtend b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/generators/LinuxRunnableGenerator.xtend
index cd73949..0c03b7b 100644
--- a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/generators/LinuxRunnableGenerator.xtend
+++ b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/generators/LinuxRunnableGenerator.xtend
@@ -16,36 +16,52 @@
 package org.eclipse.app4mc.slg.linux.generators
 
 import java.util.HashMap
+import java.util.Properties
 import org.eclipse.app4mc.amalthea.model.LabelAccess
 import org.eclipse.app4mc.amalthea.model.MinAvgMaxStatistic
 import org.eclipse.app4mc.amalthea.model.Runnable
 import org.eclipse.app4mc.amalthea.model.SingleValueStatistic
+import org.eclipse.app4mc.amalthea.model.StringObject
 import org.eclipse.app4mc.amalthea.model.Ticks
-import java.util.Properties
+import org.eclipse.app4mc.amalthea.model.impl.CustomPropertyImpl
+import org.eclipse.app4mc.slg.config.ConfigModel
+import org.eclipse.app4mc.slg.config.PlatformArchitecture
 
-class LinuxRunnableGenerator {
+public class LinuxRunnableGenerator {
+	
 
-	// Suppress default constructor.
-	private new() {
-		throw new IllegalStateException("Utility class");
-	}
-
-	def static String snippetSrcStart()
+	def static String snippetSrcStart(ConfigModel configModel)
 		'''
 			#include "runnables.h"
 			#include "codesnippets.h"
 			
-			void ticks(int numberTicks){
-				int i;
-				for(i = 0; i < numberTicks; i++){
+			«val PlatformArchitecture platformArchitectureType = configModel.getPlatformArchitectureType()»
+			«IF platformArchitectureType!==null» #define __«platformArchitectureType.getName»__«ENDIF»
+			
+				void ticks(int numberTicks){
+			#	if defined (__x86_64__)
+				for(int i = 0; i < numberTicks; i++){
 					«FOR k : 1..400»
-						asm volatile("nop");
+					__asm volatile("nop");
 					«ENDFOR»
 				}
+			#	elif defined (__x86_32__) 
+			for(int i = 0; i < numberTicks; i++){
+					«FOR k : 1..400»
+					__asm volatile("mov r0, r0");
+					«ENDFOR»
+							}
+			#	elif defined (__aarch64__) 	
+			for(int i = 0; i < numberTicks; i++){
+					«FOR k : 1..400»
+					__asm volatile("mov x0, x0");
+					«ENDFOR»
+										}
+			#endif
 			}
 		'''
 
-	def static String snippetSrcBody(Runnable runnable, String codeString)
+	def static String snippetSrcBody(Runnable runnable, String codeString, boolean enableExtCode)
 		'''
 			//Runnable «runnable?.name»
 			void run_«runnable?.name»(char* coreName){
@@ -63,43 +79,56 @@
 	/**
 	 * This method is used to insert Synthetic code by considering the label-access's, Ticks (default and the PU specific i.e. extended ones)
 	 */
-	static def String syntheticLoad(Runnable runnable, boolean experimental, Properties properties) {
+	static def String syntheticLoad(Runnable runnable, boolean experimental, Properties properties, boolean enableExtCode ) {
 
-		val calc = new Calculation()
-
-		updateContent(runnable, calc,properties)
-
+		val calc=new Calculation();
+		
+		val StringBuffer codeHookFunctionsBuffer = new StringBuffer // custom property
+		val StringBuffer codeHookFunctionsOverwriteBuffer = new StringBuffer // custom property with overwrite
+		updateContent(runnable, calc, properties, codeHookFunctionsBuffer, codeHookFunctionsOverwriteBuffer)
 
 		val buffer = '''
+			«IF enableExtCode»
+				«IF codeHookFunctionsOverwriteBuffer.length() == 0»
+					
+						«codeHookFunctionsBuffer»
+				«ELSE»
+					
+						«codeHookFunctionsOverwriteBuffer»
+				«ENDIF»
+			«ENDIF»
+			«IF !enableExtCode || codeHookFunctionsOverwriteBuffer.length() == 0»    «««	// write the runnable's code either when there is no external code or when the codehook is not of the overwrite type.
 			«var extendedFound=false»
-			«FOR puName : calc.ticksSumMap.keySet.sort» 
-				«IF !puName.equals("default")»
-					«IF extendedFound »else«ENDIF» if(strcmp(coreName,"«puName»")==0){
-						«syntheticLoadContentForEachPU( experimental, calc,puName)»
-					}
-					«{extendedFound=true;""}»
-				«ENDIF»
-			«ENDFOR»		
-			«IF calc.ticksSumMap.containsKey("default")»
-				
-				«val value=syntheticLoadContentForEachPU( experimental, calc,"default" )»
-				«IF value!==null && value.length>0»
-					«IF extendedFound »else«ENDIF»
-					 {
-					 	«value»
-					 }
-					 
-				«ENDIF»
+					«FOR puName : calc.ticksSumMap.keySet.sort» 
+						«IF !puName.equals("default")»
+							«IF extendedFound »else«ENDIF» if(strcmp(coreName,"«puName»")==0){
+								«syntheticLoadContentForEachPU( experimental, calc,puName)»
+							}
+							«{extendedFound=true;""}»
+						«ENDIF»
+					«ENDFOR»		
+					«IF calc.ticksSumMap.containsKey("default")»
+						
+						«val value=syntheticLoadContentForEachPU( experimental, calc,"default" )»
+						«IF value!==null && value.length>0»
+							«IF extendedFound »else«ENDIF»
+							 {
+							 	«value»
+							 }
+							 
+						«ENDIF»
+					«ENDIF»
 				«ENDIF»
 		'''
 		return buffer
 
 	}
 	
-	def static updateContent(Runnable runnable, Calculation calculation, Properties properties) {
+	def static updateContent(Runnable runnable, Calculation calculation, Properties properties, StringBuffer codehookFct, StringBuffer codehookFctOverwrite) {
+	
 		calculation.ticksSumMap.put("default", 0)
 
-		runnable?.activityGraph?.items?.forEach [ item |
+		runnable?.activityGraph?.eContents?.forEach [ item |
 
 			
 			if (item instanceof Ticks) {
@@ -147,6 +176,32 @@
 
 				}
 			}
+			else if (item instanceof CustomPropertyImpl)  // custom property
+			{
+				if (item.getKey.equals("codehook_overwrite")){
+					
+					val value = item.getValue
+					if(value instanceof StringObject){
+						codehookFctOverwrite.append((value.value)+ ";")
+						codehookFctOverwrite.append(System.getProperty("line.separator"))
+						codehookFctOverwrite.append(System.getProperty("line.separator"))
+					}
+					// println(item.value)
+				}
+				
+				else if (item.getKey.equals("codehook")){
+					
+					val value = item.getValue
+					if(value instanceof StringObject){
+						codehookFct.append((value.value)+ ";")
+						codehookFct.append(System.getProperty("line.separator"))
+						codehookFct.append(System.getProperty("line.separator"))
+						
+					}
+					// println(item.value)
+				}
+
+			}
 		]
 	}
 
diff --git a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/generators/LinuxStimulusGenerator.xtend b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/generators/LinuxStimulusGenerator.xtend
index 2428828..538dd27 100644
--- a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/generators/LinuxStimulusGenerator.xtend
+++ b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/generators/LinuxStimulusGenerator.xtend
@@ -39,9 +39,7 @@
 			«IF stimulus instanceof PeriodicStimulus»
 				void *«stimulus.name»Entry(){
 				«FOR task : stimulus.affectedProcesses»
-					«IF enableInstrumentation»instrument_start_measurement(counter);«ENDIF»
-						«task.name»();
-					«IF enableInstrumentation»instrument_stop_measurement(counter); counter++;«ENDIF»
+					«task.name»();
 				«ENDFOR»
 				}
 			«ENDIF»
@@ -70,6 +68,11 @@
 					«IF stimulus instanceof PeriodicStimulus»
 						pthread_t «stimulus.name»_;
 						pthread_create(&«stimulus.name»_, NULL, «stimulus.name»Loop, NULL);
+								«FOR task : stimulus.affectedProcesses»
+									«IF enableInstrumentation»instrument_start_measurement(counter);«ENDIF»
+										«task.name»();
+									«IF enableInstrumentation»instrument_stop_measurement(counter); counter++;«ENDIF»
+								«ENDFOR»
 					«ENDIF»
 				«ENDFOR»
 				«IF lastStimulus !== null»pthread_join(«lastStimulus.name»_, NULL);«ENDIF»
diff --git a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/generators/LinuxTaskGenerator.xtend b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/generators/LinuxTaskGenerator.xtend
index a5f2afb..9c8385b 100644
--- a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/generators/LinuxTaskGenerator.xtend
+++ b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/generators/LinuxTaskGenerator.xtend
@@ -21,12 +21,13 @@
 import org.eclipse.app4mc.amalthea.model.Task
 
 class LinuxTaskGenerator {
-
+	
 	// Suppress default constructor
 	private new() {
 		throw new IllegalStateException("Utility class");
 	}
-
+	
+	
 	static def void handleInterProcessTrigger(List<String> statements, List<Process> processedTasks,
 		Stimulus stimulus) {
 		statements.add("//interprocess trigger");
@@ -57,13 +58,19 @@
 	static def String snippetIncStart() '''
 		#include "runnables.h"
 	'''
-
-	static def String snippetSrcStart() '''
+	static def String snippetSrcStart(boolean enableInstrumentation_R) '''
 		#include "tasks.h"
 		#include <pthread.h>
-	'''
-
+		«IF enableInstrumentation_R»
+		#include "instrument.h"
+		
+		int counter1=0;
+		«ENDIF»
+		
+		'''
+	
 	static def String toH(Task task) '''
+	
 		void «task.name»();
 		void *«task.name»_entry();
 	'''
diff --git a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/LinuxModel2TextTransformer.java b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/LinuxModel2TextTransformer.java
index 8c7e90c..dd89084 100644
--- a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/LinuxModel2TextTransformer.java
+++ b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/LinuxModel2TextTransformer.java
@@ -52,10 +52,12 @@
 	@Override
 	public void transform(final Amalthea model, final String outputFolder) {
 
-		final boolean experimentalCodeSnippetMatching = 
-				Boolean.parseBoolean(getProperty("experimentalCodeSnippetMatching", "false"));
-		final boolean enableInstrumentation = 
-				Boolean.parseBoolean(getProperty("enableInstrumentation", "false"));
+		final boolean experimentalCodeSnippetMatching = Boolean
+				.parseBoolean(getProperty("experimentalCodeSnippetMatching"));
+		final boolean enableInstrumentation = Boolean
+				.parseBoolean(getProperty("enableInstrumentation_Tasks"));
+		final boolean enableInstrumentation_R = Boolean
+				.parseBoolean(getProperty("enableInstrumentation_Runnables"));
 
 		final StimuliModel stimuliModel = ModelUtil.getOrCreateStimuliModel(model);
 		final SWModel swModel = ModelUtil.getOrCreateSwModel(model);
@@ -85,6 +87,9 @@
 		if (enableInstrumentation) {
 			instrumentationTransformer.transform("synthetic_gen/instrument");
 		}
+		if (enableInstrumentation_R) {
+			instrumentationTransformer.transform("synthetic_gen/tasks/_src/instrument");
+		}
 
 		linuxMakeTransformer.transform();
 
diff --git a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/stimuli/LinuxStimulusTransformer.java b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/stimuli/LinuxStimulusTransformer.java
index dfd1b23..f5abad4 100644
--- a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/stimuli/LinuxStimulusTransformer.java
+++ b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/stimuli/LinuxStimulusTransformer.java
@@ -90,7 +90,7 @@
 
 	private void genFiles(SLGTranslationUnit tu, final List<Stimulus> stimuli) {
 		Stimulus lastStimulus = stimuli.get(stimuli.size() - 1);
-		boolean enableInstrumentation = Boolean.parseBoolean(properties.getProperty("enableInstrumentation"));
+		boolean enableInstrumentation = Boolean.parseBoolean(properties.getProperty("enableInstrumentation_Tasks"));
 
 		srcAppend(tu, LinuxStimulusGenerator.toSrc(stimuli, lastStimulus, enableInstrumentation));
 	}
diff --git a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/sw/LinuxMakeTransformer.java b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/sw/LinuxMakeTransformer.java
index 7cc1276..929bb75 100644
--- a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/sw/LinuxMakeTransformer.java
+++ b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/sw/LinuxMakeTransformer.java
@@ -15,6 +15,8 @@
 
 import java.util.Properties;
 
+import org.eclipse.app4mc.slg.commons.m2t.CustomObjectsStore;
+import org.eclipse.app4mc.slg.config.ConfigModel;
 import org.eclipse.app4mc.slg.linux.generators.LinuxMakeGenerator;
 import org.eclipse.app4mc.slg.linux.transformers.LinuxBaseTransformer;
 import org.eclipse.app4mc.transformation.util.OutputBuffer;
@@ -25,16 +27,25 @@
 
 	@Inject private OutputBuffer outputBuffer;
 	@Inject private Properties properties;
-
+	@Inject private CustomObjectsStore customObjsStore;
+	
 	public void transform() {
 
 		final boolean experimentalCodeMatching = Boolean
 				.parseBoolean(this.properties.getProperty("experimentalCodeSnippetMatching", "false"));
 		final boolean instrumentation = Boolean
-				.parseBoolean(this.properties.getProperty("enableInstrumentation", "false"));
+				.parseBoolean(this.properties.getProperty("enableInstrumentation_Tasks", "false"));
+		final boolean instrumentation_R = Boolean
+				.parseBoolean(this.properties.getProperty("enableInstrumentation_Runnables", "false"));
+		
+		final boolean externalCode = Boolean
+				.parseBoolean(this.properties.getProperty("enableExternalCode", "false"));
 
+		final ConfigModel configModel = customObjsStore.<ConfigModel>getInstance(ConfigModel.class);
+		
+		
 		this.outputBuffer.appendTo("OTHER", "Makefile",
-				LinuxMakeGenerator.getContent(experimentalCodeMatching, instrumentation));
+				LinuxMakeGenerator.getContent(experimentalCodeMatching, instrumentation,instrumentation_R,externalCode, configModel));
 	}
 
 }
diff --git a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/sw/LinuxRunnableTransformer.java b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/sw/LinuxRunnableTransformer.java
index 5f6c631..9759245 100644
--- a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/sw/LinuxRunnableTransformer.java
+++ b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/sw/LinuxRunnableTransformer.java
@@ -13,6 +13,7 @@
 
 package org.eclipse.app4mc.slg.linux.transformers.sw;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -31,7 +32,11 @@
 import org.eclipse.app4mc.amalthea.model.Runnable;
 import org.eclipse.app4mc.amalthea.model.SingleValueStatistic;
 import org.eclipse.app4mc.amalthea.model.Ticks;
+import org.eclipse.app4mc.slg.commons.m2t.CustomObjectsStore;
 import org.eclipse.app4mc.slg.commons.m2t.transformers.SLGTranslationUnit;
+import org.eclipse.app4mc.slg.config.CodehookType;
+import org.eclipse.app4mc.slg.config.ConfigModel;
+import org.eclipse.app4mc.slg.config.util.ConfigModelUtils;
 import org.eclipse.app4mc.slg.linux.generators.LinuxRunnableGenerator;
 import org.eclipse.app4mc.slg.linux.generators.LinuxRunnableGenerator.Calculation;
 import org.eclipse.app4mc.slg.linux.transformers.LinuxBaseTransformer;
@@ -43,10 +48,31 @@
 public class LinuxRunnableTransformer extends LinuxBaseTransformer {
 
 	@Inject private Properties properties;
+	@Inject private CustomObjectsStore customObjsStore;
+
 
 	// ---------- generic part "def create new transform(...)" ----------
+	
+    // ---------------------------------------------testing fetchig names
 
+	/*	final ConfigModel configModel = customObjsStore.<ConfigModel>getInstance(ConfigModel.class);
+	
+	public static void listFilesInFolder(final File folder) {
+	    for (final File fileEntry : folder.listFiles()) {
+	        if (fileEntry.isDirectory()) {
+	            listFilesInFolder(fileEntry);
+	        } else {
+	            System.out.println(fileEntry.getName());
+	        }
+	    }
+	}	
+*/
+	
+	// ------------------------------------------------testing fetchig names
+	
 	private final Map<List<Object>, SLGTranslationUnit> transformCache = new HashMap<>();
+	
+
 
 	@Override
 	public Map<List<Object>, SLGTranslationUnit> getCache() {
@@ -91,11 +117,31 @@
 	}
 
 	private void genFiles(SLGTranslationUnit tu, final Runnable runnable) {
+		final ConfigModel configModel = customObjsStore.<ConfigModel>getInstance(ConfigModel.class);
+		
 		if (isIncFileEmpty(tu)) {
+			
+			//----------------------------------/* fetch headers names*/--------------------------------------
+			// to fetch the headers names we use the getHeaderFilesDirectories function and we go through every directory with the for loop
+			
+			boolean enableExtCode = Boolean.parseBoolean(properties.getProperty("enableExternalCode"));
+			if(enableExtCode)    //  input property to test if we need to include the external code headerfiles
+			{
+			    for (String hDir : ConfigModelUtils.getHeaderFilesDirectories(configModel,CodehookType.RUNNABLE)) 
+			    {
+				final File folder = new File(hDir.trim());                          // fetching all the names in the headerfile directory.
+				String names = ConfigModelUtils.getHeaderFilesIncludeMultiString(folder,new StringBuffer());
+				incAppend(tu,names); 
+	            } 
+			}
+			//------------------------------------------------------------------------
+			
 			incAppend(tu, LinuxRunnableGenerator.snippetIncStart());
+			
+			
 		}
 		if (isSrcFileEmpty(tu)) {
-			srcAppend(tu, LinuxRunnableGenerator.snippetSrcStart());
+			srcAppend(tu, LinuxRunnableGenerator.snippetSrcStart(configModel));
 		}
 
 		// write header
@@ -153,9 +199,10 @@
 		}
 
 		boolean useExperimental = Boolean.parseBoolean(properties.getProperty("experimentalCodeSnippetMatching"));
-
-		String codeString = LinuxRunnableGenerator.syntheticLoad(runnable,useExperimental,properties);
-		srcAppend(tu, LinuxRunnableGenerator.snippetSrcBody(runnable, codeString));
+		boolean enableExtCode = Boolean.parseBoolean(properties.getProperty("enableExternalCode"));
+		
+		String codeString = LinuxRunnableGenerator.syntheticLoad(runnable,useExperimental,properties,enableExtCode);
+		srcAppend(tu, LinuxRunnableGenerator.snippetSrcBody(runnable, codeString, enableExtCode ));
 	}
 
 }
diff --git a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/sw/LinuxTaskTransformer.java b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/sw/LinuxTaskTransformer.java
index ef5cd55..d8e4263 100644
--- a/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/sw/LinuxTaskTransformer.java
+++ b/load_generator/linux/plugins/org.eclipse.app4mc.slg.linux/src/org/eclipse/app4mc/slg/linux/transformers/sw/LinuxTaskTransformer.java
@@ -13,11 +13,13 @@
 
 package org.eclipse.app4mc.slg.linux.transformers.sw;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 import java.util.Set;
 
 import org.eclipse.app4mc.amalthea.model.ActivityGraphItem;
@@ -31,17 +33,27 @@
 import org.eclipse.app4mc.amalthea.model.ProcessingUnitDefinition;
 import org.eclipse.app4mc.amalthea.model.Runnable;
 import org.eclipse.app4mc.amalthea.model.RunnableCall;
+import org.eclipse.app4mc.amalthea.model.StringObject;
 import org.eclipse.app4mc.amalthea.model.Task;
+import org.eclipse.app4mc.amalthea.model.Value;
+import org.eclipse.app4mc.amalthea.model.impl.CustomPropertyImpl;
 import org.eclipse.app4mc.amalthea.model.util.DeploymentUtil;
+import org.eclipse.app4mc.slg.commons.m2t.CustomObjectsStore;
 import org.eclipse.app4mc.slg.commons.m2t.transformers.SLGTranslationUnit;
+import org.eclipse.app4mc.slg.config.CodehookType;
+import org.eclipse.app4mc.slg.config.ConfigModel;
+import org.eclipse.app4mc.slg.config.util.ConfigModelUtils;
 import org.eclipse.app4mc.slg.linux.generators.LinuxTaskGenerator;
 import org.eclipse.app4mc.slg.linux.transformers.LinuxBaseTransformer;
+import org.eclipse.emf.ecore.EObject;
 
+import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
 @Singleton
 public class LinuxTaskTransformer extends LinuxBaseTransformer {
-
+	@Inject private Properties properties;
+	@Inject private CustomObjectsStore customObjsStore;
 	// ---------- generic part "def create new transform(...)" ----------
 
 	private final Map<List<Object>, SLGTranslationUnit> transformCache = new HashMap<>();
@@ -89,6 +101,12 @@
 	}
 
 	private void genFiles(SLGTranslationUnit tu, final Task task) {
+		
+		boolean enableInstrumentation_R = Boolean.parseBoolean(properties.getProperty("enableInstrumentation_Runnables")); // runnable instrumentation
+		boolean enableExtCode = Boolean.parseBoolean(properties.getProperty("enableExternalCode"));
+
+		boolean extOverwrite = false; // enabling codehook overwriting
+		
 		final Amalthea root = AmaltheaServices.getContainerOfType(task, Amalthea.class);
 		final Set<ProcessingUnit> assignedCores = DeploymentUtil.getAssignedCoreForProcess(task, root);
 
@@ -106,15 +124,49 @@
 
 		final List<String> statements = new ArrayList<>();
 		final List<Process> processedTasks = new ArrayList<>();
+		final List<String> statementsOverwrite = new ArrayList<>();
 
 		if (task != null && task.getActivityGraph() != null) {
-			for (ActivityGraphItem item : task.getActivityGraph().getItems()) {
+			for (final EObject item : task.getActivityGraph().eContents()) {
+				
+				if (item  instanceof CustomPropertyImpl)  // custom property: 
+				{
+					if (enableExtCode) {
+						if (((CustomPropertyImpl) item).getKey().equals("codehook")) {
+
+							Value value = ((CustomPropertyImpl) item).getValue();
+
+							if (value instanceof StringObject) {
+
+								statements.add(((StringObject) value).getValue() + ";");
+
+							}
+						} else if (((CustomPropertyImpl) item).getKey().equals("codehook_overwrite")) {
+							extOverwrite = true;
+							Value value1 = ((CustomPropertyImpl) item).getValue();
+
+							if (value1 instanceof StringObject) {
+
+								statementsOverwrite.add(((StringObject) value1).getValue());
+							}
+						}
+
+					}
+				}
 
 				if (item instanceof Group) {
 					for (ActivityGraphItem item2 : ((Group) item).getItems()) {
+						
 						if ((item2 instanceof RunnableCall)) {
 							final Runnable runnable = ((RunnableCall) item2).getRunnable();
-							statements.add("run_" + runnable.getName() + "(\"" + puDefinition.toString() + "\");");
+							if(enableInstrumentation_R) {
+								statements.add("instrument_start_measurement(counter1);");
+								statements.add("run_" + runnable.getName() + "(\"" + puDefinition.toString() + "\");");
+								statements.add("instrument_stop_measurement(counter1); counter1++;");
+								}
+							else {
+								statements.add("run_" + runnable.getName() + "(\"" + puDefinition.toString() + "\");");
+							}
 						} else if ((item2 instanceof InterProcessTrigger)) {
 							InterProcessStimulus stimulus = ((InterProcessTrigger) item2).getStimulus();
 							LinuxTaskGenerator.handleInterProcessTrigger(statements, processedTasks, stimulus);
@@ -123,7 +175,15 @@
 				} else if (item instanceof RunnableCall) {
 					final Runnable runnable = ((RunnableCall) item).getRunnable();
 					if ((runnable != null)) {
-						statements.add("run_" + runnable.getName() + "(\"" + puDefinition.toString() + "\");");
+
+						if(enableInstrumentation_R) {
+							statements.add("instrument_start_measurement(counter1);");
+							statements.add("run_" + runnable.getName() + "(\"" + puDefinition.toString() + "\");");
+							statements.add("instrument_stop_measurement(counter1); counter1++;");
+							}
+						else {
+							statements.add("run_" + runnable.getName() + "(\"" + puDefinition.toString() + "\");");
+						}
 					}
 				} else if (item instanceof InterProcessTrigger) {
 					InterProcessStimulus stimulus = ((InterProcessTrigger) item).getStimulus();
@@ -133,12 +193,47 @@
 		}
 
 		if (isIncFileEmpty(tu)) {
+			//----------------------------------/* fetch headers names*/--------------------------------------
+			// to fetch the headers names we use the getHeaderFilesDirectories function and we go through every directory with the for loop
+			final ConfigModel configModel = customObjsStore.<ConfigModel>getInstance(ConfigModel.class);
+			
+			if(enableExtCode )    //  input property to test if we need to include the external code headerfiles
+			{
+			    for (String hDir : ConfigModelUtils.getHeaderFilesDirectories(configModel,CodehookType.TASK)) 
+			    {
+				final File folder = new File(hDir.trim());                          // fetching all the names in the headerfile directory.
+				String names = ConfigModelUtils.getHeaderFilesIncludeMultiString(folder,new StringBuffer());
+				incAppend(tu,names); 
+	            } 
+			}
+			//------------------------------------------------------------------------
+			
 			incAppend(tu, LinuxTaskGenerator.snippetIncStart());
+			
 		}
 		if (isSrcFileEmpty(tu)) {
-			srcAppend(tu, LinuxTaskGenerator.snippetSrcStart());
+			srcAppend(tu, LinuxTaskGenerator.snippetSrcStart(enableInstrumentation_R));
 		}
-		srcAppend(tu, LinuxTaskGenerator.toCpp(task, statements));
+		
+		//------------------------  write body with overwrite codehook  function 
+		
+		if (extOverwrite) {
+			//This code is 
+			String statement_overwrite = "void " + task.getName() + "(){ \n\n";
+			srcAppend(tu, statement_overwrite);
+
+			for (String statement : statementsOverwrite) {
+				srcAppend(tu, statement + ";" + "\n");
+			}
+			srcAppend(tu, "\n" + "}" + "\n");
+
+			srcAppend(tu, "\n void *" + task.getName() + "_entry(){ \n \n");
+			srcAppend(tu, task.getName() + "(); \n");
+			srcAppend(tu, "\n" + "}" + "\n");
+
+		} else {
+			srcAppend(tu, LinuxTaskGenerator.toCpp(task, statements));
+		}
 		incAppend(tu, LinuxTaskGenerator.toH(task));
 	}
 
diff --git a/load_generator/linux/releng/org.eclipse.app4mc.slg.linux.product/input.properties b/load_generator/linux/releng/org.eclipse.app4mc.slg.linux.product/input.properties
index ca472ee..8344c4f 100644
--- a/load_generator/linux/releng/org.eclipse.app4mc.slg.linux.product/input.properties
+++ b/load_generator/linux/releng/org.eclipse.app4mc.slg.linux.product/input.properties
@@ -9,10 +9,12 @@
 #  	 Robert Bosch GmbH - initial API and implementation
 # 
 # *******************************************************************************
-input_models_folder=./input
-configurationFile=./input/linux.config
+input_models_folder=./input_test
+configurationFile=./input_test/linux.config
 output_folder=./output
+log_file=./output/transformation.txt
 experimentalCodeSnippetMatching=false
-enableInstrumentation=false
-
-m2tTransformers=LINUX_SLG
\ No newline at end of file
+enableInstrumentation_Tasks=false
+enableInstrumentation_Runnables=false
+enableExternalCode=true
+m2tTransformers=LINUX_SLG
diff --git a/load_generator/linux/releng/org.eclipse.app4mc.slg.linux.product/input_test/linux.config b/load_generator/linux/releng/org.eclipse.app4mc.slg.linux.product/input_test/linux.config
index fec7e66..e0e5dff 100644
--- a/load_generator/linux/releng/org.eclipse.app4mc.slg.linux.product/input_test/linux.config
+++ b/load_generator/linux/releng/org.eclipse.app4mc.slg.linux.product/input_test/linux.config
@@ -1,6 +1,15 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<config:ConfigModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:config="http://config" >
-    <customTickImpl value=""/>
-  	<customReadImpl value=""/>
-  	<customWriteImpl value=""/>
-</config:ConfigModel>
\ No newline at end of file
+<config:ConfigModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:config="http://config">
+  <customTickImpl value=""/>
+  <customReadImpl value=""/>
+  <customWriteImpl value=""/>
+  <codeHooks>
+    <libLocations>
+      <linkedLibraries>-fopenmp</linkedLibraries>
+      <linkedLibraries>/home/firas/Codehook_Example1/CodeHooks/BIGLIB.a</linkedLibraries>
+    </libLocations>
+    <headerFiles>
+      <headerFilesDirectories>k:\Users\yof7rng\Desktop\temp\Headers</headerFilesDirectories>
+    </headerFiles>
+  </codeHooks>
+</config:ConfigModel>
diff --git a/load_generator/linux/releng/org.eclipse.app4mc.slg.linux.product/input_test/test.amxmi b/load_generator/linux/releng/org.eclipse.app4mc.slg.linux.product/input_test/test.amxmi
index 4be8767..1aa13da 100644
--- a/load_generator/linux/releng/org.eclipse.app4mc.slg.linux.product/input_test/test.amxmi
+++ b/load_generator/linux/releng/org.eclipse.app4mc.slg.linux.product/input_test/test.amxmi
@@ -1,8 +1,20 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<am:Amalthea xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:am="http://app4mc.eclipse.org/amalthea/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+<am:Amalthea xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:am="http://app4mc.eclipse.org/amalthea/1.1.0">
   <swModel>
     <tasks xmi:id="Task1?type=Task" name="Task1" stimuli="stepstimulus?type=PeriodicStimulus" preemption="preemptive" multipleTaskActivationLimit="0">
       <activityGraph>
+        <customProperties key="codehook">
+          <value xsi:type="am:StringObject" value="function1()"/>
+        </customProperties>
+        <customProperties key="codehook_overwrite">
+          <value xsi:type="am:StringObject" value="function1_overwrite()"/>
+        </customProperties>
+        <customProperties key="codehook">
+          <value xsi:type="am:StringObject" value="function2()"/>
+        </customProperties>
+        <customProperties key="codehook_overwrite">
+          <value xsi:type="am:StringObject" value="function2_overwrite()"/>
+        </customProperties>
         <items xsi:type="am:ModeSwitch">
           <entries name="">
             <items xsi:type="am:RunnableCall" runnable="initialize?type=Runnable"/>
@@ -20,11 +32,15 @@
     </tasks>
     <tasks xmi:id="Task2?type=Task" name="Task2" stimuli="ips?type=InterProcessStimulus" multipleTaskActivationLimit="0">
       <activityGraph>
+        <customProperties key="codehook">
+          <value xsi:type="am:StringObject" value="function1()"/>
+        </customProperties>
         <items xsi:type="am:Ticks">
           <extended key="puDef?type=ProcessingUnitDefinition">
             <value xsi:type="am:DiscreteValueStatistics" lowerBound="0" upperBound="0" average="5000.0"/>
           </extended>
         </items>
+        <items xsi:type="am:RunnableCall" runnable="initialize?type=Runnable"/>
       </activityGraph>
     </tasks>
     <runnables xmi:id="initialize?type=Runnable" name="initialize" callback="false" service="false">