1  /* Copyright (C) 2021-2023 Free Software Foundation, Inc.
       2     Contributed by Oracle.
       3  
       4     This file is part of GNU Binutils.
       5  
       6     This program is free software; you can redistribute it and/or modify
       7     it under the terms of the GNU General Public License as published by
       8     the Free Software Foundation; either version 3, or (at your option)
       9     any later version.
      10  
      11     This program is distributed in the hope that it will be useful,
      12     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14     GNU General Public License for more details.
      15  
      16     You should have received a copy of the GNU General Public License
      17     along with this program; if not, write to the Free Software
      18     Foundation, 51 Franklin Street - Fifth Floor, Boston,
      19     MA 02110-1301, USA.  */
      20  
      21  #include <unistd.h>
      22  #include <stdlib.h>
      23  #include <stdio.h>
      24  #include "stopwatch.h"
      25  
      26  /*=======================================================*/
      27  
      28  /* pagethrash - allocate some memory, and thrash around in it */
      29  int
      30  pagethrash (int thrashmb)
      31  {
      32    char buf[1024];
      33  
      34    hrtime_t start = gethrtime ();
      35    hrtime_t vstart = gethrvtime ();
      36  
      37    /* Log the event */
      38    wlog ("start of pagethrash", NULL);
      39  
      40    /* Start a stopwatch */
      41    stopwatch_t *w = stpwtch_alloc ("pagethrash", 0);
      42  
      43    /* compute the size */
      44    unsigned long size = thrashmb * 1024 * 1024;
      45    int pagesize = getpagesize ();
      46    void *space = malloc (size + pagesize);
      47    if (space == NULL)
      48      {
      49        fprintf (stderr, "\tpagethrash failed; can't get %ld bytes.\n", size);
      50        exit (1);
      51      }
      52  
      53    /* round address to page boundary */
      54    unsigned long loc = (((unsigned long) space + pagesize - 1) & ~(pagesize - 1));
      55    long npages = size / pagesize;
      56  
      57    /* touch all the pages to force them in */
      58    for (long i = 0; i < npages; i++)
      59      {
      60        stpwtch_start (w);
      61        *(int *) (loc + i * pagesize) = i;
      62        stpwtch_stop (w);
      63      }
      64  
      65    /* now free up the space */
      66    free (space);
      67  
      68    /* print the timing results */
      69    stpwtch_print (w);
      70    free ((void *) w);
      71  
      72    sprintf (buf, "pagethrash: %ld pages", npages);
      73    whrvlog (gethrtime () - start, gethrvtime () - vstart, buf, NULL);
      74    return 0;
      75  }