Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r71145 - in trunk/boost/interprocess: detail smart_ptr
From: igaztanaga_at_[hidden]
Date: 2011-04-09 07:50:37


Author: igaztanaga
Date: 2011-04-09 07:50:37 EDT (Sat, 09 Apr 2011)
New Revision: 71145
URL: http://svn.boost.org/trac/boost/changeset/71145

Log:
Removed dynamic library loading to improve performance.
Text files modified:
   trunk/boost/interprocess/detail/win32_api.hpp | 208 +++++++++++++++++++++++++++------------
   trunk/boost/interprocess/smart_ptr/shared_ptr.hpp | 2
   2 files changed, 143 insertions(+), 67 deletions(-)

Modified: trunk/boost/interprocess/detail/win32_api.hpp
==============================================================================
--- trunk/boost/interprocess/detail/win32_api.hpp (original)
+++ trunk/boost/interprocess/detail/win32_api.hpp 2011-04-09 07:50:37 EDT (Sat, 09 Apr 2011)
@@ -24,6 +24,7 @@
 # pragma comment( lib, "advapi32.lib" )
 # pragma comment( lib, "oleaut32.lib" )
 # pragma comment( lib, "Ole32.lib" )
+# pragma comment( lib, "Psapi.lib" )
 #endif
 
 #if (defined BOOST_INTERPROCESS_WINDOWS)
@@ -843,6 +844,10 @@
 extern "C" __declspec(dllimport) void *__stdcall GetProcAddress(void *, const char*);
 extern "C" __declspec(dllimport) void *__stdcall GetModuleHandleA(const char*);
 extern "C" __declspec(dllimport) void *__stdcall GetFileInformationByHandle(void *, interprocess_by_handle_file_information*);
+extern "C" __declspec(dllimport) unsigned long __stdcall GetMappedFileNameW(void *, void *, wchar_t *, unsigned long);
+extern "C" __declspec(dllimport) long __stdcall RegOpenKeyExA(void *, const char *, unsigned long, unsigned long, void **);
+extern "C" __declspec(dllimport) long __stdcall RegQueryValueExA(void *, const char *, unsigned long*, unsigned long*, unsigned char *, unsigned long*);
+extern "C" __declspec(dllimport) long __stdcall RegCloseKey(void *);
 
 //COM API
 extern "C" __declspec(dllimport) long __stdcall CoInitialize(void *pvReserved);
@@ -868,6 +873,8 @@
 //Pointer to functions
 typedef long (__stdcall *NtDeleteFile_t)(object_attributes_t *ObjectAttributes);
 typedef long (__stdcall *NtSetInformationFile_t)(void *FileHandle, io_status_block_t *IoStatusBlock, void *FileInformation, unsigned long Length, int FileInformationClass );
+typedef long (__stdcall * NtQuerySystemInformation_t)(int, void*, unsigned long, unsigned long *);
+typedef long (__stdcall * NtQueryObject_t)(void*, object_information_class, void *, unsigned long, unsigned long *);
 typedef long (__stdcall *NtQueryInformationFile_t)(void *,io_status_block_t *,void *, long, int);
 typedef long (__stdcall *NtOpenFile_t)(void*,unsigned long ,object_attributes_t*,io_status_block_t*,unsigned long,unsigned long);
 typedef long (__stdcall *NtClose_t) (void*);
@@ -875,13 +882,8 @@
 typedef void (__stdcall *RtlFreeUnicodeString_t)(unicode_string_t *);
 typedef void (__stdcall *RtlInitUnicodeString_t)( unicode_string_t *, const wchar_t * );
 typedef long (__stdcall *RtlAppendUnicodeToString_t)(unicode_string_t *Destination, const wchar_t *Source);
-typedef long (__stdcall * NtQuerySystemInformation_t)(int, void*, unsigned long, unsigned long *);
-typedef long (__stdcall * NtQueryObject_t)(void*, object_information_class, void *, unsigned long, unsigned long *);
-typedef unsigned long (__stdcall * GetMappedFileName_t)(void *, void *, wchar_t *, unsigned long);
 typedef unsigned long (__stdcall * GetMappedFileName_t)(void *, void *, wchar_t *, unsigned long);
-typedef long (__stdcall * RegOpenKey_t)(void *, const char *, void **);
 typedef long (__stdcall * RegOpenKeyEx_t)(void *, const char *, unsigned long, unsigned long, void **);
-typedef long (__stdcall * RegQueryValue_t)(void *, const char *, char *, long*);
 typedef long (__stdcall * RegQueryValueEx_t)(void *, const char *, unsigned long*, unsigned long*, unsigned char *, unsigned long*);
 typedef long (__stdcall * RegCloseKey_t)(void *);
 
@@ -1111,6 +1113,18 @@
 inline void *get_module_handle(const char *name)
 { return GetModuleHandleA(name); }
 
+inline unsigned long get_mapped_file_name(void *process, void *lpv, wchar_t *lpfilename, unsigned long nSize)
+{ return GetMappedFileNameW(process, lpv, lpfilename, nSize); }
+
+inline long reg_open_key_ex(void *hKey, const char *lpSubKey, unsigned long ulOptions, unsigned long samDesired, void **phkResult)
+{ return RegOpenKeyExA(hKey, lpSubKey, ulOptions, samDesired, phkResult); }
+
+inline long reg_query_value_ex(void *hKey, const char *lpValueName, unsigned long*lpReserved, unsigned long*lpType, unsigned char *lpData, unsigned long*lpcbData)
+{ return RegQueryValueExA(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); }
+
+inline long reg_close_key(void *hKey)
+{ return RegCloseKey(hKey); }
+
 inline void initialize_object_attributes
 ( object_attributes_t *pobject_attr, unicode_string_t *name
  , unsigned long attr, void *rootdir, void *security_descr)
@@ -1131,6 +1145,48 @@
    ucStr->MaximumLength = bufSize;
 }
 
+template<int Dummy>
+struct function_address_holder
+{
+ enum { NtSetInformationFile, NtQuerySystemInformation, NtQueryObject, FunctionAddressNum };
+
+ private:
+ static void *FunctionAddresses[FunctionAddressNum];
+ static volatile long FunctionStates[FunctionAddressNum];
+
+ static void *get_address_from_dll(const unsigned int id)
+ {
+ const char *module[] = { "ntdll.dll", "ntdll.dll", "ntdll.dll" };
+ const char *function[] = { "NtSetInformationFile", "NtQuerySystemInformation", "NtQueryObject" };
+ return get_proc_address(get_module_handle(module[id]), function[id]);
+ }
+
+ public:
+ static void *get(const unsigned int id)
+ {
+ while(FunctionStates[id] < 2u){
+ if(interlocked_compare_exchange(&FunctionStates[id], 1, 0) == 0){
+ FunctionAddresses[id] = get_address_from_dll(id);
+ interlocked_increment(&FunctionStates[id]);
+ }
+ else{
+ sched_yield();
+ }
+ }
+ return FunctionAddresses[id];
+ }
+};
+
+template<int Dummy>
+void *function_address_holder<Dummy>::FunctionAddresses[FunctionAddressNum];
+
+template<int Dummy>
+volatile long function_address_holder<Dummy>::FunctionStates[FunctionAddressNum];
+
+struct dll_func
+ : public function_address_holder<0>
+{};
+
 //Complex winapi based functions...
 struct library_unloader
 {
@@ -1147,30 +1203,29 @@
       return false;
    }
 
- void *hiPSAPI = load_library("PSAPI.DLL");
- if (0 == hiPSAPI)
- return 0;
-
- library_unloader unloader(hiPSAPI);
-
- // Pointer to function getMappedFileName() in PSAPI.DLL
- GetMappedFileName_t pfGMFN =
- (GetMappedFileName_t)get_proc_address(hiPSAPI, "GetMappedFileNameW");
- if (! pfGMFN){
- return 0; // Failed: unexpected error
- }
+// void *hiPSAPI = load_library("PSAPI.DLL");
+// if (0 == hiPSAPI)
+// return 0;
+// library_unloader unloader(hiPSAPI);
+
+// Pointer to function getMappedFileName() in PSAPI.DLL
+// GetMappedFileName_t pfGMFN =
+// (GetMappedFileName_t)get_proc_address(hiPSAPI, "GetMappedFileNameW");
+// if (! pfGMFN){
+// return 0; // Failed: unexpected error
+// }
 
    bool bSuccess = false;
 
    // Create a file mapping object.
    void * hFileMap = create_file_mapping(hFile, page_readonly, 0, 1, 0, 0);
- if(hFileMap)
- {
+ if(hFileMap){
       // Create a file mapping to get the file name.
       void* pMem = map_view_of_file_ex(hFileMap, file_map_read, 0, 0, 1, 0);
 
       if (pMem){
- out_length = pfGMFN(get_current_process(), pMem, pszFilename, MaxPath);
+ //out_length = pfGMFN(get_current_process(), pMem, pszFilename, MaxPath);
+ out_length = get_mapped_file_name(get_current_process(), pMem, pszFilename, MaxPath);
          if(out_length){
             bSuccess = true;
          }
@@ -1185,7 +1240,8 @@
 inline bool get_system_time_of_day_information(system_timeofday_information &info)
 {
    NtQuerySystemInformation_t pNtQuerySystemInformation = (NtQuerySystemInformation_t)
- get_proc_address(get_module_handle("ntdll.dll"), "NtQuerySystemInformation");
+ //get_proc_address(get_module_handle("ntdll.dll"), "NtQuerySystemInformation");
+ dll_func::get(dll_func::NtQuerySystemInformation);
    unsigned long res;
    long status = pNtQuerySystemInformation(system_time_of_day_information, &info, sizeof(info), &res);
    if(status){
@@ -1280,13 +1336,15 @@
 {
    try{
       NtSetInformationFile_t pNtSetInformationFile =
- (NtSetInformationFile_t)get_proc_address(get_module_handle("ntdll.dll"), "NtSetInformationFile");
+ //(NtSetInformationFile_t)get_proc_address(get_module_handle("ntdll.dll"), "NtSetInformationFile");
+ (NtSetInformationFile_t)dll_func::get(dll_func::NtSetInformationFile);
       if(!pNtSetInformationFile){
          return false;
       }
 
       NtQueryObject_t pNtQueryObject =
- (NtQueryObject_t)get_proc_address(get_module_handle("ntdll.dll"), "NtQueryObject");
+ //(NtQueryObject_t)get_proc_address(get_module_handle("ntdll.dll"), "NtQueryObject");
+ (NtQueryObject_t)dll_func::get(dll_func::NtQueryObject);
 
       //First step: Obtain a handle to the file using Win32 rules. This resolves relative paths
       void *fh = create_file(filename, generic_read | delete_access, open_existing,
@@ -1354,105 +1412,123 @@
 
 struct reg_closer
 {
- RegCloseKey_t func_;
+ //reg_closer(RegCloseKey_t func, void *key) : func_(func), key_(key){}
+ //~reg_closer(){ (*func_)(key_); }
+ //RegCloseKey_t func_;
    void *key_;
- reg_closer(RegCloseKey_t func, void *key) : func_(func), key_(key){}
- ~reg_closer(){ (*func_)(key_); }
+ reg_closer(void *key) : key_(key){}
+ ~reg_closer(){ reg_close_key(key_); }
 };
 
 inline void get_shared_documents_folder(std::string &s)
 {
    s.clear();
- void *hAdvapi = load_library("Advapi32.dll");
- if (hAdvapi){
- library_unloader unloader(hAdvapi);
+ //void *hAdvapi = load_library("Advapi32.dll");
+ //if (hAdvapi){
+ //library_unloader unloader(hAdvapi);
       // Pointer to function RegOpenKeyA
- RegOpenKeyEx_t pRegOpenKey =
- (RegOpenKeyEx_t)get_proc_address(hAdvapi, "RegOpenKeyExA");
- if (pRegOpenKey){
+ //RegOpenKeyEx_t pRegOpenKey =
+ //(RegOpenKeyEx_t)get_proc_address(hAdvapi, "RegOpenKeyExA");
+ //if (pRegOpenKey){
          // Pointer to function RegCloseKey
- RegCloseKey_t pRegCloseKey =
- (RegCloseKey_t)get_proc_address(hAdvapi, "RegCloseKey");
- if (pRegCloseKey){
+ //RegCloseKey_t pRegCloseKey =
+ //(RegCloseKey_t)get_proc_address(hAdvapi, "RegCloseKey");
+ //if (pRegCloseKey){
             // Pointer to function RegQueryValueA
- RegQueryValueEx_t pRegQueryValue =
- (RegQueryValueEx_t)get_proc_address(hAdvapi, "RegQueryValueExA");
- if (pRegQueryValue){
+ //RegQueryValueEx_t pRegQueryValue =
+ //(RegQueryValueEx_t)get_proc_address(hAdvapi, "RegQueryValueExA");
+ //if (pRegQueryValue){
                //Open the key
                void *key;
- if ((*pRegOpenKey)( hkey_local_machine
+ //if ((*pRegOpenKey)( hkey_local_machine
+ //, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
+ //, 0
+ //, key_query_value
+ //, &key) == 0){
+ //reg_closer key_closer(pRegCloseKey, key);
+ if (reg_open_key_ex( hkey_local_machine
                                  , "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
                                  , 0
                                  , key_query_value
                                  , &key) == 0){
- reg_closer key_closer(pRegCloseKey, key);
+ reg_closer key_closer(key);
 
                   //Obtain the value
                   unsigned long size;
                   unsigned long type;
                   const char *const reg_value = "Common AppData";
- long err = (*pRegQueryValue)( key, reg_value, 0, &type, 0, &size);
+ //long err = (*pRegQueryValue)( key, reg_value, 0, &type, 0, &size);
+ long err = reg_query_value_ex( key, reg_value, 0, &type, 0, &size);
                   if(!err){
                      //Size includes terminating NULL
                      s.resize(size);
- err = (*pRegQueryValue)( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
+ //err = (*pRegQueryValue)( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
+ err = reg_query_value_ex( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
                      if(!err)
                         s.erase(s.end()-1);
                      (void)err;
                   }
                }
- }
- }
- }
- }
+ //}
+ //}
+ //}
+ //}
 }
 
 
 inline void get_registry_value(const char *folder, const char *value_key, std::vector<unsigned char> &s)
 {
    s.clear();
- void *hAdvapi = load_library("Advapi32.dll");
- if (hAdvapi){
- library_unloader unloader(hAdvapi);
+ //void *hAdvapi = load_library("Advapi32.dll");
+ //if (hAdvapi){
+ //library_unloader unloader(hAdvapi);
       // Pointer to function RegOpenKeyA
- RegOpenKeyEx_t pRegOpenKey =
- (RegOpenKeyEx_t)get_proc_address(hAdvapi, "RegOpenKeyExA");
- if (pRegOpenKey){
+ //RegOpenKeyEx_t pRegOpenKey =
+ //(RegOpenKeyEx_t)get_proc_address(hAdvapi, "RegOpenKeyExA");
+ //if (pRegOpenKey){
          // Pointer to function RegCloseKey
- RegCloseKey_t pRegCloseKey =
- (RegCloseKey_t)get_proc_address(hAdvapi, "RegCloseKey");
- if (pRegCloseKey){
+ //RegCloseKey_t pRegCloseKey =
+ //(RegCloseKey_t)get_proc_address(hAdvapi, "RegCloseKey");
+ //if (pRegCloseKey){
             // Pointer to function RegQueryValueA
- RegQueryValueEx_t pRegQueryValue =
- (RegQueryValueEx_t)get_proc_address(hAdvapi, "RegQueryValueExA");
- if (pRegQueryValue){
+ //RegQueryValueEx_t pRegQueryValue =
+ //(RegQueryValueEx_t)get_proc_address(hAdvapi, "RegQueryValueExA");
+ //if (pRegQueryValue){
                //Open the key
                void *key;
- if ((*pRegOpenKey)( hkey_local_machine
+ //if ((*pRegOpenKey)( hkey_local_machine
+ //, folder
+ //, 0
+ //, key_query_value
+ //, &key) == 0){
+ //reg_closer key_closer(pRegCloseKey, key);
+ if (reg_open_key_ex( hkey_local_machine
                                  , folder
                                  , 0
                                  , key_query_value
                                  , &key) == 0){
- reg_closer key_closer(pRegCloseKey, key);
+ reg_closer key_closer(key);
 
                   //Obtain the value
                   unsigned long size;
                   unsigned long type;
                   const char *const reg_value = value_key;
- long err = (*pRegQueryValue)( key, reg_value, 0, &type, 0, &size);
+ //long err = (*pRegQueryValue)( key, reg_value, 0, &type, 0, &size);
+ long err = reg_query_value_ex( key, reg_value, 0, &type, 0, &size);
                   if(!err){
                      //Size includes terminating NULL
                      s.resize(size);
- err = (*pRegQueryValue)( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
+ //err = (*pRegQueryValue)( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
+ err = reg_query_value_ex( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
                      if(!err)
                         s.erase(s.end()-1);
                      (void)err;
                   }
                }
- }
- }
- }
- }
+ //}
+ //}
+ //}
+ //}
 }
 
 struct co_uninitializer

Modified: trunk/boost/interprocess/smart_ptr/shared_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/shared_ptr.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/shared_ptr.hpp 2011-04-09 07:50:37 EDT (Sat, 09 Apr 2011)
@@ -384,7 +384,7 @@
       );
    }
    catch(...){
- return managed_shared_ptr<T, ManagedMemory>::type();
+ return typename managed_shared_ptr<T, ManagedMemory>::type();
    }
 }
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk