User Tools

Site Tools


realtime:documentation:howto:applications:memory:mlockall_stack_sample

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
realtime:documentation:howto:applications:memory:mlockall_stack_sample [2017/06/01 01:30]
jithu created
realtime:documentation:howto:applications:memory:mlockall_stack_sample [2017/06/10 00:41]
jithu
Line 4: Line 4:
  
 <code c> <code c>
-/*  +/* 
-   ​gcc -o check_stack_page_faults check_stack_page_faults.c -Wall -O3 -lpthread + gcc -o check_stack_page_faults check_stack_page_faults.c -Wall -O3 -lpthread 
-   ​This application checks whether mlockall() forces all pages of a + This application checks whether mlockall() forces all pages of a 
-   ​stack into RAM. + stack into RAM. 
-*/ + */ 
-#include <​stdio.h>​ + 
-#include <string.h>+#include <limits.h>
 #include <​pthread.h>​ #include <​pthread.h>​
-#include <​semaphore.h>​ 
 #include <​sched.h>​ #include <​sched.h>​
-#include <unistd.h>+#include <semaphore.h>​ 
 +#include <​stdio.h>​ 
 +#include <​stdlib.h>​ 
 +#include <string.h>
 #include <​sys/​mman.h>​ #include <​sys/​mman.h>​
 #include <​sys/​resource.h>​ #include <​sys/​resource.h>​
-#include <limits.h>+#include <unistd.h>
  
 /* struct thread_data communicates data to our threads */ /* struct thread_data communicates data to our threads */
Line 31: Line 33:
  if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {  if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
  perror("​mlockall() failed"​);​  perror("​mlockall() failed"​);​
 + exit(-1);
  }  }
 } }
Line 37: Line 40:
 static int dump_page_faults(void) static int dump_page_faults(void)
 { {
 + int new_minor_page_faults,​ new_major_page_faults;​
  int page_faults_detected = 0;  int page_faults_detected = 0;
- static int init = 0; 
  static struct rusage rusage_prev;​  static struct rusage rusage_prev;​
  struct rusage rusage;​  struct rusage rusage;​
- int  new_minor_page_faults,​ new_major_page_faults;+ static ​int init;
  
  getrusage(RUSAGE_SELF,​ &​rusage);​  getrusage(RUSAGE_SELF,​ &​rusage);​
Line 50: Line 53:
  
  if (init) {  if (init) {
- if ((new_minor_page_faults > 0) || + if ((new_minor_page_faults > 0) ||
      (new_major_page_faults > 0)) {      (new_major_page_faults > 0)) {
  printf("​New minor/major page faults: %d/​%d\n",​  printf("​New minor/major page faults: %d/​%d\n",​
Line 63: Line 66:
 /* Start a thread */ /* Start a thread */
 static pthread_t startThread(int prio, int stack_size, static pthread_t startThread(int prio, int stack_size,
-      void *(*thread_run) (void *), void *args)+      void *(*thread_run)(void *), void *args)
 { {
 + int min_stack_size = 16384;
 + struct sched_param sched;
  const char *failure;  const char *failure;
  pthread_attr_t attr;  pthread_attr_t attr;
- pthread_t tid; 
- struct sched_param sched; 
- int policy; 
  int priority_min;​  int priority_min;​
  int priority_max;​  int priority_max;​
- int min_stack_size = 16384;+ pthread_t tid; 
 + int policy;
  
  for (;;) {  for (;;) {
- if ((policy = sched_getscheduler(0)== -1) {+ policy = sched_getscheduler(0)
 + if (policy ​== -1) {
  failure = "​sched_getscheduler";​  failure = "​sched_getscheduler";​
  break;  break;
  }  }
  
- if ((priority_min = sched_get_priority_min(policy)== -1) {+ priority_min = sched_get_priority_min(policy)
 + if (priority_min ​== -1) {
  failure = "​sched_get_priority_min";​  failure = "​sched_get_priority_min";​
  break;  break;
Line 88: Line 93:
  prio = priority_min;​  prio = priority_min;​
  
- if ((priority_max = sched_get_priority_max(policy)== -1) {+ priority_max = sched_get_priority_max(policy)
 + if (priority_max ​== -1) {
  failure = "​sched_get_priority_max";​  failure = "​sched_get_priority_max";​
  break;  break;
Line 156: Line 162:
  }  }
  
- return ​tid;+ printf("​FAILURE while %s in startThread\n",​ failure); 
 + return ​-1;
 } }
  
Line 175: Line 182:
  { /* Limit the scope */  { /* Limit the scope */
  char stack_filler[pthread_data->​stack_filler_size];​  char stack_filler[pthread_data->​stack_filler_size];​
- +
  printf("​%s performing checks\n",​ pthread_data->​name);​  printf("​%s performing checks\n",​ pthread_data->​name);​
- for (i = 0; + for (i = 0;
       i < (int)pthread_data->​stack_filler_size;​       i < (int)pthread_data->​stack_filler_size;​
       i += sysconf(_SC_PAGESIZE)) {       i += sysconf(_SC_PAGESIZE)) {
  stack_filler[i] = 42;  stack_filler[i] = 42;
  }  }
- printf("​%s done\n",​ pthread_data->​name);​+ /* dummy read of stack_filler[52] to prevent unused warning */ 
 + printf("​%s done %d\n", pthread_data->​name, stack_filler[52]);
  }  }
  
Line 194: Line 202:
 int main(int argc, char *argv[]) int main(int argc, char *argv[])
 { {
- int lock_memory = 1; + const int page_size = sysconf(_SC_PAGESIZE);​
- int i; +
- const int  page_size = sysconf(_SC_PAGESIZE);​+
  int page_faults_detected_in_thread1;​  int page_faults_detected_in_thread1;​
  int page_faults_detected_in_thread2;​  int page_faults_detected_in_thread2;​
- /* Thread data */+ int lock_memory = 1; 
 + struct thread_data thread_data[2];​
  pthread_t thread_ids[2];​  pthread_t thread_ids[2];​
- struct thread_data thread_data[2];+ int i;
  
  /* Start a thread prior to locking memory. */  /* Start a thread prior to locking memory. */
Line 209: Line 216:
  thread_ids[0] = startThread(0,​ stack_size, check_stack_thread,​  thread_ids[0] = startThread(0,​ stack_size, check_stack_thread,​
  (void *)&​thread_data[0]);​  (void *)&​thread_data[0]);​
 + if (thread_ids[0] == -1) {
 + printf("​Exiting - Unexpected failure while creating thread1\n"​);​
 + exit(-1);
 + }
  /* Give it 1 second to start */  /* Give it 1 second to start */
  sleep(1);  sleep(1);
  
  for (i = 1; i < argc; i++) {  for (i = 1; i < argc; i++) {
- if (strncmp(argv[i],​ "​-nolockmem",​ 10) == 0) {+ if (strncmp(argv[i],​ "​-nolockmem",​ 10) == 0)
  lock_memory = 0;  lock_memory = 0;
- } 
  }  }
  
Line 222: Line 232:
  printf("​Current and future memory locked in RAM\n"​);​  printf("​Current and future memory locked in RAM\n"​);​
  }  }
- /* printf something so we avoid introducing a page fault simply by 
-    ​performing the potentially first printf call. */ 
- printf("​Page size = %d\n", page_size); 
  
  (void)dump_page_faults();​ /* Set the baseline */  (void)dump_page_faults();​ /* Set the baseline */
  
- /* From this point onwards we no longer expect to have any + /
-    page faults for currently allocated memory. */+         * From this point onwards we no longer expect to have any 
 +  ​* ​page faults for currently allocated memory. 
 +  */
  
  /* Make the first thread fill the stack. */  /* Make the first thread fill the stack. */
Line 244: Line 253:
         "​thread 1. This is expected.\n"​);​         "​thread 1. This is expected.\n"​);​
  else  else
- printf ("​After locking memory, new page faults have " \+ printf("​After locking memory, new page faults have " \
  "​been generated during during stack access " \  "​been generated during during stack access " \
  "​of thread 1. This is unexpected!\n"​);​  "​of thread 1. This is unexpected!\n"​);​
  }  }
- /* Thread 1 has not yet terminated, meaning that thread 2 will not + /
-    reuse the same (locked) stack region. */+         * Thread 1 has not yet terminated, meaning that thread 2 will not 
 +  ​* ​reuse the same (locked) stack region. 
 +  */
  
  /* Start the second thread and make it fill the stack. */  /* Start the second thread and make it fill the stack. */
Line 257: Line 268:
  thread_ids[1] = startThread(0,​ stack_size, check_stack_thread,​  thread_ids[1] = startThread(0,​ stack_size, check_stack_thread,​
  (void *)&​thread_data[1]);​  (void *)&​thread_data[1]);​
 + if (thread_ids[1] == -1) {
 + printf("​Exiting - Unexpected failure while creating thread2\n"​);​
 + exit(-1);
 + }
  /* Give it 1 second to start */  /* Give it 1 second to start */
  sleep(1);  sleep(1);
Line 279: Line 294:
  /* Check whether page faults have been detected. */  /* Check whether page faults have been detected. */
  int exit_code = 0;  int exit_code = 0;
 +
  if ((page_faults_detected_in_thread1) ||  if ((page_faults_detected_in_thread1) ||
      (page_faults_detected_in_thread2)) {      (page_faults_detected_in_thread2)) {
Line 293: Line 309:
  return exit_code;  return exit_code;
 } }
 +
 </​code>​ </​code>​
  
realtime/documentation/howto/applications/memory/mlockall_stack_sample.txt · Last modified: 2017/06/10 00:41 by jithu