STXXL  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
simdisk_file.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * lib/io/simdisk_file.cpp
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
5  *
6  * Copyright (C) 2002-2003 Roman Dementiev <[email protected]>
7  * Copyright (C) 2008 Andreas Beckmann <[email protected]>
8  *
9  * Distributed under the Boost Software License, Version 1.0.
10  * (See accompanying file LICENSE_1_0.txt or copy at
11  * http://www.boost.org/LICENSE_1_0.txt)
12  **************************************************************************/
13 
15 
16 #if STXXL_HAVE_SIMDISK_FILE
17 
18 #include <stxxl/bits/io/iostats.h>
20 #include "ufs_platform.h"
21 #include <sys/mman.h>
22 
24 
25 
26 void simdisk_geometry::add_zone(int& first_cyl, int last_cyl,
27  int sec_per_track, int& first_sect)
28 {
29  double rate =
30  nsurfaces * sec_per_track * bytes_per_sector /
31  ((nsurfaces - 1) * head_switch_time +
32  cyl_switch_time +
33  nsurfaces * revolution_time);
34  int sectors =
35  (last_cyl - first_cyl +
36  1) * nsurfaces * sec_per_track;
37  zones.insert(Zone(first_sect, sectors, rate));
38  first_sect += sectors;
39  first_cyl = last_cyl + 1;
40 }
41 
42 // returns delay in s
43 double simdisk_geometry::get_delay(file::offset_type offset, file::size_type size)
44 {
45 #if 0
46  int first_sect = offset / bytes_per_sector;
47  int last_sect = (offset + size) / bytes_per_sector;
48  int sectors = size / bytes_per_sector;
49  double delay =
50  cmd_ovh + seek_time + rot_latency +
51  double(bytes_per_sector) /
52  double(interface_speed);
53 
54  std::set<Zone, ZoneCmp>::iterator zone = zones.lower_bound(first_sect);
55  //std::cout << __PRETTY_FUNCTION__ << " " << (*zone).first_sector << std::endl;
56  while (1)
57  {
58  int from_this_zone =
59  last_sect - ((*zone).first_sector +
60  (*zone).sectors);
61  if (from_this_zone <= 0)
62  {
63  delay += sectors * bytes_per_sector /
64  ((*zone).sustained_data_rate);
65  break;
66  }
67  else
68  {
69  delay += from_this_zone *
70  bytes_per_sector /
71  ((*zone).sustained_data_rate);
72  zone++;
73  stxxl_nassert(zone == zones.end());
74  sectors -= from_this_zone;
75  }
76  }
77 
78  return delay;
79 #else
80  STXXL_UNUSED(offset);
81  return double(size) / double(AVERAGE_SPEED);
82 #endif
83 }
84 
85 
86 IC35L080AVVA07::IC35L080AVVA07()
87 {
88  std::cout << "Creating IBM 120GXP IC35L080AVVA07" <<
89  std::endl;
90 
91  nsurfaces = 4;
92  bytes_per_sector = 512;
93  cmd_ovh = 0.0002; // in s
94  seek_time = 0.0082; // in s
95  rot_latency = 0.00417; // in s
96  head_switch_time = 0.0015; // in s
97  cyl_switch_time = 0.002; // in s
98  revolution_time = 0.0083; // in s
99  interface_speed = 100000000; // in byte/s
100 
101  int first_sect = 0;
102  int last_cyl = 0;
103  add_zone(last_cyl, 1938, 928, first_sect);
104  add_zone(last_cyl, 3756, 921, first_sect);
105  add_zone(last_cyl, 5564, 896, first_sect);
106  add_zone(last_cyl, 7687, 896, first_sect);
107  add_zone(last_cyl, 9526, 888, first_sect);
108  add_zone(last_cyl, 11334, 883, first_sect);
109  add_zone(last_cyl, 13331, 864, first_sect);
110  add_zone(last_cyl, 15128, 850, first_sect);
111  add_zone(last_cyl, 16925, 840, first_sect);
112  add_zone(last_cyl, 18922, 822, first_sect);
113  add_zone(last_cyl, 20709, 806, first_sect);
114  add_zone(last_cyl, 22601, 792, first_sect);
115  add_zone(last_cyl, 24138, 787, first_sect);
116  add_zone(last_cyl, 26024, 768, first_sect);
117  add_zone(last_cyl, 27652, 752, first_sect);
118  add_zone(last_cyl, 29501, 740, first_sect);
119  add_zone(last_cyl, 31234, 725, first_sect);
120  add_zone(last_cyl, 33009, 698, first_sect);
121  add_zone(last_cyl, 34784, 691, first_sect);
122  add_zone(last_cyl, 36609, 672, first_sect);
123  add_zone(last_cyl, 38374, 648, first_sect);
124  add_zone(last_cyl, 40139, 630, first_sect);
125  add_zone(last_cyl, 41904, 614, first_sect);
126  add_zone(last_cyl, 43519, 595, first_sect);
127  add_zone(last_cyl, 45250, 576, first_sect);
128  add_zone(last_cyl, 47004, 552, first_sect);
129  add_zone(last_cyl, 48758, 533, first_sect);
130  add_zone(last_cyl, 50491, 512, first_sect);
131  add_zone(last_cyl, 52256, 493, first_sect);
132  add_zone(last_cyl, 54010, 471, first_sect);
133  add_zone(last_cyl, 55571, 448, first_sect);
134 
135 #if 0
136  set<Zone, ZoneCmp>::iterator it = zones.begin();
137  int i = 0;
138  for ( ; it != zones.end(); it++, i++)
139  {
140  //const int block_size = 128*3*1024* 4; // one cylinder
141 
142  std::cout << "Zone " << i << " first sector: " << (*it).first_sector;
143  std::cout << " sectors: " << (*it).sectors << " sustained rate: ";
144  std::cout << (*it).sustained_data_rate / 1024 / 1024 << " MiB/s" << std::endl;
145  }
146 
147  std::cout << "Last sector : " << first_sect << std::endl;
148  std::cout << "Approx. capacity: " << (first_sect / 1024 / 1024) * bytes_per_sector << " MiB" << std::endl;
149 #endif
150 
151  std::cout << "Transfer 16 MiB from zone 0 : " <<
152  get_delay(0, 16 * 1024 * 1024) << " s" << std::endl;
153  std::cout << "Transfer 16 MiB from zone 30: " <<
154  get_delay(file::offset_type(158204036) * file::offset_type(bytes_per_sector), 16 * 1024 * 1024) << " s" << std::endl;
155 }
156 
157 ////////////////////////////////////////////////////////////////////////////
158 
159 void sim_disk_file::serve(const request* req) throw (io_error)
160 {
161  scoped_mutex_lock fd_lock(fd_mutex);
162  assert(req->get_file() == this);
163  offset_type offset = req->get_offset();
164  void* buffer = req->get_buffer();
165  size_type bytes = req->get_size();
166  request::request_type type = req->get_type();
167  double op_start = timestamp();
168 
169  stats::scoped_read_write_timer read_write_timer(bytes, type == request::WRITE);
170 
171  void* mem = mmap(NULL, bytes, PROT_READ | PROT_WRITE, MAP_SHARED, file_des, offset);
172  if (mem == MAP_FAILED)
173  {
175  (io_error,
176  " mmap() failed." <<
177  " Page size: " << sysconf(_SC_PAGESIZE) <<
178  " offset modulo page size " << (offset % sysconf(_SC_PAGESIZE)));
179  }
180  else if (mem == 0)
181  {
182  STXXL_THROW_ERRNO(io_error, "mmap() returned NULL");
183  }
184  else
185  {
186  if (type == request::READ)
187  {
188  memcpy(buffer, mem, bytes);
189  }
190  else
191  {
192  memcpy(mem, buffer, bytes);
193  }
194  STXXL_THROW_ERRNO_NE_0(munmap(mem, bytes), io_error,
195  "munmap() failed");
196  }
197 
198  double delay = get_delay(offset, bytes);
199 
200  delay = delay - timestamp() + op_start;
201 
202  assert(delay > 0.0);
203 
204  int seconds_to_wait = static_cast<int>(floor(delay));
205  if (seconds_to_wait)
206  sleep(seconds_to_wait);
207 
208  usleep((unsigned long)((delay - seconds_to_wait) * 1000000.));
209 }
210 
211 const char* sim_disk_file::io_type() const
212 {
213  return "simdisk";
214 }
215 
216 ////////////////////////////////////////////////////////////////////////////
217 
218 void sim_disk_file::set_size(offset_type newsize)
219 {
220  scoped_mutex_lock fd_lock(fd_mutex);
221  if (newsize > _size())
222  {
223  STXXL_THROW_ERRNO_LT_0(::lseek(file_des, newsize - 1, SEEK_SET), io_error,
224  "lseek() fd=" << file_des << " pos=" << newsize - 1);
225  STXXL_THROW_ERRNO_LT_0(::write(file_des, "", 1), io_error,
226  "write() fd=" << file_des << " size=1");
227  }
228 }
229 
231 
232 #endif // #if STXXL_HAVE_SIMDISK_FILE
233 // vim: et:ts=4:sw=4
static const int bytes
number of bytes in uint_pair
Definition: uint_types.h:99
#define STXXL_THROW_ERRNO_NE_0(expr, exception_type, error_message)
Throws exception_type if (expr != 0) with &quot;Error in [function] : [error_message] : [errno message]&quot;...
#define lseek
Definition: ufs_platform.h:72
double timestamp()
Returns number of seconds since the epoch, high resolution.
Definition: timer.h:42
#define AVERAGE_SPEED
Definition: simdisk_file.h:39
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
void STXXL_UNUSED(const U &)
Definition: unused.h:23
#define STXXL_THROW_ERRNO_LT_0(expr, exception_type, error_message)
Throws exception_type if (expr &lt; 0) with &quot;Error in [function] : [error_message] : [errno message]&quot;...
#define STXXL_THROW_ERRNO(exception_type, error_message)
Throws exception_type with &quot;Error in [function] : [error_message] : [errno message]&quot;.
#define STXXL_END_NAMESPACE
Definition: namespace.h:17