Stxxl  1.4.0
io/simdisk_file.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002  *  io/simdisk_file.cpp
00003  *
00004  *  Part of the STXXL. See http://stxxl.sourceforge.net
00005  *
00006  *  Copyright (C) 2002-2003 Roman Dementiev <dementiev@mpi-sb.mpg.de>
00007  *  Copyright (C) 2008 Andreas Beckmann <beckmann@cs.uni-frankfurt.de>
00008  *
00009  *  Distributed under the Boost Software License, Version 1.0.
00010  *  (See accompanying file LICENSE_1_0.txt or copy at
00011  *  http://www.boost.org/LICENSE_1_0.txt)
00012  **************************************************************************/
00013 
00014 #include <stxxl/bits/io/simdisk_file.h>
00015 
00016 #if STXXL_HAVE_SIMDISK_FILE
00017 
00018 #include <stxxl/bits/io/iostats.h>
00019 #include <stxxl/bits/common/error_handling.h>
00020 
00021 
00022 __STXXL_BEGIN_NAMESPACE
00023 
00024 
00025 void DiskGeometry::add_zone(int & first_cyl, int last_cyl,
00026                             int sec_per_track, int & first_sect)
00027 {
00028     double rate =
00029         nsurfaces * sec_per_track * bytes_per_sector /
00030         ((nsurfaces - 1) * head_switch_time +
00031          cyl_switch_time +
00032          nsurfaces * revolution_time);
00033     int sectors =
00034         (last_cyl - first_cyl +
00035          1) * nsurfaces * sec_per_track;
00036     zones.insert(Zone(first_sect, sectors, rate));
00037     first_sect += sectors;
00038     first_cyl = last_cyl + 1;
00039 }
00040 
00041 // returns delay in s
00042 double DiskGeometry::get_delay(file::offset_type offset, file::size_type size)
00043 {
00044 #if 0
00045     int first_sect = offset / bytes_per_sector;
00046     int last_sect = (offset + size) / bytes_per_sector;
00047     int sectors = size / bytes_per_sector;
00048     double delay =
00049         cmd_ovh + seek_time + rot_latency +
00050         double(bytes_per_sector) /
00051         double(interface_speed);
00052 
00053     std::set<Zone, ZoneCmp>::iterator zone = zones.lower_bound(first_sect);
00054     //std::cout << __PRETTY_FUNCTION__ << " " << (*zone).first_sector << std::endl;
00055     while (1)
00056     {
00057         int from_this_zone =
00058             last_sect - ((*zone).first_sector +
00059                          (*zone).sectors);
00060         if (from_this_zone <= 0)
00061         {
00062             delay += sectors * bytes_per_sector /
00063                      ((*zone).sustained_data_rate);
00064             break;
00065         }
00066         else
00067         {
00068             delay += from_this_zone *
00069                      bytes_per_sector /
00070                      ((*zone).sustained_data_rate);
00071             zone++;
00072             stxxl_nassert(zone == zones.end());
00073             sectors -= from_this_zone;
00074         }
00075     }
00076 
00077     return delay;
00078 #else
00079     STXXL_UNUSED(offset);
00080     return double(size) / double(AVERAGE_SPEED);
00081 #endif
00082 }
00083 
00084 
00085 IC35L080AVVA07::IC35L080AVVA07()
00086 {
00087     std::cout << "Creating IBM 120GXP IC35L080AVVA07" <<
00088     std::endl;
00089 
00090     nsurfaces = 4;
00091     bytes_per_sector = 512;
00092     cmd_ovh = 0.0002;                           // in s
00093     seek_time = 0.0082;                         // in s
00094     rot_latency = 0.00417;                      // in s
00095     head_switch_time = 0.0015;                  // in s
00096     cyl_switch_time = 0.002;                    // in s
00097     revolution_time = 0.0083;                   // in s
00098     interface_speed = 100000000;                // in byte/s
00099 
00100     int first_sect = 0;
00101     int last_cyl = 0;
00102     add_zone(last_cyl, 1938, 928, first_sect);
00103     add_zone(last_cyl, 3756, 921, first_sect);
00104     add_zone(last_cyl, 5564, 896, first_sect);
00105     add_zone(last_cyl, 7687, 896, first_sect);
00106     add_zone(last_cyl, 9526, 888, first_sect);
00107     add_zone(last_cyl, 11334, 883, first_sect);
00108     add_zone(last_cyl, 13331, 864, first_sect);
00109     add_zone(last_cyl, 15128, 850, first_sect);
00110     add_zone(last_cyl, 16925, 840, first_sect);
00111     add_zone(last_cyl, 18922, 822, first_sect);
00112     add_zone(last_cyl, 20709, 806, first_sect);
00113     add_zone(last_cyl, 22601, 792, first_sect);
00114     add_zone(last_cyl, 24138, 787, first_sect);
00115     add_zone(last_cyl, 26024, 768, first_sect);
00116     add_zone(last_cyl, 27652, 752, first_sect);
00117     add_zone(last_cyl, 29501, 740, first_sect);
00118     add_zone(last_cyl, 31234, 725, first_sect);
00119     add_zone(last_cyl, 33009, 698, first_sect);
00120     add_zone(last_cyl, 34784, 691, first_sect);
00121     add_zone(last_cyl, 36609, 672, first_sect);
00122     add_zone(last_cyl, 38374, 648, first_sect);
00123     add_zone(last_cyl, 40139, 630, first_sect);
00124     add_zone(last_cyl, 41904, 614, first_sect);
00125     add_zone(last_cyl, 43519, 595, first_sect);
00126     add_zone(last_cyl, 45250, 576, first_sect);
00127     add_zone(last_cyl, 47004, 552, first_sect);
00128     add_zone(last_cyl, 48758, 533, first_sect);
00129     add_zone(last_cyl, 50491, 512, first_sect);
00130     add_zone(last_cyl, 52256, 493, first_sect);
00131     add_zone(last_cyl, 54010, 471, first_sect);
00132     add_zone(last_cyl, 55571, 448, first_sect);
00133 
00134 #if 0
00135     set<Zone, ZoneCmp>::iterator it = zones.begin();
00136     int i = 0;
00137     for ( ; it != zones.end(); it++, i++)
00138     {
00139         //const int block_size = 128*3*1024* 4;  // one cylinder
00140 
00141         std::cout << "Zone " << i << " first sector: " << (*it).first_sector;
00142         std::cout << " sectors: " << (*it).sectors << " sustained rate: ";
00143         std::cout << (*it).sustained_data_rate / 1024 / 1024 << " MiB/s" << std::endl;
00144     }
00145 
00146     std::cout << "Last sector     : " << first_sect << std::endl;
00147     std::cout << "Approx. capacity: " << (first_sect / 1024 / 1024) * bytes_per_sector << " MiB" << std::endl;
00148 #endif
00149 
00150     std::cout << "Transfer 16 MiB from zone 0 : " <<
00151     get_delay(0, 16 * 1024 * 1024) << " s" << std::endl;
00152     std::cout << "Transfer 16 MiB from zone 30: " <<
00153     get_delay(file::offset_type(158204036) * file::offset_type(bytes_per_sector), 16 * 1024 * 1024) << " s" << std::endl;
00154 }
00155 
00156 ////////////////////////////////////////////////////////////////////////////
00157 
00158 void sim_disk_file::serve(const request * req) throw (io_error)
00159 {
00160     scoped_mutex_lock fd_lock(fd_mutex);
00161     assert(req->get_file() == this);
00162     offset_type offset = req->get_offset();
00163     void * buffer = req->get_buffer();
00164     size_type bytes = req->get_size();
00165     request::request_type type = req->get_type();
00166     double op_start = timestamp();
00167 
00168     stats::scoped_read_write_timer read_write_timer(bytes, type == request::WRITE);
00169 
00170     void * mem = mmap(NULL, bytes, PROT_READ | PROT_WRITE, MAP_SHARED, file_des, offset);
00171     if (mem == MAP_FAILED)
00172     {
00173         STXXL_THROW2(io_error,
00174                      " Mapping failed." <<
00175                      " Page size: " << sysconf(_SC_PAGESIZE) <<
00176                      " offset modulo page size " << (offset % sysconf(_SC_PAGESIZE)));
00177     }
00178     else if (mem == 0)
00179     {
00180         stxxl_function_error(io_error);
00181     }
00182     else
00183     {
00184         if (type == request::READ)
00185         {
00186             memcpy(buffer, mem, bytes);
00187         } else {
00188             memcpy(mem, buffer, bytes);
00189         }
00190         stxxl_check_ge_0(munmap(mem, bytes), io_error);
00191     }
00192 
00193     double delay = get_delay(offset, bytes);
00194 
00195     delay = delay - timestamp() + op_start;
00196 
00197     assert(delay > 0.0);
00198 
00199     int seconds_to_wait = static_cast<int>(floor(delay));
00200     if (seconds_to_wait)
00201         sleep(seconds_to_wait);
00202 
00203     usleep((unsigned long)((delay - seconds_to_wait) * 1000000.));
00204 }
00205 
00206 const char * sim_disk_file::io_type() const
00207 {
00208     return "simdisk";
00209 }
00210 
00211 ////////////////////////////////////////////////////////////////////////////
00212 
00213 void sim_disk_file::set_size(offset_type newsize)
00214 {
00215     scoped_mutex_lock fd_lock(fd_mutex);
00216     if (newsize > _size())
00217     {
00218         stxxl_check_ge_0(::lseek(file_des, newsize - 1, SEEK_SET), io_error);
00219         stxxl_check_ge_0(::write(file_des, "", 1), io_error);
00220     }
00221 }
00222 
00223 __STXXL_END_NAMESPACE
00224 
00225 #endif  // #if STXXL_HAVE_SIMDISK_FILE
00226 // vim: et:ts=4:sw=4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines