diff --git a/counters.h b/counters.h
index 15926127826cb8745e740cd315eef88617112835..751557ab5b308c0eda13c61f077d5bdff6519cd1 100644
--- a/counters.h
+++ b/counters.h
@@ -18,12 +18,9 @@
 
  *******************************************************/
 
-#include <linux/perf_event.h>
+unsigned int init_counters(char*, void **);
+unsigned int get_counters(uint64_t* results, void*);
+void clean_counters(void *);
+void label_counters(char **labels, void*);
 
-typedef struct _counter_t* counter_t;
-
-counter_t init_counters(const int nb_perf, const __u32 *types, const __u64 *names);
-void clean_counters(counter_t fd);
-void start_counters(counter_t fd);
-void reset_counters(counter_t fd);
-void get_counters(counter_t fd, uint64_t *values);
+void show_all_counters();
diff --git a/counters_individual.c b/counters_individual.c
index fac60290570139d5439b07b7cad9c31eac6bdf28..79533ff756fc5f5ec92780748757451ebea2d922 100644
--- a/counters_individual.c
+++ b/counters_individual.c
@@ -28,17 +28,58 @@
 #include <asm/unistd.h>
 #include <stdint.h>
 
-#include "counters.h"
-
 struct _counter_t {
   int nbcores;
   int nbperf;
   int **counters;
+  uint64_t *counters_values;
+  uint64_t *tmp_counters_values;
+
+  int* perf_indexes;
+  
 };
- 
-static long
-perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
-		int cpu, int group_fd, unsigned long flags) {
+typedef struct _counter_t* counter_t;
+
+#include "counters_option.h"
+
+void show_all_counters() {
+  for(int i=0; i<nb_counter_option;i++)
+    printf("%s\n", perf_static_info[i].name);
+  
+}
+
+void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb){
+  *perf_type = malloc(nb*sizeof(__u32));
+  *perf_key  = malloc(nb*sizeof(__u64));
+  for(int i=0; i<nb; i++) {
+    (*perf_key)[i]  = perf_static_info[indexes[i]].perf_key;
+    (*perf_type)[i] = perf_static_info[indexes[i]].perf_type;
+  }
+}
+void perf_event_list(char *perf_string, int *nb_perf, int **perf_indexes) {
+  char *token;
+  *nb_perf=0;
+  *perf_indexes=NULL;
+  while((token=strtok(perf_string, ",")) != NULL) {
+    perf_string = NULL;
+    int i;
+    for(i=0; i<nb_counter_option; i++) {
+      if(strcmp(perf_static_info[i].name, token) == 0) {
+	(*nb_perf)++;
+	(*perf_indexes) = realloc(*perf_indexes, sizeof(int)*(*nb_perf));
+	(*perf_indexes)[*nb_perf-1]=i;
+	break;
+      }
+    }
+    if(i == nb_counter_option) {
+      fprintf(stderr, "Unknown performance counter: %s\n", token);
+      exit(EXIT_FAILURE);
+    }
+  }
+}
+
+static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
+			    int cpu, int group_fd, unsigned long flags) {
   long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
   if (res == -1) {
     perror("perf_event_open");
@@ -48,7 +89,7 @@ perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
   return res;
 }
 
-counter_t init_counters(const int nb_perf, const __u32 *types, const __u64 *names) {
+counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *names) {
   struct perf_event_attr pe;
   unsigned int nbcores = sysconf(_SC_NPROCESSORS_ONLN);
   memset(&pe, 0, sizeof(struct perf_event_attr));
@@ -71,13 +112,18 @@ counter_t init_counters(const int nb_perf, const __u32 *types, const __u64 *name
   return counters;
 }
 
-void clean_counters(counter_t counters) {
+void clean_counters(void *ptr) {
+  counter_t counters = (counter_t) ptr;
   for(int counter=0; counter<counters->nbperf; counter++) {
     for(int core=0; core<counters->nbcores; core++)
       close(counters->counters[counter][core]);
     free(counters->counters[counter]);
   }
   free(counters->counters);
+  free(counters->counters_values);
+  free(counters->tmp_counters_values);
+  free(counters->perf_indexes);
+
   free(counters);
 }
 
@@ -86,25 +132,70 @@ void start_counters(counter_t counters) {
     for(int core=0; core<counters->nbcores; core++)
       ioctl(counters->counters[counter][core], PERF_EVENT_IOC_ENABLE, 0);
 }
+
 void reset_counters(counter_t counters) {
   for(int counter=0; counter<counters->nbperf; counter++)
     for(int core=0; core<counters->nbcores; core++)
       ioctl(counters->counters[counter][core], PERF_EVENT_IOC_RESET, 0);
 }
 
-void get_counters(counter_t counters, uint64_t *values) {
-  //memset(values, 0, nb_perf*sizeof(long long));
+void _get_counters(counter_t counters, uint64_t *values) {
   for(int i=0; i<counters->nbperf; i++) {
     uint64_t accu=0;
     uint64_t count=0;
     for (int core=0; core<counters->nbcores; core++) {
       if (-1 == read(counters->counters[i][core], &count, sizeof(uint64_t))) {
-	fprintf(stderr, "PB Lecture resultat");
+	fprintf(stderr, "Cannot read result");
 	exit(EXIT_FAILURE);
       }
       accu += count;
     }
     values[i] = accu;
   }
-  //reset_counters(counters);
+}
+
+
+
+
+
+
+unsigned int init_counters(char* args, void **state) {
+  int nb_perf;
+  int* perf_indexes=NULL;
+
+  perf_event_list(args, &nb_perf, &perf_indexes);
+
+  __u32* perf_type;
+  __u64* perf_key;
+  perf_type_key(&perf_type, &perf_key, perf_indexes, nb_perf);
+  counter_t fd = _init_counters(nb_perf, perf_type, perf_key);
+  free(perf_type);
+  free(perf_key);
+
+  fd->perf_indexes = perf_indexes;
+  fd->counters_values = malloc(nb_perf*sizeof(uint64_t));
+  fd->tmp_counters_values = malloc(nb_perf*sizeof(uint64_t));
+  start_counters(fd);
+  _get_counters(fd, fd->counters_values);
+  *state = (void*) fd;
+
+  return nb_perf;
+}
+
+unsigned int get_counters(uint64_t* results, void*ptr) {
+  counter_t state = (counter_t) ptr;
+
+_get_counters(state, state->tmp_counters_values);
+  for(int i=0; i<state->nbperf; i++)
+    results[i] = state->tmp_counters_values[i] - state->counters_values[i];
+
+  memcpy(state->counters_values, state->tmp_counters_values, state->nbperf * sizeof(uint64_t));
+  return state->nbperf;
+}
+
+void label_counters(char **labels, void*ptr) {
+  counter_t state = (counter_t) ptr;
+  for(int i=0; i<state->nbperf;i++)
+    labels[i] = perf_static_info[state->perf_indexes[i]].name;
+
 }
diff --git a/infiniband.c b/infiniband.c
index fb8928c4a6e68f6fce1badd09e4061d9f9c678a0..318a9e4f0a9f1b8051454bdd4c455b8a0b80e9ca 100644
--- a/infiniband.c
+++ b/infiniband.c
@@ -66,21 +66,3 @@ unsigned int init_infiniband(char* infi_path, void**ptr) {
 
   return 4;
 }
-
-/* void get_network(long long* results, char** sources) { */
-/*   if(sources==NULL) */
-/*     return; */
-/*   for(int i=0; i<4; i++){ */
-/*     FILE* f = fopen(sources[i], "rb"); */
-/*     fscanf(f, "%lld", &results[i]); */
-/*     fclose(f); */
-/*   } */
-/* } */
-
-/* void clean_network(char **sources) { */
-/*   if(sources==NULL) */
-/*     return; */
-/*   for(int i=0;i<4;i++) */
-/*     free(sources[i]); */
-/*   free(sources); */
-/* }     */
diff --git a/mojitos.c b/mojitos.c
index a10cd47c009e2a4c7166b3ee7100dc37f3ddd44f..b72e2b72db770f25b4e47189ed924a66423fccb2 100644
--- a/mojitos.c
+++ b/mojitos.c
@@ -20,12 +20,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-#include <asm/unistd.h>
-#include <sys/stat.h>
-#include <fcntl.h>
 #include <time.h>
-#include <string.h>
-#include <getopt.h>
 #include <signal.h>
 #include <inttypes.h>
 #include <unistd.h>
@@ -36,53 +31,9 @@
 #include "infiniband.h"
 #include "load.h"
 
-#include "counters_option.h"
 
-void show_all_counters() {
-  for(int i=0; i<nb_counter_option;i++)
-    printf("%s\n", perf_static_info[i].name);
-  
-}
 
 
-int nb_perf = 5;
-int* perf_indexes=NULL;
-// const char* perf_names[5] = {"instructions", "cachemisses", "pagefaults", "branchmisses", "cachmiss"};
-// const __u32 perf_type[5] = {PERF_TYPE_HARDWARE,PERF_TYPE_HARDWARE,PERF_TYPE_SOFTWARE, PERF_TYPE_HARDWARE, PERF_TYPE_HW_CACHE};
-// const __u64 perf_key[5] = {PERF_COUNT_HW_INSTRUCTIONS, PERF_COUNT_HW_CACHE_MISSES,
-//			   PERF_COUNT_SW_PAGE_FAULTS,PERF_COUNT_HW_BRANCH_MISSES,
-//			   PERF_COUNT_HW_CACHE_LL};
-
-void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb){
-  *perf_type = malloc(nb*sizeof(__u32));
-  *perf_key  = malloc(nb*sizeof(__u64));
-  for(int i=0; i<nb; i++) {
-    (*perf_key)[i]  = perf_static_info[indexes[i]].perf_key;
-    (*perf_type)[i] = perf_static_info[indexes[i]].perf_type;
-  }
-}
-void perf_event_list(char *perf_string, int *nb_perf, int **perf_indexes) {
-  char *token;
-  *nb_perf=0;
-  *perf_indexes=NULL;
-  while((token=strtok(perf_string, ",")) != NULL) {
-    perf_string = NULL;
-    int i;
-    for(i=0; i<nb_counter_option; i++) {
-      if(strcmp(perf_static_info[i].name, token) == 0) {
-	(*nb_perf)++;
-	(*perf_indexes) = realloc(*perf_indexes, sizeof(int)*(*nb_perf));
-	(*perf_indexes)[*nb_perf-1]=i;
-	break;
-      }
-    }
-    if(i == nb_counter_option) {
-      fprintf(stderr, "Unknown performance counter: %s\n", token);
-      exit(EXIT_FAILURE);
-    }
-  }
-}
-
 void usage(char** argv) {
   printf("Usage : %s [-t time] [-f freq] [-r] [-p perf_list] [-l] [-u] [-c] [-d network_device] [-i infiniband_path] [-o logfile] [-e command arguments...]\n", argv[0]);
   printf("if time==0 then loops infinitively\n");
@@ -149,7 +100,6 @@ int main(int argc, char **argv) {
   int frequency=1;
   char **application = NULL;
 
-  int perf_mode = -1;
   int stat_mode = -1;
 
   if(argc==1)
@@ -188,8 +138,7 @@ int main(int argc, char **argv) {
       signal(17,sighandler);
       break;
     case 'p':
-      perf_event_list(argv[optind], &nb_perf, &perf_indexes);
-      perf_mode=0;
+      add_source(init_counters, argv[optind], label_counters, get_counters, clean_counters);
       break;
     case 'r':
       add_source(init_rapl, NULL, label_rapl, get_rapl, clean_rapl);
@@ -207,28 +156,10 @@ int main(int argc, char **argv) {
       usage(argv);
     }
   
-  // Hardware Performance Counters initialization
-  __u32* perf_type;
-  __u64* perf_key;
-  counter_t fd=0;
-  uint64_t *counter_values=NULL;
-  uint64_t *tmp_counter_values=NULL;
-  if(perf_mode==0) {
-    perf_type_key(&perf_type, &perf_key, perf_indexes, nb_perf);
-    fd = init_counters(nb_perf, perf_type, perf_key);
-
-    counter_values = malloc(nb_perf*sizeof(uint64_t));
-    tmp_counter_values = malloc(nb_perf*sizeof(uint64_t));
-
-    get_counters(fd, counter_values);
-  }
   struct timespec ts;
   struct timespec ts_ref;
 
   fprintf(output, "#timestamp ");
-  if(perf_mode==0)
-    for(int i=0; i<nb_perf;i++)
-      fprintf(output, "%s ", perf_static_info[perf_indexes[i]].name);
 
   for(int i=0; i<nb_sensors; i++)
     fprintf(output, "%s ", labels[i]);
@@ -239,16 +170,11 @@ int main(int argc, char **argv) {
   fprintf(output, "\n");
 
   unsigned long int stat_data=0;
-  if(perf_mode==0)
-    start_counters(fd);
 
   for (int temps = 0; temps <total_time*frequency; temps+=delta) {
     clock_gettime(CLOCK_MONOTONIC, &ts_ref);
 
     // Get Data
-    if(perf_mode==0)
-      get_counters(fd, tmp_counter_values);
-    
     unsigned int current = 0;
     for(int i=0; i<nb_sources; i++)
       current += getter[i](&values[current], states[i]);
@@ -284,9 +210,6 @@ int main(int argc, char **argv) {
       // Treat Data
       fprintf(output, "%ld.%09ld ", ts_ref.tv_sec, ts_ref.tv_nsec);
     }
-    if(perf_mode==0)
-      for(int i=0; i<nb_perf;i++) 
-	fprintf(output, "%" PRIu64 " ", tmp_counter_values[i]-counter_values[i]);
     
     for(int i=0; i<nb_sensors; i++)
       fprintf(output, "%" PRIu64 " ", values[i]);
@@ -298,8 +221,6 @@ int main(int argc, char **argv) {
 
     if(application != NULL)
       break;
-    if(perf_mode==0)
-      memcpy(counter_values, tmp_counter_values, nb_perf*sizeof(uint64_t));
 
     clock_gettime(CLOCK_MONOTONIC, &ts);
     usleep(1000*1000/frequency-(ts.tv_nsec/1000)%(1000*1000/frequency));
@@ -308,14 +229,6 @@ int main(int argc, char **argv) {
   for(int i=0; i<nb_sources;i++)
     cleaner[i](states[i]);
 
-  if(perf_mode==0){
-    clean_counters(fd);
-    free(counter_values);
-    free(tmp_counter_values);
-    free(perf_type);
-    free(perf_key);
-    free(perf_indexes);
-  }
   if(nb_sources > 0) {
     free(getter);
     free(cleaner);