title: c, linux - using pthread.h in kernel
body: <p>I'm trying to test the validity of a 9*9 sudoku problem and the results should be printed via <code>printk(KERN_INFO "blablabla")</code>. I've tried two methods to compile my c file, <code>make</code> and <code>gcc myfile.c myfile -o -lpthread</code>. However, none of them worked. </p>
  
  <p>When I called <code>make</code> it threw me with an fatal error: pthread.h: no such file or directory but it is right in the path <code>/usr/include</code>.</p>
  
  <p>Then I found some recommendations from the net so I tried <code>gcc</code> this time. Unfortunately, I got a bunch of errors after calling <code>gcc myfile.c myfile -o -lpthread</code> such as </p>
  
  <p><code>/usr/include/linux/list.h: In function 'INIT_LIST_HEAD': /usr/include/linux/list.h:27:17: error: dereferencing pointer to incomplete type 'struct list_head'</code></p>
  
  <p>and</p>
  
  <p><code>error: unknown type name 'bool'</code>, </p>
  
  <p>to name but a few. The point is that I got these errors <strong>after</strong> I upgrade my softwares via <code>sudo apt-get update -y</code>.</p>
  
  <p>Here's the code:</p>
  
  <pre><code>#include &lt;pthread.h&gt;
  #include &lt;linux/module.h&gt;
  #include &lt;linux/kernel.h&gt;
  #include &lt;linux/init.h&gt;
  
  typedef struct
  {
      int row;
      int col;
      int (* board)[9];
  } parameters;
  
  void * find_rows(void * params);
  
  void * find_cols(void * params);
  
  void * check_valid(void * params);
  
  /***************
   * ENTRY POINT
   **************/
  int thread_init(void)
  {
      // ====== Create the board =======
      int board[9][9] = {
              {6, 2, 4, 5, 3, 9, 1, 8, 7},
              {5, 1, 9, 7, 2, 8, 6, 3, 4},
              {8, 3, 7, 6, 1, 4, 2, 9, 5},
              {1, 4, 3, 8, 6, 5, 7, 2, 9},
              {9, 5, 8, 2, 4, 7, 3, 6, 1},
              {7, 6, 2, 3, 9, 1, 4, 5, 8},
              {3, 7, 1, 9, 5, 6, 8, 4, 2},
              {4, 9, 6, 1, 8, 2, 5, 7, 3},
              {2, 8, 5, 4, 7, 3, 9, 1, 6}
          };
  
      /*int  i, j = 0;
      size_t count;
      int board[9][9];
      char *line = (char *) malloc(100);
  
      FILE *file;
      file = fopen("test.txt", "r");
  
      while(getline(&amp;line, &amp;count, file) != -1) {
          for (count &gt; 0; count--; j++)
              sscanf(line, "%d", &amp;board[i][j]);
          i++;
      }*/
  
      parameters * data = (parameters *) malloc(sizeof(parameters));
      data-&gt;row = 0;
      data-&gt;col = 0;
      data-&gt;board = board;
  
      // ====== Create the parameters for the 3x3 threads ======
  
      // First 3x3
      parameters * data1 = (parameters *) malloc(sizeof(parameters));
      data1-&gt;row = 0;
      data1-&gt;col = 0;
      data1-&gt;board = board;
  
      // Second 3x3
      parameters * data2 = (parameters *) malloc(sizeof(parameters));
      data2-&gt;row = 0;
      data2-&gt;col = 3;
      data2-&gt;board = board;
  
      // Third 3x3
      parameters * data3 = (parameters *) malloc(sizeof(parameters));
      data3-&gt;row = 0;
      data3-&gt;col = 6;
      data3-&gt;board = board;
  
      // Fourth 3x3
      parameters * data4 = (parameters *) malloc(sizeof(parameters));
      data4-&gt;row = 3;
      data4-&gt;col = 0;
      data4-&gt;board = board;
  
      // Fifth 3x3
      parameters * data5 = (parameters *) malloc(sizeof(parameters));
      data5-&gt;row = 3;
      data5-&gt;col = 3;
      data5-&gt;board = board;
  
      // Sixth 3x3
      parameters * data6 = (parameters *) malloc(sizeof(parameters));
      data6-&gt;row = 3;
      data6-&gt;col = 6;
      data6-&gt;board = board;
  
      // Seventh 3x3
      parameters * data7 = (parameters *) malloc(sizeof(parameters));
      data7-&gt;row = 6;
      data7-&gt;col = 0;
      data7-&gt;board = board;
  
      // Eighth 3x3
      parameters * data8 = (parameters *) malloc(sizeof(parameters));
      data8-&gt;row = 6;
      data8-&gt;col = 3;
      data8-&gt;board = board;
  
      // Ninth 3x3
      parameters * data9 = (parameters *) malloc(sizeof(parameters));
      data9-&gt;row = 6;
      data9-&gt;col = 6;
      data9-&gt;board = board;
  
      // ====== Create the threads ======
      pthread_t thread_rows, thread_cols, thread1, thread2, thread3, thread4, thread5, thread6, thread7, thread8, thread9;
  
      // ====== Create the return values for the threads ======
      void * all_rows;
      void * all_cols;
      void * square1;
      void * square2;
      void * square3;
      void * square4;
      void * square5;
      void * square6;
      void * square7;
      void * square8;
      void * square9;
  
      // ====== Initialize the threads ======
      pthread_create(&amp;thread_rows, NULL, find_rows, (void *) data);
      pthread_create(&amp;thread_cols, NULL, find_cols, (void *) data);
      pthread_create(&amp;thread1, NULL, check_valid, (void *) data1);
      pthread_create(&amp;thread2, NULL, check_valid, (void *) data2);
      pthread_create(&amp;thread3, NULL, check_valid, (void *) data3);
      pthread_create(&amp;thread4, NULL, check_valid, (void *) data4);
      pthread_create(&amp;thread5, NULL, check_valid, (void *) data5);
      pthread_create(&amp;thread6, NULL, check_valid, (void *) data6);
      pthread_create(&amp;thread7, NULL, check_valid, (void *) data7);
      pthread_create(&amp;thread8, NULL, check_valid, (void *) data8);
      pthread_create(&amp;thread9, NULL, check_valid, (void *) data9);
  
      // ======= Wait for all threads to finish their tasks =======
      pthread_join(thread_rows, &amp;all_rows);
      pthread_join(thread_cols, &amp;all_cols);
      pthread_join(thread1, &amp;square1);
      pthread_join(thread2, &amp;square2);
      pthread_join(thread3, &amp;square3);
      pthread_join(thread4, &amp;square4);
      pthread_join(thread5, &amp;square5);
      pthread_join(thread6, &amp;square6);
      pthread_join(thread7, &amp;square7);
      pthread_join(thread8, &amp;square8);
      pthread_join(thread9, &amp;square9);
  
      // ====== Check whether the Sudoku Puzzle was solved ======
      if (    (int)(uintptr_t) all_rows == 1 &amp;&amp;
              (int)(uintptr_t) all_cols == 1 &amp;&amp;
              (int)(uintptr_t) square1 == 1 &amp;&amp;
              (int)(uintptr_t) square2 == 1 &amp;&amp;
              (int)(uintptr_t) square3 == 1 &amp;&amp;
              (int)(uintptr_t) square4 == 1 &amp;&amp;
              (int)(uintptr_t) square5 == 1 &amp;&amp;
              (int)(uintptr_t) square6 == 1 &amp;&amp;
              (int)(uintptr_t) square7 == 1 &amp;&amp;
              (int)(uintptr_t) square8 == 1 &amp;&amp;
              (int)(uintptr_t) square9 == 1 )
      {
          printf("The Sudoku Puzzle is solved!\n");
      }
      else
      {
          printf("The Sudoku Puzzle is NOT solved.\n");
      }
  
      return 0;
  }
  
  void * find_rows(void * params) {
      parameters * data = (parameters *) params;
      int startRow = data-&gt;row;
      int startCol = data-&gt;col;
      for (int i = startRow; i &lt; 9; ++i) {
          int row[10] = {0};
          for (int j = startCol; j &lt; 9; ++j) {
              int val = data-&gt;board[i][j];
              if (row[val] != 0) {
                  return (void *) 0;
              }
              else{
                  row[val] = 1;
              }
          }
      }
      return (void *) 1;
  }
  
  void * find_cols(void * params) {
      parameters * data = (parameters *) params;
      int startRow = data-&gt;row;
      int startCol = data-&gt;col;
      for (int i = startCol; i &lt; 9; ++i) {
          int col[10] = {0};
          for (int j = startRow; j &lt; 9; ++j) {
              int val = data-&gt;board[j][i];
              if (col[val] != 0) {
                  return (void *) 0;
              }
              else{
                  col[val] = 1;
              }
          }
      }
      return (void *) 1;
  }
  
  void * check_valid(void * params) {
      parameters * data = (parameters *) params;
      int startRow = data-&gt;row;
      int startCol = data-&gt;col;
      int saved[10] = {0};
      for (int i = startRow; i &lt; startRow + 3; ++i) {
          for (int j = startCol; j &lt; startCol + 3; ++j) {
              int val = data-&gt;board[i][j];
              if (saved[val] != 0) {
                  return (void *) 0;
              }
              else{
                  saved[val] = 1;
              }
          }
      }
      return (void *) 1;
  }
  
  void thread_exit(void)
  {
      printk(KERN_INFO "Removing Module\n");
  }
  
  module_init( thread_init );
  module_exit( thread_exit );
  </code></pre>
  
  <p>I just can't figure out what went wrong...and no idea how to debug.</p>
  
  <p>Thanks in advance.</p>