DeviceAccessScheduler.cpp

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/device/DeviceAccessScheduler.cpp#15 $
00003 // Fennel is a library of data storage and processing components.
00004 // Copyright (C) 2005-2009 The Eigenbase Project
00005 // Copyright (C) 2005-2009 SQLstream, Inc.
00006 // Copyright (C) 2005-2009 LucidEra, Inc.
00007 // Portions Copyright (C) 1999-2009 John V. Sichi
00008 //
00009 // This program is free software; you can redistribute it and/or modify it
00010 // under the terms of the GNU General Public License as published by the Free
00011 // Software Foundation; either version 2 of the License, or (at your option)
00012 // any later version approved by The Eigenbase Project.
00013 //
00014 // This program is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with this program; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 */
00023 
00024 #include "fennel/common/CommonPreamble.h"
00025 #include "fennel/device/DeviceAccessScheduler.h"
00026 #include "fennel/device/DeviceAccessSchedulerParams.h"
00027 #include "fennel/device/ThreadPoolScheduler.h"
00028 #include "fennel/device/RandomAccessDevice.h"
00029 #include "fennel/device/RandomAccessRequest.h"
00030 #include "fennel/common/FennelExcn.h"
00031 #include "fennel/common/FennelResource.h"
00032 
00033 #ifdef __MSVC__
00034 #include "fennel/device/IoCompletionPortScheduler.h"
00035 #include "fennel/common/SysCallExcn.h"
00036 #include <windows.h>
00037 #else
00038 #include <dlfcn.h>
00039 #endif
00040 
00041 #ifdef USE_AIO_H
00042 #include "fennel/device/AioPollingScheduler.h"
00043 #include "fennel/device/AioSignalScheduler.h"
00044 #endif
00045 
00046 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/device/DeviceAccessScheduler.cpp#15 $");
00047 
00048 #ifdef USE_LIBAIO_H
00049 static DeviceAccessScheduler *dlopenAioLinuxScheduler(
00050     DeviceAccessSchedulerParams const &params)
00051 {
00052     // TODO jvs 4-Sept-2006:  add corresponding dlclose if anyone cares
00053     void *hLib = dlopen("libfennel_device_aio.so", RTLD_NOW | RTLD_GLOBAL);
00054     if (!hLib) {
00055         return NULL;
00056     }
00057     void *pFactory = dlsym(hLib, "newAioLinuxScheduler");
00058     if (!pFactory) {
00059         return NULL;
00060     }
00061     typedef DeviceAccessScheduler *(*PDeviceAccessSchedulerFactory)(
00062         DeviceAccessSchedulerParams const &);
00063     PDeviceAccessSchedulerFactory pSchedulerFactory =
00064         (PDeviceAccessSchedulerFactory) pFactory;
00065     return (*pSchedulerFactory)(params);
00066 }
00067 #endif
00068 
00069 DeviceAccessScheduler *
00070 DeviceAccessScheduler::newScheduler(
00071     DeviceAccessSchedulerParams const &params)
00072 {
00073     switch (params.schedulerType) {
00074     case DeviceAccessSchedulerParams::THREAD_POOL_SCHEDULER:
00075         return new ThreadPoolScheduler(params);
00076 
00077 #ifdef __MSVC__
00078     case DeviceAccessSchedulerParams::IO_COMPLETION_PORT_SCHEDULER:
00079         return new IoCompletionPortScheduler(params);
00080 #endif
00081 
00082 #ifdef USE_LIBAIO_H
00083     case DeviceAccessSchedulerParams::AIO_LINUX_SCHEDULER:
00084         {
00085             DeviceAccessScheduler *pScheduler = dlopenAioLinuxScheduler(params);
00086             if (pScheduler) {
00087                 return pScheduler;
00088             } else {
00089                 // if the aioLinux scheduler was explicitly selected (vs simply
00090                 // using the default type for the OS), then the AIO runtime
00091                 // library must be installed; otherwise, fall through to use
00092                 // ThreadPoolScheduler as fallback
00093                 if (params.usingDefaultSchedulerType) {
00094                     break;
00095                 }
00096                 throw FennelExcn(FennelResource::instance().libaioRequired());
00097             }
00098         }
00099 #endif
00100 
00101 #ifdef USE_AIO_H
00102     case DeviceAccessSchedulerParams::AIO_POLLING_SCHEDULER:
00103         return new AioPollingScheduler(params);
00104     case DeviceAccessSchedulerParams::AIO_SIGNAL_SCHEDULER:
00105         return new AioSignalScheduler(params);
00106 #endif
00107 
00108     default:
00109         // fall through to use ThreadPoolScheduler as a fallback
00110         break;
00111     }
00112     return new ThreadPoolScheduler(params);
00113 }
00114 
00115 DeviceAccessScheduler::~DeviceAccessScheduler()
00116 {
00117 }
00118 
00119 RandomAccessRequestBinding::RandomAccessRequestBinding()
00120 {
00121 #ifdef __MSVC__
00122     // TODO:  only create this when ThreadPoolScheduler is being used?
00123     hEvent = CreateEvent(NULL,1,0,NULL);
00124     if (!hEvent) {
00125         throw new SysCallExcn("CreateEvent failed");
00126     }
00127 #endif
00128 }
00129 
00130 RandomAccessRequestBinding::~RandomAccessRequestBinding()
00131 {
00132 #ifdef __MSVC__
00133     CloseHandle(hEvent);
00134 #endif
00135 }
00136 
00137 void RandomAccessRequest::execute()
00138 {
00139     pDevice->transfer(*this);
00140 }
00141 
00142 void DeviceAccessScheduler::registerDevice(
00143     SharedRandomAccessDevice)
00144 {
00145 }
00146 
00147 void DeviceAccessScheduler::unregisterDevice(
00148     SharedRandomAccessDevice)
00149 {
00150 }
00151 
00152 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/device/DeviceAccessScheduler.cpp#15 $");
00153 
00154 // End DeviceAccessScheduler.cpp

Generated on Mon Jun 22 04:00:18 2009 for Fennel by  doxygen 1.5.1