00001 /* 00002 * Copyright (C) 2009, Edmundo Albuquerque de Souza e Silva. 00003 * 00004 * This file may be distributed under the terms of the Q Public License 00005 * as defined by Trolltech AS of Norway and appearing in the file 00006 * LICENSE.QPL included in the packaging of this file. 00007 * 00008 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING 00009 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00010 * PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, 00011 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING 00012 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 00013 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 00014 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 00015 * 00016 * Thanks: Jose Renato Santos 00017 * 00018 */ 00019 00020 /////////////////////////////////////////////////////////////////////////////// 00021 // diskrequest.cpp: Implementation of DiskRequest classes: 00022 // - CDiskRequestQueue 00023 // - CDiskRequestManager 00024 /////////////////////////////////////////////////////////////////////////////// 00025 00026 #include "diskrequest.h" 00027 #include "RioError.h" 00028 00029 #include <iostream> 00030 00031 ////////////////////////// CDiskRequestQueue ///////////////////////////////// 00032 00033 /////////////////////////////////////////////////////////////////////////////// 00034 // Put -- Put request at end of queue 00035 void CDiskRequestQueue::Put( StrDiskRequest* Request ) 00036 { 00037 m_Queue.Put(( LocalQueueEle* ) Request ); 00038 } 00039 00040 /////////////////////////////////////////////////////////////////////////////// 00041 // Get -- Get first element of queue. 00042 StrDiskRequest* CDiskRequestQueue::Get() 00043 { 00044 return ( StrDiskRequest* ) m_Queue.Get(); 00045 } 00046 00047 /////////////////////////////////////////////////////////////////////////////// 00048 // Put -- Remove an arbitrary request from queue 00049 void CDiskRequestQueue::Remove( StrDiskRequest* Request ) 00050 { 00051 m_Queue.Remove(( LocalQueueEle* ) Request ); 00052 } 00053 00054 //////////////////////////// CDiskRequestManager ///////////////////////////// 00055 00056 /////////////////////////////////////////////////////////////////////////////// 00057 CDiskRequestManager::CDiskRequestManager() 00058 { 00059 m_n = 0; 00060 // m_FreeList does not need to be initialized 00061 m_DiskRequest = 0; 00062 } 00063 00064 CDiskRequestManager::~CDiskRequestManager() 00065 { 00066 if( m_DiskRequest != 0 ) 00067 { 00068 delete[] m_DiskRequest; 00069 } 00070 } 00071 00072 /////////////////////////////////////////////////////////////////////////////// 00073 int CDiskRequestManager::Initialize( const unsigned int nDiskRequest ) 00074 { 00075 // Request index has to fit in 16 bits 00076 if( ( nDiskRequest <= 0 ) || ( nDiskRequest > 0xffff ) ) 00077 { 00078 return ERROR_ROUTER + ERROR_INVALID_PARAM; 00079 } 00080 00081 // In case was initialized before 00082 if( m_DiskRequest != 0 ) 00083 { 00084 delete[] m_DiskRequest; 00085 m_n = 0; 00086 } 00087 00088 m_DiskRequest = new StrDiskRequest[nDiskRequest]; 00089 00090 if( m_DiskRequest == 0 ) 00091 return ERROR_ROUTER + ERROR_MEMORY; 00092 00093 m_n = nDiskRequest; 00094 00095 for( int i = ((int)( nDiskRequest )) - 1; i >= 0; i-- ) 00096 { 00097 m_DiskRequest[i].Status = DiskRequestStatusFree; 00098 m_DiskRequest[i].Id = i; 00099 m_FreeList.Put( &m_DiskRequest[i] ); 00100 } 00101 00102 return (0); 00103 } 00104 00105 /////////////////////////////////////////////////////////////////////////////// 00106 // Free --Return DiskRequest to free list 00107 void CDiskRequestManager::Free( StrDiskRequest* DiskRequest ) 00108 { 00109 // Higher order 16 bits are version number, incremented every time 00110 // request is free. Lower order 16 bits are index to 00111 // vector m_DiskRequest 00112 00113 u32 Version = (( DiskRequest->Id & 0xffff0000 ) >> 16 ); 00114 Version ++; 00115 u32 Ind = DiskRequest->Id & 0xffff; 00116 DiskRequest->Id = Ind | ( Version << 16 ); 00117 DiskRequest->Status = DiskRequestStatusFree; 00118 00119 m_FreeList.Put( DiskRequest ); 00120 } 00121 00122 /////////////////////////////////////////////////////////////////////////////// 00123 // New -- Get new request structure from free list if available, otherwise 00124 // return null 00125 StrDiskRequest* CDiskRequestManager::New() 00126 { 00127 StrDiskRequest* rp; 00128 00129 rp = ( StrDiskRequest* ) m_FreeList.Get(); 00130 00131 if( rp !=0 ) 00132 { 00133 rp->Status = DiskRequestStatusInUse; 00134 } 00135 00136 return rp; 00137 } 00138 00139 /////////////////////////////////////////////////////////////////////////////// 00140 // Get -- Get address of request structure associated with a given request id 00141 StrDiskRequest* CDiskRequestManager::Get( const u32 ReqId ) 00142 { 00143 StrDiskRequest* rp; 00144 00145 // lower 16 bits are index to vector m_DiskRequest; 00146 u32 ind = ReqId & 0xffff; 00147 00148 if( ind >= m_n ) 00149 return 0; 00150 00151 rp = &m_DiskRequest[ind]; 00152 00153 // Request must be in use and Request Id version must match 00154 if( ( rp->Status != DiskRequestStatusFree ) && ( rp->Id == ReqId ) ) 00155 return rp; 00156 else 00157 return 0; 00158 } 00159