LTP GCOV extension - code coverage report
Current view: directory - storage/maria/unittest - ma_pagecache_rwconsist.c
Test: mtr_and_unit.info
Date: 2009-03-05 Instrumented lines: 139
Code covered: 7.2 % Executed lines: 10

       1                 : /* Copyright (C) 2006-2008 MySQL AB
       2                 : 
       3                 :    This program is free software; you can redistribute it and/or modify
       4                 :    it under the terms of the GNU General Public License as published by
       5                 :    the Free Software Foundation; version 2 of the License.
       6                 : 
       7                 :    This program is distributed in the hope that it will be useful,
       8                 :    but WITHOUT ANY WARRANTY; without even the implied warranty of
       9                 :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      10                 :    GNU General Public License for more details.
      11                 : 
      12                 :    You should have received a copy of the GNU General Public License
      13                 :    along with this program; if not, write to the Free Software
      14                 :    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
      15                 : 
      16                 : /*
      17                 :   TODO: use pthread_join instead of wait_for_thread_count_to_be_zero, like in
      18                 :   my_atomic-t.c (see BUG#22320).
      19                 : */
      20                 : 
      21                 : #include <tap.h>
      22                 : #include <my_sys.h>
      23                 : #include <m_string.h>
      24                 : #include "test_file.h"
      25                 : #include <tap.h>
      26                 : 
      27                 : #define PCACHE_SIZE (TEST_PAGE_SIZE*1024*8)
      28                 : 
      29                 : #ifndef DBUG_OFF
      30                 : static const char* default_dbug_option;
      31                 : #endif
      32                 : 
      33                 : 
      34                 : #define SLEEP my_sleep(5)
      35                 : 
      36                 : static char *file1_name= (char*)"page_cache_test_file_1";
      37                 : static PAGECACHE_FILE file1;
      38                 : static pthread_cond_t COND_thread_count;
      39                 : static pthread_mutex_t LOCK_thread_count;
      40                 : static uint thread_count= 0;
      41                 : static PAGECACHE pagecache;
      42                 : 
      43                 : static uint number_of_readers= 5;
      44                 : static uint number_of_writers= 5;
      45                 : static uint number_of_read_tests= 2000;
      46                 : static uint number_of_write_tests= 1000;
      47                 : static uint read_sleep_limit= 3;
      48                 : static uint report_divisor= 50;
      49                 : 
      50                 : /**
      51                 :   @brief Dummy pagecache callback.
      52                 : */
      53                 : 
      54                 : static my_bool
      55                 : dummy_callback(uchar *page __attribute__((unused)),
      56                 :                pgcache_page_no_t page_no __attribute__((unused)),
      57                 :                uchar* data_ptr __attribute__((unused)))
      58               0 : {
      59               0 :   return 0;
      60                 : }
      61                 : 
      62                 : 
      63                 : /**
      64                 :   @brief Dummy pagecache callback.
      65                 : */
      66                 : 
      67                 : static void
      68                 : dummy_fail_callback(uchar* data_ptr __attribute__((unused)))
      69               0 : {
      70                 :   return;
      71                 : }
      72                 : 
      73                 : 
      74                 : /**
      75                 :   @brief Checks page consistency
      76                 : 
      77                 :   @param buff            pointer to the page content
      78                 :   @param task            task ID
      79                 : */
      80                 : void check_page(uchar *buff, int task)
      81               0 : {
      82                 :   uint i;
      83               0 :   DBUG_ENTER("check_page");
      84                 : 
      85               0 :   for (i= 1; i < TEST_PAGE_SIZE; i++)
      86                 :   {
      87               0 :     if (buff[0] != buff[i])
      88               0 :       goto err;
      89                 :   }
      90               0 :   DBUG_VOID_RETURN;
      91               0 : err:
      92               0 :   diag("Task %d char #%u '%u' != '%u'", task, i, (uint) buff[0],
      93                 :        (uint) buff[i]);
      94               0 :   DBUG_PRINT("err", ("try to flush"));
      95               0 :   exit(1);
      96                 : }
      97                 : 
      98                 : 
      99                 : 
     100                 : void reader(int num)
     101               0 : {
     102                 :   unsigned char *buff;
     103                 :   uint i;
     104                 :   PAGECACHE_BLOCK_LINK *link;
     105                 : 
     106               0 :   for (i= 0; i < number_of_read_tests; i++)
     107                 :   {
     108               0 :     if (i % report_divisor == 0)
     109               0 :       diag("Reader %d - %u", num, i);
     110               0 :     buff= pagecache_read(&pagecache, &file1, 0, 3, NULL,
     111                 :                          PAGECACHE_PLAIN_PAGE,
     112                 :                          PAGECACHE_LOCK_READ,
     113                 :                          &link);
     114               0 :     check_page(buff, num);
     115               0 :     pagecache_unlock_by_link(&pagecache, link,
     116                 :                              PAGECACHE_LOCK_READ_UNLOCK,
     117                 :                              PAGECACHE_UNPIN, 0, 0, 0, FALSE);
     118                 :     {
     119               0 :       int lim= rand() % read_sleep_limit;
     120                 :       int j;
     121               0 :       for (j= 0; j < lim; j++)
     122               0 :         SLEEP;
     123                 :     }
     124                 :   }
     125                 : }
     126                 : 
     127                 : 
     128                 : void writer(int num)
     129               0 : {
     130                 :   uint i;
     131                 :   uchar *buff;
     132                 :   PAGECACHE_BLOCK_LINK *link;
     133                 : 
     134               0 :   for (i= 0; i < number_of_write_tests; i++)
     135                 :   {
     136               0 :     uchar c= (uchar) rand() % 256;
     137                 : 
     138               0 :     if (i % report_divisor == 0)
     139               0 :       diag("Writer %d - %u", num, i);
     140               0 :     buff= pagecache_read(&pagecache, &file1, 0, 3, NULL,
     141                 :                          PAGECACHE_PLAIN_PAGE,
     142                 :                          PAGECACHE_LOCK_WRITE,
     143                 :                          &link);
     144                 : 
     145               0 :     check_page(buff, num);
     146               0 :     bfill(buff, TEST_PAGE_SIZE / 2, c);
     147               0 :     SLEEP;
     148               0 :     bfill(buff + TEST_PAGE_SIZE/2, TEST_PAGE_SIZE / 2, c);
     149               0 :     check_page(buff, num);
     150               0 :     pagecache_unlock_by_link(&pagecache, link,
     151                 :                              PAGECACHE_LOCK_WRITE_UNLOCK,
     152                 :                              PAGECACHE_UNPIN, 0, 0, 1, FALSE);
     153               0 :     SLEEP;
     154                 :   }
     155                 : }
     156                 : 
     157                 : 
     158                 : static void *test_thread_reader(void *arg)
     159               0 : {
     160               0 :   int param=*((int*) arg);
     161               0 :   my_thread_init();
     162                 :   {
     163               0 :     DBUG_ENTER("test_reader");
     164                 : 
     165               0 :     DBUG_PRINT("enter", ("param: %d", param));
     166                 : 
     167               0 :     reader(param);
     168                 : 
     169               0 :     DBUG_PRINT("info", ("Thread %s ended", my_thread_name()));
     170               0 :     pthread_mutex_lock(&LOCK_thread_count);
     171               0 :     ok(1, "reader%d: done", param);
     172               0 :     thread_count--;
     173               0 :     VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
     174               0 :     pthread_mutex_unlock(&LOCK_thread_count);
     175               0 :     free((uchar*) arg);
     176               0 :     my_thread_end();
     177                 :   }
     178               0 :   return 0;
     179                 : }
     180                 : 
     181                 : 
     182                 : static void *test_thread_writer(void *arg)
     183               0 : {
     184               0 :   int param=*((int*) arg);
     185               0 :   my_thread_init();
     186                 :   {
     187               0 :     DBUG_ENTER("test_writer");
     188                 : 
     189               0 :     writer(param);
     190                 : 
     191               0 :     DBUG_PRINT("info", ("Thread %s ended", my_thread_name()));
     192               0 :     pthread_mutex_lock(&LOCK_thread_count);
     193               0 :     ok(1, "writer%d: done", param);
     194               0 :     thread_count--;
     195               0 :     VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
     196               0 :     pthread_mutex_unlock(&LOCK_thread_count);
     197               0 :     free((uchar*) arg);
     198               0 :     my_thread_end();
     199                 :   }
     200               0 :   return 0;
     201                 : }
     202                 : 
     203                 : 
     204                 : int main(int argc __attribute__((unused)),
     205                 :          char **argv __attribute__((unused)))
     206               1 : {
     207                 :   pthread_t tid;
     208                 :   pthread_attr_t thr_attr;
     209                 :   int *param, error, pagen;
     210                 : 
     211               1 :   MY_INIT(argv[0]);
     212                 : 
     213                 : #ifndef DBUG_OFF
     214                 : #if defined(__WIN__)
     215                 :   default_dbug_option= "d:t:i:O,\\test_pagecache_consist.trace";
     216                 : #else
     217               1 :   default_dbug_option= "d:t:i:O,/tmp/test_pagecache_consist.trace";
     218                 : #endif
     219               1 :   if (argc > 1)
     220                 :   {
     221               0 :     DBUG_SET(default_dbug_option);
     222               0 :     DBUG_SET_INITIAL(default_dbug_option);
     223                 :   }
     224                 : #endif
     225                 : 
     226                 :   {
     227               1 :   DBUG_ENTER("main");
     228               1 :   DBUG_PRINT("info", ("Main thread: %s\n", my_thread_name()));
     229               1 :   plan(number_of_writers + number_of_readers);
     230               1 :   SKIP_BIG_TESTS(number_of_writers + number_of_readers)
     231                 :   {
     232                 : 
     233               0 :   if ((file1.file= my_open(file1_name,
     234                 :                            O_CREAT | O_TRUNC | O_RDWR, MYF(0))) == -1)
     235                 :   {
     236               0 :     diag( "Got error during file1 creation from open() (errno: %d)\n",
     237                 :             errno);
     238               0 :     exit(1);
     239                 :   }
     240               0 :   pagecache_file_init(file1, &dummy_callback, &dummy_callback,
     241                 :                       &dummy_fail_callback, &dummy_callback, NULL);
     242               0 :   DBUG_PRINT("info", ("file1: %d", file1.file));
     243               0 :   if (my_chmod(file1_name, S_IRWXU | S_IRWXG | S_IRWXO, MYF(MY_WME)))
     244               0 :     exit(1);
     245               0 :   my_pwrite(file1.file, (const uchar*) "test file", 9, 0, MYF(0));
     246                 : 
     247               0 :   if ((error= pthread_cond_init(&COND_thread_count, NULL)))
     248                 :   {
     249               0 :     diag( "COND_thread_count: %d from pthread_cond_init (errno: %d)\n",
     250                 :             error, errno);
     251               0 :     exit(1);
     252                 :   }
     253               0 :   if ((error= pthread_mutex_init(&LOCK_thread_count, MY_MUTEX_INIT_FAST)))
     254                 :   {
     255               0 :     diag( "LOCK_thread_count: %d from pthread_cond_init (errno: %d)\n",
     256                 :             error, errno);
     257               0 :     exit(1);
     258                 :   }
     259                 : 
     260               0 :   if ((error= pthread_attr_init(&thr_attr)))
     261                 :   {
     262               0 :     diag("Got error: %d from pthread_attr_init (errno: %d)\n",
     263                 :             error,errno);
     264               0 :     exit(1);
     265                 :   }
     266               0 :   if ((error= pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_DETACHED)))
     267                 :   {
     268               0 :     diag(
     269                 :             "Got error: %d from pthread_attr_setdetachstate (errno: %d)\n",
     270                 :             error,errno);
     271               0 :     exit(1);
     272                 :   }
     273                 : 
     274                 : #ifdef HAVE_THR_SETCONCURRENCY
     275                 :   VOID(thr_setconcurrency(2));
     276                 : #endif
     277                 : 
     278               0 :   if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
     279                 :                              TEST_PAGE_SIZE, 0)) == 0)
     280                 :   {
     281               0 :     diag("Got error: init_pagecache() (errno: %d)\n",
     282                 :             errno);
     283               0 :     exit(1);
     284                 :   }
     285               0 :   DBUG_PRINT("info", ("Page cache %d pages", pagen));
     286                 :   {
     287               0 :     unsigned char *buffr= malloc(TEST_PAGE_SIZE);
     288               0 :     memset(buffr, '\0', TEST_PAGE_SIZE);
     289               0 :     pagecache_write(&pagecache, &file1, 0, 3, buffr,
     290                 :                     PAGECACHE_PLAIN_PAGE,
     291                 :                     PAGECACHE_LOCK_LEFT_UNLOCKED,
     292                 :                     PAGECACHE_PIN_LEFT_UNPINNED,
     293                 :                     PAGECACHE_WRITE_DELAY,
     294                 :                     0, LSN_IMPOSSIBLE);
     295                 :   }
     296               0 :   pthread_mutex_lock(&LOCK_thread_count);
     297                 : 
     298               0 :   while (number_of_readers != 0 || number_of_writers != 0)
     299                 :   {
     300               0 :     if (number_of_readers != 0)
     301                 :     {
     302               0 :       param=(int*) malloc(sizeof(int));
     303               0 :       *param= number_of_readers + number_of_writers;
     304               0 :       if ((error= pthread_create(&tid, &thr_attr, test_thread_reader,
     305                 :                                  (void*) param)))
     306                 :       {
     307               0 :         diag("Got error: %d from pthread_create (errno: %d)\n",
     308                 :                 error,errno);
     309               0 :         exit(1);
     310                 :       }
     311               0 :       thread_count++;
     312               0 :       number_of_readers--;
     313                 :     }
     314               0 :     if (number_of_writers != 0)
     315                 :     {
     316               0 :       param=(int*) malloc(sizeof(int));
     317               0 :       *param= number_of_writers + number_of_readers;
     318               0 :       if ((error= pthread_create(&tid, &thr_attr, test_thread_writer,
     319                 :                                  (void*) param)))
     320                 :       {
     321               0 :         diag("Got error: %d from pthread_create (errno: %d)\n",
     322                 :                 error,errno);
     323               0 :         exit(1);
     324                 :       }
     325               0 :       thread_count++;
     326               0 :       number_of_writers--;
     327                 :     }
     328                 :   }
     329               0 :   DBUG_PRINT("info", ("Thread started"));
     330               0 :   pthread_mutex_unlock(&LOCK_thread_count);
     331                 : 
     332               0 :   pthread_attr_destroy(&thr_attr);
     333                 : 
     334                 :   /* wait finishing */
     335               0 :   pthread_mutex_lock(&LOCK_thread_count);
     336               0 :   while (thread_count)
     337                 :   {
     338               0 :     if ((error= pthread_cond_wait(&COND_thread_count, &LOCK_thread_count)))
     339               0 :       diag("COND_thread_count: %d from pthread_cond_wait\n", error);
     340                 :   }
     341               0 :   pthread_mutex_unlock(&LOCK_thread_count);
     342               0 :   DBUG_PRINT("info", ("thread ended"));
     343                 : 
     344               0 :   end_pagecache(&pagecache, 1);
     345               0 :   DBUG_PRINT("info", ("Page cache ended"));
     346                 : 
     347               0 :   if (my_close(file1.file, MYF(0)) != 0)
     348                 :   {
     349               0 :     diag( "Got error during file1 closing from close() (errno: %d)\n",
     350                 :             errno);
     351               0 :     exit(1);
     352                 :   }
     353               0 :   my_delete(file1_name, MYF(0));
     354                 : 
     355               0 :   DBUG_PRINT("info", ("file1 (%d) closed", file1.file));
     356               0 :   DBUG_PRINT("info", ("Program end"));
     357                 :   } /* SKIP_BIG_TESTS */
     358               1 :   my_end(0);
     359                 : 
     360               1 :   return exit_status();
     361                 :   }
     362                 : }

Generated by: LTP GCOV extension version 1.4