diff options
author | Shashank | 2017-05-29 12:40:26 +0530 |
---|---|---|
committer | Shashank | 2017-05-29 12:40:26 +0530 |
commit | 0345245e860375a32c9a437c4a9d9cae807134e9 (patch) | |
tree | ad51ecbfa7bcd3cc5f09834f1bb8c08feaa526a4 /modules/parallel/src | |
download | scilab_for_xcos_on_cloud-0345245e860375a32c9a437c4a9d9cae807134e9.tar.gz scilab_for_xcos_on_cloud-0345245e860375a32c9a437c4a9d9cae807134e9.tar.bz2 scilab_for_xcos_on_cloud-0345245e860375a32c9a437c4a9d9cae807134e9.zip |
CMSCOPE changed
Diffstat (limited to 'modules/parallel/src')
-rwxr-xr-x | modules/parallel/src/c/DllmainParallel.c | 36 | ||||
-rwxr-xr-x | modules/parallel/src/c/core_Import.def | 13 | ||||
-rwxr-xr-x | modules/parallel/src/c/forkWindows.c | 266 | ||||
-rwxr-xr-x | modules/parallel/src/c/forkWindows.h | 33 | ||||
-rwxr-xr-x | modules/parallel/src/c/parallel.rc | 96 | ||||
-rwxr-xr-x | modules/parallel/src/c/parallel.vcxproj | 271 | ||||
-rwxr-xr-x | modules/parallel/src/c/parallel.vcxproj.filters | 81 | ||||
-rwxr-xr-x | modules/parallel/src/c/semWindows.h | 32 | ||||
-rwxr-xr-x | modules/parallel/src/cpp/parallel_run.hxx | 401 | ||||
-rwxr-xr-x | modules/parallel/src/noparallel/.deps/libsciparallel_la-noparallel.Plo | 1 | ||||
-rwxr-xr-x | modules/parallel/src/noparallel/noparallel.c | 37 | ||||
-rwxr-xr-x | modules/parallel/src/noparallel/noparallel.h | 19 |
12 files changed, 1286 insertions, 0 deletions
diff --git a/modules/parallel/src/c/DllmainParallel.c b/modules/parallel/src/c/DllmainParallel.c new file mode 100755 index 000000000..c130af365 --- /dev/null +++ b/modules/parallel/src/c/DllmainParallel.c @@ -0,0 +1,36 @@ +/* + * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab + * Copyright (C) 2010 - DIGITEO - Allan CORNET + * + * This file must be used under the terms of the CeCILL. + * This source file is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at + * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + * + */ + +#include <windows.h> +/*--------------------------------------------------------------------------*/ +#pragma comment(lib,"../../../../bin/libintl.lib") +#ifdef __INTEL_COMPILER +#pragma comment(lib,"libiomp5md.lib") +#endif +/*--------------------------------------------------------------------------*/ +int WINAPI DllMain (HINSTANCE hInstance , DWORD reason, PVOID pvReserved) +{ + switch (reason) + { + case DLL_PROCESS_ATTACH: + break; + case DLL_PROCESS_DETACH: + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + break; + } + return 1; +} +/*--------------------------------------------------------------------------*/ + diff --git a/modules/parallel/src/c/core_Import.def b/modules/parallel/src/c/core_Import.def new file mode 100755 index 000000000..fd0b802ea --- /dev/null +++ b/modules/parallel/src/c/core_Import.def @@ -0,0 +1,13 @@ +LIBRARY core.dll + + +EXPORTS +callFunctionFromGateway +intersci_ +com_ +vstk_ +getrhsvar_ +scifunction_ +scistring_ +MyHeapAlloc +MyHeapFree diff --git a/modules/parallel/src/c/forkWindows.c b/modules/parallel/src/c/forkWindows.c new file mode 100755 index 000000000..a490d4510 --- /dev/null +++ b/modules/parallel/src/c/forkWindows.c @@ -0,0 +1,266 @@ +/* +* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +* Copyright (C) DIGITEO - 2010 - Allan CORNET +* +* This file must be used under the terms of the CeCILL. +* This source file is licensed as described in the file COPYING, which +* you should have received as part of this distribution. The terms +* are also available at +* http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +* +*/ +/*--------------------------------------------------------------------------*/ +#include <windows.h> +#include <WinNT.h> +#include <setjmp.h> +#include "forkWindows.h" +/*--------------------------------------------------------------------------*/ +typedef LONG NTSTATUS; +/*--------------------------------------------------------------------------*/ +typedef struct _SYSTEM_HANDLE_INFORMATION +{ + ULONG ProcessId; + UCHAR ObjectTypeNumber; + UCHAR Flags; + USHORT Handle; + PVOID Object; + ACCESS_MASK GrantedAccess; +} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; +/*--------------------------------------------------------------------------*/ +typedef struct _OBJECT_ATTRIBUTES +{ + ULONG Length; + HANDLE RootDirectory; + PVOID /* really PUNICODE_STRING */ ObjectName; + ULONG Attributes; + PVOID SecurityDescriptor; /* type SECURITY_DESCRIPTOR */ + PVOID SecurityQualityOfService; /* type SECURITY_QUALITY_OF_SERVICE */ +} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; +/*--------------------------------------------------------------------------*/ +typedef enum _MEMORY_INFORMATION_ +{ + MemoryBasicInformation, + MemoryWorkingSetList, + MemorySectionName, + MemoryBasicVlmInformation +} MEMORY_INFORMATION_CLASS; +/*--------------------------------------------------------------------------*/ +typedef struct _CLIENT_ID +{ + HANDLE UniqueProcess; + HANDLE UniqueThread; +} CLIENT_ID, *PCLIENT_ID; +/*--------------------------------------------------------------------------*/ +typedef struct _USER_STACK +{ + PVOID FixedStackBase; + PVOID FixedStackLimit; + PVOID ExpandableStackBase; + PVOID ExpandableStackLimit; + PVOID ExpandableStackBottom; +} USER_STACK, *PUSER_STACK; +/*--------------------------------------------------------------------------*/ +typedef LONG KPRIORITY; +typedef ULONG_PTR KAFFINITY; +typedef KAFFINITY *PKAFFINITY; +/*--------------------------------------------------------------------------*/ +typedef struct _THREAD_BASIC_INFORMATION +{ + NTSTATUS ExitStatus; + PVOID TebBaseAddress; + CLIENT_ID ClientId; + KAFFINITY AffinityMask; + KPRIORITY Priority; + KPRIORITY BasePriority; +} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION; +/*--------------------------------------------------------------------------*/ +typedef enum _SYSTEM_INFORMATION_CLASS { SystemHandleInformation = 0x10 } SYSTEM_INFORMATION_CLASS; +/*--------------------------------------------------------------------------*/ +typedef NTSTATUS (NTAPI *ZwWriteVirtualMemory_t)(IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN PVOID Buffer, + IN ULONG NumberOfBytesToWrite, + OUT PULONG NumberOfBytesWritten OPTIONAL); +/*--------------------------------------------------------------------------*/ +typedef NTSTATUS (NTAPI *ZwCreateProcess_t)(OUT PHANDLE ProcessHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN HANDLE InheriteFromProcessHandle, + IN BOOLEAN InheritHandles, + IN HANDLE SectionHandle OPTIONAL, + IN HANDLE DebugPort OPTIONAL, + IN HANDLE ExceptionPort OPTIONAL); +/*--------------------------------------------------------------------------*/ +typedef NTSTATUS (WINAPI *ZwQuerySystemInformation_t)(SYSTEM_INFORMATION_CLASS SystemInformationClass, + PVOID SystemInformation, + ULONG SystemInformationLength, + PULONG ReturnLength); +typedef NTSTATUS (NTAPI *ZwQueryVirtualMemory_t)(IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN MEMORY_INFORMATION_CLASS MemoryInformationClass, + OUT PVOID MemoryInformation, + IN ULONG MemoryInformationLength, + OUT PULONG ReturnLength OPTIONAL); +/*--------------------------------------------------------------------------*/ +typedef NTSTATUS (NTAPI *ZwGetContextThread_t)(IN HANDLE ThreadHandle, OUT PCONTEXT Context); +typedef NTSTATUS (NTAPI *ZwCreateThread_t)(OUT PHANDLE ThreadHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN HANDLE ProcessHandle, + OUT PCLIENT_ID ClientId, + IN PCONTEXT ThreadContext, + IN PUSER_STACK UserStack, + IN BOOLEAN CreateSuspended); +/*--------------------------------------------------------------------------*/ +typedef NTSTATUS (NTAPI *ZwResumeThread_t)(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL); +typedef NTSTATUS (NTAPI *ZwClose_t)(IN HANDLE ObjectHandle); +typedef NTSTATUS (NTAPI *ZwQueryInformationThread_t)(IN HANDLE ThreadHandle, + IN THREAD_INFORMATION_CLASS ThreadInformationClass, + OUT PVOID ThreadInformation, + IN ULONG ThreadInformationLength, + OUT PULONG ReturnLength OPTIONAL ); +/*--------------------------------------------------------------------------*/ +static ZwCreateProcess_t ZwCreateProcess = NULL; +static ZwQuerySystemInformation_t ZwQuerySystemInformation = NULL; +static ZwQueryVirtualMemory_t ZwQueryVirtualMemory = NULL; +static ZwCreateThread_t ZwCreateThread = NULL; +static ZwGetContextThread_t ZwGetContextThread = NULL; +static ZwResumeThread_t ZwResumeThread = NULL; +static ZwClose_t ZwClose = NULL; +static ZwQueryInformationThread_t ZwQueryInformationThread = NULL; +static ZwWriteVirtualMemory_t ZwWriteVirtualMemory = NULL; +/*--------------------------------------------------------------------------*/ +#define NtCurrentProcess() ((HANDLE)-1) +#define NtCurrentThread() ((HANDLE) -2) +/* we use really the Nt versions - so the following is just for completeness */ +#define ZwCurrentProcess() NtCurrentProcess() +#define ZwCurrentThread() NtCurrentThread() +#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) +#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) +/*--------------------------------------------------------------------------*/ +/* setjmp env for the jump back into the fork() function */ +static jmp_buf jenv; +/*--------------------------------------------------------------------------*/ +/* entry point for our child thread process - just longjmp into fork */ +static int child_entry(void) +{ + longjmp(jenv, 1); + return 0; +} +/*--------------------------------------------------------------------------*/ +static BOOL haveLoadedFunctionsForFork(void) +{ + HMODULE ntdll = GetModuleHandle("ntdll"); + if (ntdll == NULL) + { + return FALSE; + } + + if (ZwCreateProcess && ZwQuerySystemInformation && ZwQueryVirtualMemory && + ZwCreateThread && ZwGetContextThread && ZwResumeThread && + ZwQueryInformationThread && ZwWriteVirtualMemory && ZwClose) + { + return TRUE; + } + + ZwCreateProcess = (ZwCreateProcess_t) GetProcAddress(ntdll, "ZwCreateProcess"); + ZwQuerySystemInformation = (ZwQuerySystemInformation_t) GetProcAddress(ntdll, "ZwQuerySystemInformation"); + ZwQueryVirtualMemory = (ZwQueryVirtualMemory_t) GetProcAddress(ntdll, "ZwQueryVirtualMemory"); + ZwCreateThread = (ZwCreateThread_t) GetProcAddress(ntdll, "ZwCreateThread"); + ZwGetContextThread = (ZwGetContextThread_t) GetProcAddress(ntdll, "ZwGetContextThread"); + ZwResumeThread = (ZwResumeThread_t) GetProcAddress(ntdll, "ZwResumeThread"); + ZwQueryInformationThread = (ZwQueryInformationThread_t) GetProcAddress(ntdll, "ZwQueryInformationThread"); + ZwWriteVirtualMemory = (ZwWriteVirtualMemory_t) GetProcAddress(ntdll, "ZwWriteVirtualMemory"); + ZwClose = (ZwClose_t) GetProcAddress(ntdll, "ZwClose"); + + if (ZwCreateProcess && ZwQuerySystemInformation && ZwQueryVirtualMemory && + ZwCreateThread && ZwGetContextThread && ZwResumeThread && + ZwQueryInformationThread && ZwWriteVirtualMemory && ZwClose) + { + return TRUE; + } + else + { + ZwCreateProcess = NULL; + ZwQuerySystemInformation = NULL; + ZwQueryVirtualMemory = NULL; + ZwCreateThread = NULL; + ZwGetContextThread = NULL; + ZwResumeThread = NULL; + ZwQueryInformationThread = NULL; + ZwWriteVirtualMemory = NULL; + ZwClose = NULL; + } + return FALSE; +} +/*--------------------------------------------------------------------------*/ +int fork(void) +{ + HANDLE hProcess = 0, hThread = 0; + OBJECT_ATTRIBUTES oa = { sizeof(oa) }; + MEMORY_BASIC_INFORMATION mbi; + CLIENT_ID cid; + USER_STACK stack; + PNT_TIB tib; + THREAD_BASIC_INFORMATION tbi; + + CONTEXT context = {CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS | CONTEXT_FLOATING_POINT}; + + if (setjmp(jenv) != 0) + { + return 0; /* return as a child */ + } + + /* check whether the entry points are initilized and get them if necessary */ + if (!ZwCreateProcess && !haveLoadedFunctionsForFork()) + { + return -1; + } + + /* create forked process */ + ZwCreateProcess(&hProcess, PROCESS_ALL_ACCESS, &oa, NtCurrentProcess(), TRUE, 0, 0, 0); + + /* set the Eip for the child process to our child function */ + ZwGetContextThread(NtCurrentThread(), &context); + + /* In x64 the Eip and Esp are not present, their x64 counterparts are Rip and + Rsp respectively. + */ +#if _WIN64 + context.Rip = (ULONG)child_entry; +#else + context.Eip = (ULONG)child_entry; +#endif + +#if _WIN64 + ZwQueryVirtualMemory(NtCurrentProcess(), (PVOID)context.Rsp, MemoryBasicInformation, &mbi, sizeof mbi, 0); +#else + ZwQueryVirtualMemory(NtCurrentProcess(), (PVOID)context.Esp, MemoryBasicInformation, &mbi, sizeof mbi, 0); +#endif + + stack.FixedStackBase = 0; + stack.FixedStackLimit = 0; + stack.ExpandableStackBase = (PCHAR)mbi.BaseAddress + mbi.RegionSize; + stack.ExpandableStackLimit = mbi.BaseAddress; + stack.ExpandableStackBottom = mbi.AllocationBase; + + /* create thread using the modified context and stack */ + ZwCreateThread(&hThread, THREAD_ALL_ACCESS, &oa, hProcess, &cid, &context, &stack, TRUE); + + /* copy exception table */ + ZwQueryInformationThread(NtCurrentThread(), ThreadMemoryPriority, &tbi, sizeof tbi, 0); + tib = (PNT_TIB)tbi.TebBaseAddress; + ZwQueryInformationThread(hThread, ThreadMemoryPriority, &tbi, sizeof tbi, 0); + ZwWriteVirtualMemory(hProcess, tbi.TebBaseAddress, &tib->ExceptionList, sizeof tib->ExceptionList, 0); + + /* start (resume really) the child */ + ZwResumeThread(hThread, 0); + + /* clean up */ + ZwClose(hThread); + ZwClose(hProcess); + + /* exit with child's pid */ + return (int)cid.UniqueProcess; +} +/*--------------------------------------------------------------------------*/ diff --git a/modules/parallel/src/c/forkWindows.h b/modules/parallel/src/c/forkWindows.h new file mode 100755 index 000000000..ab27e9afb --- /dev/null +++ b/modules/parallel/src/c/forkWindows.h @@ -0,0 +1,33 @@ +/* +* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +* Copyright (C) DIGITEO - 2010 - Allan CORNET +* +* This file must be used under the terms of the CeCILL. +* This source file is licensed as described in the file COPYING, which +* you should have received as part of this distribution. The terms +* are also available at +* http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +* +*/ +/*--------------------------------------------------------------------------*/ +#ifndef __FORK_WINDOWS_H__ +#define __FORK_WINDOWS_H__ + +#include "BOOL.h" + +/* http://technet.microsoft.com/en-us/library/bb497007.aspx */ +/* http://undocumented.ntinternals.net/ */ + +/** +* simulate fork on Windows +*/ +int fork(void); + +/** +* check if symbols to simulate fork are present +* and load these symbols +*/ +BOOL haveLoadedFunctionsForFork(void); + +#endif /* __FORK_WINDOWS_H__ */ +/*--------------------------------------------------------------------------*/ diff --git a/modules/parallel/src/c/parallel.rc b/modules/parallel/src/c/parallel.rc new file mode 100755 index 000000000..50e8f24dd --- /dev/null +++ b/modules/parallel/src/c/parallel.rc @@ -0,0 +1,96 @@ +// Microsoft Visual C++ generated resource script. +// + + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// French (France) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) +#ifdef _WIN32 +LANGUAGE LANG_FRENCH, SUBLANG_FRENCH +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 5,5,2,0 + PRODUCTVERSION 5,5,2,0 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040c04b0" + BEGIN + VALUE "FileDescription", "parallel module" + VALUE "FileVersion", "1, 0, 0, 0" + VALUE "InternalName", "parallel module" + VALUE "LegalCopyright", "Copyright (C) 2017" + VALUE "OriginalFilename", "parallel.dll" + VALUE "ProductName", " parallel" + VALUE "ProductVersion", "1, 0, 0, 0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x40c, 1200 + END +END + +#endif // French (France) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/modules/parallel/src/c/parallel.vcxproj b/modules/parallel/src/c/parallel.vcxproj new file mode 100755 index 000000000..cdafb33f0 --- /dev/null +++ b/modules/parallel/src/c/parallel.vcxproj @@ -0,0 +1,271 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{56A2E2F3-26CF-45D5-BE7A-534C39CD7003}</ProjectGuid> + <RootNamespace>parallel</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <WholeProgramOptimization>false</WholeProgramOptimization> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <WholeProgramOptimization>false</WholeProgramOptimization> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)bin\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)$(Configuration)\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)bin\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)$(Configuration)\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)bin\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)$(Configuration)\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)bin\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)$(Configuration)\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>.;../../includes;../../src/cpp;../../../dynamic_link/includes;../../../parameters/includes;../../../jvm/includes;../../../output_stream/includes;../../../core/includes;../../../api_scilab/includes;../../../windows_tools/src/c/scilab_windows;../../../parallel/includes;../../../localization/includes;../../../windows_tools/includes;../../../../libs/intl;../../../../java/jdk/include;../../../../java/jdk/include/win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;FORDLL;_DEBUG;_WINDOWS;_USRDLL;PARALLEL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <OpenMPSupport>true</OpenMPSupport> + <WarningLevel>Level3</WarningLevel> + <DisableSpecificWarnings>4800;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <PreLinkEvent> + <Message>Make dependencies</Message> + <Command>lib /DEF:"$(ProjectDir)core_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platform) /OUT:"$(ProjectDir)core.lib" 1>NUL 2>NUL +</Command> + </PreLinkEvent> + <Link> + <AdditionalDependencies>core.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(SolutionDir)bin\$(ProjectName).dll</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <ImportLibrary>$(SolutionDir)bin\$(ProjectName).lib</ImportLibrary> + <TargetMachine>MachineX86</TargetMachine> + <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + </Link> + <PostBuildEvent> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Midl> + <TargetEnvironment>X64</TargetEnvironment> + </Midl> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>.;../../includes;../../src/cpp;../../../dynamic_link/includes;../../../parameters/includes;../../../jvm/includes;../../../output_stream/includes;../../../core/includes;../../../api_scilab/includes;../../../windows_tools/src/c/scilab_windows;../../../parallel/includes;../../../localization/includes;../../../windows_tools/includes;../../../../libs/intl;../../../../java/jdk/include;../../../../java/jdk/include/win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;FORDLL;_DEBUG;_WINDOWS;_USRDLL;PARALLEL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <OpenMPSupport>true</OpenMPSupport> + <WarningLevel>Level3</WarningLevel> + <DisableSpecificWarnings>4800;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <PreLinkEvent> + <Message>Make dependencies</Message> + <Command>lib /DEF:"$(ProjectDir)core_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platform) /OUT:"$(ProjectDir)core.lib" 1>NUL 2>NUL +</Command> + </PreLinkEvent> + <Link> + <AdditionalDependencies>core.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(SolutionDir)bin\$(ProjectName).dll</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <ImportLibrary>$(SolutionDir)bin\$(ProjectName).lib</ImportLibrary> + <TargetMachine>MachineX64</TargetMachine> + <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + </Link> + <PostBuildEvent> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <WholeProgramOptimization>false</WholeProgramOptimization> + <AdditionalIncludeDirectories>.;../../includes;../../src/cpp;../../../dynamic_link/includes;../../../parameters/includes;../../../jvm/includes;../../../output_stream/includes;../../../core/includes;../../../api_scilab/includes;../../../windows_tools/src/c/scilab_windows;../../../parallel/includes;../../../localization/includes;../../../windows_tools/includes;../../../../libs/intl;../../../../java/jdk/include;../../../../java/jdk/include/win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;FORDLL;NDEBUG;_WINDOWS;_USRDLL;PARALLEL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <OpenMPSupport>true</OpenMPSupport> + <WarningLevel>Level3</WarningLevel> + <DisableSpecificWarnings>4800;%(DisableSpecificWarnings)</DisableSpecificWarnings> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + </ClCompile> + <PreLinkEvent> + <Message>Make dependencies</Message> + <Command>lib /DEF:"$(ProjectDir)core_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platform) /OUT:"$(ProjectDir)core.lib" 1>NUL 2>NUL +</Command> + </PreLinkEvent> + <Link> + <AdditionalDependencies>core.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(SolutionDir)bin\$(ProjectName).dll</OutputFile> + <GenerateDebugInformation>false</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <ImportLibrary>$(SolutionDir)bin\$(ProjectName).lib</ImportLibrary> + <TargetMachine>MachineX86</TargetMachine> + <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + </Link> + <PostBuildEvent> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Midl> + <TargetEnvironment>X64</TargetEnvironment> + </Midl> + <ClCompile> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <WholeProgramOptimization>false</WholeProgramOptimization> + <AdditionalIncludeDirectories>.;../../includes;../../src/cpp;../../../dynamic_link/includes;../../../parameters/includes;../../../jvm/includes;../../../output_stream/includes;../../../core/includes;../../../api_scilab/includes;../../../windows_tools/src/c/scilab_windows;../../../parallel/includes;../../../localization/includes;../../../windows_tools/includes;../../../../libs/intl;../../../../java/jdk/include;../../../../java/jdk/include/win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;FORDLL;NDEBUG;_WINDOWS;_USRDLL;PARALLEL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <OpenMPSupport>true</OpenMPSupport> + <WarningLevel>Level3</WarningLevel> + <DisableSpecificWarnings>4800;%(DisableSpecificWarnings)</DisableSpecificWarnings> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + </ClCompile> + <PreLinkEvent> + <Message>Make dependencies</Message> + <Command>lib /DEF:"$(ProjectDir)core_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platform) /OUT:"$(ProjectDir)core.lib" 1>NUL 2>NUL +</Command> + </PreLinkEvent> + <Link> + <AdditionalDependencies>core.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(SolutionDir)bin\$(ProjectName).dll</OutputFile> + <GenerateDebugInformation>false</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <ImportLibrary>$(SolutionDir)bin\$(ProjectName).lib</ImportLibrary> + <TargetMachine>MachineX64</TargetMachine> + <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + </Link> + <PostBuildEvent> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="DllmainParallel.c" /> + <ClCompile Include="forkWindows.c" /> + <ClCompile Include="..\..\sci_gateway\c\gw_parallel.c" /> + <ClCompile Include="..\..\sci_gateway\c\sci_parallel_concurrency.c" /> + <ClCompile Include="..\..\sci_gateway\cpp\sci_parallel_run.cpp"> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_SCL_SECURE_NO_WARNINGS ;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4800;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_SCL_SECURE_NO_WARNINGS ;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">4800;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_SCL_SECURE_NO_WARNINGS ;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">4800;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_SCL_SECURE_NO_WARNINGS ;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Release|x64'">4800;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\includes\concurrency.h" /> + <ClInclude Include="..\..\includes\dynlib_parallel.h" /> + <ClInclude Include="forkWindows.h" /> + <ClInclude Include="..\..\includes\gw_parallel.h" /> + <ClInclude Include="..\cpp\parallel_run.hxx" /> + <ClInclude Include="semWindows.h" /> + </ItemGroup> + <ItemGroup> + <None Include="..\..\locales\parallel.pot" /> + <None Include="core_import.def" /> + <None Include="..\..\Makefile.am" /> + <None Include="..\..\parallel.iss" /> + <None Include="..\..\sci_gateway\parallel_gateway.xml" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="parallel.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\..\..\Visual-Studio-settings\rename-vc-files\rename-vc-files.vcxproj"> + <Project>{dd8a0506-8d31-4cf8-856a-c10ece9c13a4}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\api_scilab\api_scilab.vcxproj"> + <Project>{43c5bab1-1dca-4743-a183-77e0d42fe7d0}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\dynamic_link\src\c\dynamic_link.vcxproj"> + <Project>{eab6c580-22b3-4359-ba1d-dd7499a96163}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\output_stream\src\c\output_stream.vcxproj"> + <Project>{a5911cd7-f8e8-440c-a23e-4843a0636f3a}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\parameters\parameters.vcxproj"> + <Project>{a09e8584-0713-48a5-97ba-aced0f3728f8}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="..\..\..\windows_tools\src\c\scilab_windows\scilab_windows.vcxproj"> + <Project>{8028f371-6a94-4a26-8804-6e7f05f1d1aa}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/modules/parallel/src/c/parallel.vcxproj.filters b/modules/parallel/src/c/parallel.vcxproj.filters new file mode 100755 index 000000000..c8bb9c0b6 --- /dev/null +++ b/modules/parallel/src/c/parallel.vcxproj.filters @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{c4c91712-1b98-4aa6-b7c7-df5aaf6b9f03}</UniqueIdentifier> + <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{cbe6abd4-dcb2-4b31-b1f1-d43e9a72d411}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl</Extensions> + </Filter> + <Filter Include="localization"> + <UniqueIdentifier>{f274011b-952b-4933-ac2c-803e38acb313}</UniqueIdentifier> + </Filter> + <Filter Include="Swig Files"> + <UniqueIdentifier>{8be3461d-09ca-4983-9f34-5ef03a5eb5c5}</UniqueIdentifier> + </Filter> + <Filter Include="Libraries Dependencies"> + <UniqueIdentifier>{d5fa84c0-6405-4733-8847-ed1db94a09ce}</UniqueIdentifier> + </Filter> + <Filter Include="Libraries Dependencies\Imports"> + <UniqueIdentifier>{86592303-2128-45bb-94cb-5ad8bad15686}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{540a0e24-61c1-48a5-b6a1-f5f2c90f567a}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="DllmainParallel.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="forkWindows.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\sci_gateway\c\gw_parallel.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\sci_gateway\c\sci_parallel_concurrency.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\sci_gateway\cpp\sci_parallel_run.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\includes\concurrency.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\includes\dynlib_parallel.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="forkWindows.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\includes\gw_parallel.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\cpp\parallel_run.hxx"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="semWindows.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <None Include="core_import.def"> + <Filter>Libraries Dependencies\Imports</Filter> + </None> + <None Include="..\..\Makefile.am" /> + <None Include="..\..\parallel.iss" /> + <None Include="..\..\sci_gateway\parallel_gateway.xml" /> + <None Include="..\..\locales\parallel.pot"> + <Filter>localization</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="parallel.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/modules/parallel/src/c/semWindows.h b/modules/parallel/src/c/semWindows.h new file mode 100755 index 000000000..9f2236f29 --- /dev/null +++ b/modules/parallel/src/c/semWindows.h @@ -0,0 +1,32 @@ +/* +* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +* Copyright (C) DIGITEO - 2010 - Allan CORNET +* +* This file must be used under the terms of the CeCILL. +* This source file is licensed as described in the file COPYING, which +* you should have received as part of this distribution. The terms +* are also available at +* http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +* +*/ +/*--------------------------------------------------------------------------*/ +#ifndef __SEMWINDOWS_H__ +#define __SEMWINDOWS_H__ + +#include <Windows.h> + +/* emulates unix semaphore on windows */ + +#define sem_t HANDLE + +/* http://msdn.microsoft.com/en-us/library/ms682438(VS.85).aspx */ +#define sem_init(__sem, __0, __1) *__sem = CreateSemaphore(NULL, 0, 100, NULL) + +/* http://msdn.microsoft.com/en-us/library/ms687032(VS.85).aspx */ +#define sem_wait(__sem) WaitForSingleObject(*__sem, INFINITE) + +/* http://msdn.microsoft.com/en-us/library/ms685071(VS.85).aspx */ +#define sem_post(__sem) ReleaseSemaphore(*__sem, 1, NULL) + +#endif /* __SEMWINDOWS_H__ */ +/*--------------------------------------------------------------------------*/ diff --git a/modules/parallel/src/cpp/parallel_run.hxx b/modules/parallel/src/cpp/parallel_run.hxx new file mode 100755 index 000000000..b22251f74 --- /dev/null +++ b/modules/parallel/src/cpp/parallel_run.hxx @@ -0,0 +1,401 @@ +/* +* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +* Copyright (C) 2010 - DIGITEO - Bernard HUGUENEY +* +* This file must be used under the terms of the CeCILL. +* This source file is licensed as described in the file COPYING, which +* you should have received as part of this distribution. The terms +* are also available at +* http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +* +*/ + +#ifndef PARALLEL_RUN_HXX +#define PARALLEL_RUN_HXX + +#include <algorithm> +#include <vector> +#include <iterator> +#include <iostream> +#include <algorithm> +#include <cstdlib> +#include <cstring> +#include <omp.h> + +extern "C" +{ +#include "scilabmode.h" +} + +#ifndef _MSC_VER + +#ifndef MAP_ANONYMOUS +# define MAP_ANONYMOUS MAP_ANON +#endif + +#include <sys/mman.h> +#include <semaphore.h> +#include <pthread.h> +#include <signal.h> +#include <algorithm> +#include <unistd.h> + +using std::min; +using std::max; +#else +#include <windows.h> +extern "C" +{ +#include "forkWindows.h" +#include "mmapWindows.h" +#include "semWindows.h" +}; +#endif + +/* +implementation notes: +due to alignment issues, we have to use lhs differents shared memory buffers +we avoif busywaiting (bad for cpu time) or sleeping (bad for wallclock time) thanks to semaphores in shared memopry +*/ + + +namespace +{ +/* +* allocates shared memory for s elements of type T. (anonymous, not mapped to a file) +* +* @param T type to alloc +* @param s nb of elements to alloc mem, defaults to 1. +*/ +template<typename T> T* allocSharedMem(std::size_t s = 1) +{ + return static_cast<T*>(mmap(0, sizeof(T) * s, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0)); +} +void freeSharedMem(void* ptr, std::size_t s = 1) +{ + munmap(ptr, s); +} +struct PortableSemaphore +{ + explicit PortableSemaphore (unsigned int init): ptr(allocSharedMem<sem_t>()) + { + sem_init(ptr, 1, init); + } + + void post() + { + sem_post(ptr); + } + void wait() + { + sem_wait(ptr); + } + ~PortableSemaphore() + { + munmap(ptr, sizeof(sem_t)); + } + + sem_t* ptr; +}; + + +struct PortableSignalInhibiter +{ + PortableSignalInhibiter() + { +#ifndef _MSC_VER + struct sigaction reapchildren; + std::memset( &reapchildren, 0, sizeof reapchildren ); + reapchildren.sa_flags = SA_NOCLDWAIT; + sigaction( SIGCHLD, &reapchildren, &backup_sigaction ); +#else +#endif + } + ~PortableSignalInhibiter() + { +#ifndef _MSC_VER + sigaction(SIGCHLD, &backup_sigaction, 0 );/* restore of sigaction */ +#else +#endif + } +#ifndef _MSC_VER + struct sigaction backup_sigaction; +#else +#endif +}; +/* +* Handles scheduling. Could be done in parallel_wrapper, but it would a very long applyWithProcesses() member function +* breaking it would involve adding many member variables in the wrapper, so I chose an utility class with friend access to a parallel_wrapper +* taken by ref. +* +* The trick is to exchange the res[] ptr with ptrs to some shared memory so that callF() from each process fills the same shared result buffer. +* When all is done, we copy the result to the original (not shared) result buffer. Apart from the result buffer, we also share a std::size_t *todo +* poiting to the next index to compute. +* +* We use two cross process synch semaphores : +* 1°) todo_protect to protect access to the *todo shared value +* 2°) out_of_work to count how many workers have finished their work. Master process waits until nb_process have done their work. +* +*/ + +#ifndef _MSC_VER +#define __HAVE_FORK__ 1 +#endif + +#ifdef __HAVE_FORK__ +template< typename ParallelWrapper> struct scheduler +{ + typedef std::pair<std::size_t, std::size_t> workshare_t; + + /* + * constructs the scheduler, allocating the ressources (shared memory) and semaphores + * @param wrapper the parallel wrapper launching the computations + * @param nb_proc number of processes to use (spawns nb_proc-1 processes) + * @param dyn if scheduling is dynamic or static + * @param chunk_s chunk size. Only useful for dynamic sheduling as static is always faster with max chunk size for processes. + * /!\ changes w.res[] to point to shared memory buffer + */ + scheduler( ParallelWrapper& wrapper, std::size_t nb_proc, bool dyn, std::size_t chunk_s) + : w(wrapper), nb_process(nb_proc), dynamic(dyn), chunk_size(chunk_s), todo(0) + , out_of_work(0) + , todo_protect(1) + , backup_res(wrapper.lhs) + { + for (std::size_t i(0); i != w.lhs; ++i) + { + backup_res[i] = w.res[i]; + const_cast<char**>(w.res)[i] = allocSharedMem<char>(w.n * w.res_size[i]); + } + todo = allocSharedMem<std::size_t>(); + *todo = 0; + } + + /* + * performs concurrent calls from w. (with w.f()) and copy results to the original w.res[] locations + * but does not restore w.res[} (this is done in destructor. + */ + void operator()() + { + PortableSignalInhibiter guard; /* disable waiting notification from child death to avoid zombies */ + std::vector<workshare_t> init_ws(nb_process); + for (std::size_t i(0); i != nb_process; ++i) /* we precompute shares so that we don't have to synch */ + { + init_ws[i] = initialWork(i); + } + std::size_t p; + for (p = 1; p != nb_process; ++p) + { + if (!fork()) /* child process goes to work at once */ + { + setScilabMode(SCILAB_NWNI); + break; + }/* parent process continues to spawn children */ + } + if (p == nb_process) + { + p = 0; + } + w.prologue(p); + for (workshare_t ws(init_ws[p]); ws.first != ws.second; ws = getWork()) + { + for (std::size_t i(ws.first); i != ws.second; ++i) + { + w.callF(i);/* callF() is performed on our shared mem as res[] */ + } + } + out_of_work.post(); + w.epilogue(p); + if (p) + { + exit(EXIT_SUCCESS); // does not call destructor which is good :) + } + for (std::size_t i(0); i != nb_process; ++i) /* wait for all workers to finish */ + { + out_of_work.wait(); + } + for (std::size_t i(0); i != w.lhs; ++i) /* copy results into the original res[] memory */ + { + std::memcpy(backup_res[i], w.res[i], w.res_size[i]*w.n); + } + }/* guard destructor restores the signals */ + /* destroy/ free semaphores/shared memory, and restores original w.res[] values. */ + ~scheduler() + { + for (std::size_t j(0); j != w.lhs; ++j) + { + freeSharedMem(w.res[j], w.n * w.res_size[j]); + const_cast<char**>(w.res)[j] = backup_res[j]; + } + freeSharedMem(todo, sizeof(std::size_t)); + } +private: + /* compute initial workshares. no need to synch because we did not fork() yet + * @param p process id from 0(parent) -> nb_process-1 + */ + workshare_t initialWork( std::size_t p) const + { + std::size_t old_todo(*todo); + // std::cerr<<"*todo="<<*todo<<" dynamic="<<dynamic<<" nb_process="<<nb_process<<" p="<<p<<std::endl; + *todo = min(w.n, *todo + (dynamic ? chunk_size : (w.n - *todo) / (nb_process - p))); + // std::cerr<<"AFTER : *todo="<<*todo<<" dynamic="<<dynamic<<" nb_process="<<nb_process<<" p="<<p<<std::endl; + return workshare_t(old_todo, *todo); + } + /* computes next workshare with protected access to shared *todo value */ + workshare_t getWork() + { + workshare_t res; + todo_protect.wait(); + res.first = *todo; + if (*todo != w.n) + { + res.second = min(w.n, *todo + chunk_size); // no need to handle static scheduling because the last initialWork then set todo=w.n + *todo = res.second; + } + else + { + res.second = w.n; + } + todo_protect.post(); + return res; + } + ParallelWrapper& w; + std::size_t nb_process; + bool dynamic; + std::size_t chunk_size; + std::size_t* todo; + PortableSemaphore out_of_work, todo_protect; + std::vector<char*> backup_res; +}; +#else +template< typename ParallelWrapper> struct scheduler +{ + scheduler( ParallelWrapper& wrapper, std::size_t nb_proc, bool dyn, std::size_t chunk_s) + : w(wrapper) + { + } + void operator()() + { + for (std::size_t i(0); i != w.n; ++i) + { + w.callF(i); + } + } + ParallelWrapper& w; +}; +#endif +template<typename F, typename G> +struct parallel_wrapper +{ + parallel_wrapper(char const* const* const a, std::size_t const* a_s, std::size_t const* a_n, std::size_t const the_rhs, std::size_t nb_tasks, char * const* const r, std::size_t const* r_s, std::size_t const the_lhs, F the_f, G p, G e) + : args(a), args_size(a_s), args_nb(a_n), rhs(the_rhs), n(nb_tasks), res(r), res_size(r_s), lhs(the_lhs), f(the_f), prologue(p), epilogue(e) + { + } + + /* we define a functor. Calling it lanches the parallel processing of args, either with threads of processes(default). + the nb of wokers (threads or processes) can also be specified (default is implementation defined usually nb of cores). + TODO : enable specification of near / far / all (must, must not, can share L2 cache), at least for threads. + so first arge might not stay boolean (we can add an overload)*/ + F operator()( bool with_threads = false, std::size_t nb_workers = 0, bool dynamic_scheduling = true, int chunk_size = 1) + { + return with_threads + ? applyWithThreads(nb_workers, dynamic_scheduling, chunk_size) + : applyWithProcesses(nb_workers, dynamic_scheduling, chunk_size); + } +private: + friend struct scheduler<parallel_wrapper>; + + /* Launch concurrent calls to f using OpenMP threads. OpenMP semantics for the parameters. + * @param nb_threads number of threads to use + * @param dynamic_scheduling if scheduling is dynamic or static + * @param chunk_size chunk size. + */ + F applyWithThreads(std::size_t nb_threads, bool dynamic_scheduling, int chunk_size) + { + signed int i; + nb_threads = min(nb_threads, n); + if (nb_threads) + { + omp_set_num_threads(static_cast<int>(nb_threads)); + } + if (dynamic_scheduling) + { +#ifdef _OPENMP + #pragma omp parallel for private(i) schedule(dynamic, chunk_size) +#endif + for (i = 0; i < (signed int)n; ++i) + { + callF(i); + } + } + else + { +#ifdef _OPENMP + #pragma omp parallel for private(i) schedule(static, chunk_size) +#endif + for (i = 0; i < (signed int)n; ++i) + { + callF(i); + } + + } + return f; + } + + /* Launch concurrent calls to f using fork()ed processes. See scheduler<> fr details + * @param nb_processes number of processes to use + * @param dynamic_scheduling if scheduling is dynamic or static + * @param chunk_size chunk size. + */ + F applyWithProcesses(std::size_t nb_process, bool dynamic_scheduling, std::size_t chunk_size) + { + nb_process = min( (nb_process ? nb_process : omp_get_num_procs()), n); + scheduler<parallel_wrapper> s(*this, nb_process, dynamic_scheduling, chunk_size ); + s(); + return f; + } + /* Perform i^th call to f, ajusting arguments and results ptrs from args[] and res[] + * @param i args and reults index. + */ + void callF(std::size_t const i) + { + + std::vector<char const *> local_args(rhs); + for (std::size_t j(0); j != rhs; ++j) + { + local_args[j] = args[j] + (i % (*(args_nb + j))) * (*(args_size + j)); /*(i%(*(args_nb+j))) because all args are not required to have same nb of elts*/ + } + std::vector<char *> local_res(lhs); + for (std::size_t j(0); j != lhs; ++j) + { + local_res[j] = res[j] + i * (*(res_size + j)); // all res are required to have n elts + } + f(&local_args[0], &local_res[0]); + + } + char const* const* const args; /* ptrs to the rhs args */ + std::size_t const* args_size; /* sizeof each rhs */ + std::size_t const* args_nb;/* nb of given values for each arg, in 1...n */ + std::size_t const rhs; /* nb of rhs for f */ + std::size_t n; /* nb of calls to perform */ + char* const* const res; /* ptr to the lhs results */ + std::size_t const* res_size; /* sizeof each lhs */ + std::size_t const lhs;/* nb of lhs for f */ + /* no res_nb because we must have room for n vaules for each result */ + F f;/* function to call */ + G prologue, epilogue; /* function to call when launching/ terminating a worker process */ +}; + +} + + +/* +* make a parallel wrapper, just calls the constructor : is used mainly not to have to type the complete templated name of the wrapper type. +* We can then directly call the parallel_wrapper operator() to lanch the parallel processing. +* @param +*/ +template<typename ArgsItIt, typename ArgsSizeIt, typename ArgsNbIt, typename Sz1, typename Sz2, typename ResItIt, typename ResSizeIt, typename Sz3, typename F, typename G> parallel_wrapper<F, G> +make_parallel_wrapper(ArgsItIt args, ArgsSizeIt args_size, ArgsNbIt args_nb, Sz1 rhs, Sz2 n, ResItIt res, ResSizeIt res_size, Sz3 lhs, F f, G prologue, G epilogue) +{ + return parallel_wrapper<F, G>(args, args_size, args_nb, rhs, n, res, res_size, lhs, f, prologue, epilogue); +} +#endif diff --git a/modules/parallel/src/noparallel/.deps/libsciparallel_la-noparallel.Plo b/modules/parallel/src/noparallel/.deps/libsciparallel_la-noparallel.Plo new file mode 100755 index 000000000..9ce06a81e --- /dev/null +++ b/modules/parallel/src/noparallel/.deps/libsciparallel_la-noparallel.Plo @@ -0,0 +1 @@ +# dummy diff --git a/modules/parallel/src/noparallel/noparallel.c b/modules/parallel/src/noparallel/noparallel.c new file mode 100755 index 000000000..0d2e21b2e --- /dev/null +++ b/modules/parallel/src/noparallel/noparallel.c @@ -0,0 +1,37 @@ +/* +* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +* Copyright (C) 2009 - DIGITEO - Sylvestre LEDRU +* Copyright (C) 2010 - DIGITEO - Bernard HUGUENEY +* Copyright (C) 2010 - DIGITEO - Allan CORNET +* +* This file must be used under the terms of the CeCILL. +* This source file is licensed as described in the file COPYING, which +* you should have received as part of this distribution. The terms +* are also available at +* http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +* +*/ +/*--------------------------------------------------------------------------*/ +#include "noparallel.h" +#include "concurrency.h" +#include "Scierror.h" +#include "localization.h" +/*--------------------------------------------------------------------------*/ +int gw_parallel(void) +{ + Scierror(999, _("%s: %s module is not installed.\n"), "Scilab", "parallel"); + return 0; +} +/*--------------------------------------------------------------------------*/ +int parallelConcurrency(void) +{ + return 0; +} +/*--------------------------------------------------------------------------*/ +int parallelForbidden(char const* fname) +{ + /* never called then do nothing */ + return 0; +} +/*--------------------------------------------------------------------------*/ + diff --git a/modules/parallel/src/noparallel/noparallel.h b/modules/parallel/src/noparallel/noparallel.h new file mode 100755 index 000000000..e02f5573c --- /dev/null +++ b/modules/parallel/src/noparallel/noparallel.h @@ -0,0 +1,19 @@ +/* +* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +* Copyright (C) 2010 - DIGITEO - Sylvestre LEDRU +* +* This file must be used under the terms of the CeCILL. +* This source file is licensed as described in the file COPYING, which +* you should have received as part of this distribution. The terms +* are also available at +* http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt +* +*/ +/*--------------------------------------------------------------------------*/ +/** +* This function is a wrapper / fake when Scilab is compiled without parallel +* +* @return 0 +*/ +int gw_parallel(void); +/*--------------------------------------------------------------------------*/ |