I'm writing a custom task scheduler, and I would like to know if there is any way of setting the processor affinity for the current thread on Mono (running on Linux).
For the .NET runtime running on Windows, I've managed to get this to work by following Lenard Gunda's Running .NET threads on selected processor cores article; however, his approach fails on Mono (and Linux) because:
It requires a P/Invoke call to GetCurrentThreadId in the Kernel32.dll library.
The Process.Threads property currently returns an empty collection on Mono.
Does anyone please have a workaround for this?
lupus's answer was on the right track, but it took me some further research to get this implemented (such as the P/Invoke signature for sched_setaffinity and the resolution of libc.so.6). Here's the working code (excluding error-handling) in case anyone needs it:
[DllImport("libc.so.6", SetLastError=true)]
private static extern int sched_setaffinity(int pid, IntPtr cpusetsize,
ref ulong cpuset);
private static void SetAffinity(int processorID)
{
ulong processorMask = 1UL << processorID;
sched_setaffinity(0, new IntPtr(sizeof(ulong)), ref processorMask);
}
Edit: The above signature worked fine for my experiments, but refer to David Heffernan's answer (under my other question) for a suggested correction.
Note that you don't really have control of when a task gets run, that is up to the kernel.
Anyway, on Linux you will need to P/Invoke to sched_setaffinity() to bind a thread to a specific cpu.
See man sched_setaffinity for the interface.
Related
I am calling some unmanaged C functions (in an external dll) from C#. I have 2 different methods to do so, and I am not sure of the differences between the 2 (other than the amount of code)
Method #1
[DllImport("PComm32.dll",CallingConvention=CallingConvention.StdCall, EntryPoint ="PmacSelect")]
public static extern int PmacSelect(IntPtr intPtr);
int device = PmacSelect(IntPrt.Zero);
Method #2
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int PmacSelect(IntPrt intptr);
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);
public PmacSelect PmacSelectFunction;
private IntPtr pDll = LoadLibrary("PComm32");
IntPtr pAddressOfFunctionToCall = GetProcAddress(pDll, "PmacSelect"); //find the function in the loaded pcomm32 dll
PmacSelectFunction = (PmacSelect)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall,type(PmacSelect));
int device = PmacSelectFunction(IntPrt.Zero);
Both methods work, and call the PmacSelect Function located in the PComm32.dll file.
My question is what are the functional differences between the 2 methods?
Method #1 must rely on windows managing the DLL in the background for me as needed? Could windows load and unload the dll without my knowledge? I dont really care if it does, as long as it automatically loads is when I call a function in the dll.
Method #2 The DLL is loaded explicitly when I call LoadLibrary. Does the library remain in memory until I free it?
I'll give you answers, but you seem to already understand what is going on.
My question is what are the functional differences between the 2 methods?
There is no functional difference between the two methods. In the first method (which you should use if at all possible), the DotNet framework is handling everything for you. Under the hood, it is doing exactly what you're doing manually: Calling LoadLibrary, GetProcAddress, and at some point, FreeLibrary. Those are the steps to calling a function in a DLL.
Method #1 must rely on windows managing the DLL in the background for me as needed? Could windows load and unload the dll without my knowledge?
Yes, that's exactly right, although I wouldn't say it is without your knowledge. You are telling it to do that when you write [DllImport("PComm32.dll"...)].
Method #2 The DLL is loaded explicitly when I call LoadLibrary. Does the library remain in memory until I free it?
Again, yes, you understand what is happening.
Since you seem to answered your own questions and I've merely confirmed your answers, let you give you the reasons why you should (almost) always use #1:
It works just as well
It is easier to use and easier to read / maintain
There is no value in doing it the hard way (#2)
I can only think of one reason that you would ever want to bother with the second method: If you needed to be able to replace the DLL, on the fly, with a newer version or something, without quitting your application, then you would want the fine grain control over when the DLL is unloaded (so that the file can be replaced).
That is unlikely to be a requirement except in very special cases.
Bottom Line: If you're using C#, you accept the fact that you are giving control to the framework in exchange for being able to focus on the work, and not worry about things like DLL or memory management. The DotNet framework is your friend, let it do the heavy lifting for you, and focus your efforts on the rest of the code.
When you pinvoke with DllImport, LoadLibrary ends up getting called for you, and the exported function is (hopefully) found in the EAT. Basically in your second example you're doing the same thing as a typedef + GetModuleHandle & GetProcAddress for c/c++.
The only reason I could think to use your second method, would be if the DllMain of your unmanaged module executes code upon attachment to a process, which you might depending on the scenario want to have specific timing control over when that module gets loaded into your process.
In my application, WinDbg gets launched and I wondered if there was any way of sending certain commands through to WinDbg (for example sending the letter k (to show the callstack) from the C# application?
I've read around some use of user32.dll which has functions that can help with this but I am unclear of how to proceed and include it in my app.
Any help would be greatly appreciated.
Steve
If you want to fully control the debug engine, then you should just host it inside your C# application using the exposed COM interfaces.
You can find sample code for automating the debug engine in the WinDbg installation directory (e.g. C:\Program Files (x86)\Windows Kits\8.1\Debuggers\x64\sdk\samples). This blog post shows how to get a stack trace using the API (in C), so you don't have to parse the output after issuing a k command.
The hardest part is just finding/creating all the IDebug* [ComImport] interfaces in C# for all the exposed objects. But once you have them, you would do something like this:
internal static class WinDbgBase
{
// STDAPI DebugCreate(__in REFIID InterfaceId, __out PVOID* Interface);
[DllImport("dbgeng.dll", EntryPoint = "DebugCreate", CallingConvention = CallingConvention.StdCall)]
public static extern int DebugCreate([In] ref System.Guid InterfaceId, ref System.IntPtr Interface);
}
Guid uuidof_IDebugClient4 = new Guid("{ca83c3de-5089-4cf8-93c8-d892387f2a5e}");
IntPtr pObj = IntPtr.Zero;
int hr = WinDbgBase.DebugCreate(ref uuidof_IDebugClient4, ref pObj);
IDebugClient4 _client = (IDebugClient4)Marshal.GetTypedObjectForIUnknown(pObj, typeof(IDebugClient4));
// QueryInterface the other objects
IDebugControl4 _control = (IDebugControl4)_client;
_client.AttachProcess(0, ProcessId, DEBUG_ATTACH.DEBUG_ATTACH_DEFAULT);
_control.WaitForEvent(DEBUG_WAIT.DEBUG_WAIT_DEFAULT, Win32.INFINITE);
...
If you are dealing with managed targets, then it is even possible to load up the SOS extension, get the managed stack (as previously mentioned) and then merge it with the native stack trace so that you can show the full stack with all the native to/from managed transitions.
References
- Listing of all Debugger COM objects
No need to send keystrokes. There's a more reliable way: see the WinDbg help for .ocommand. It works by sending commands through OutputDebugString, which is Debug.WriteLine() (Debug build) or Trace.WriteLine() (Release build) in .NET.
As you also start the debugger by yourself, you probably want to execute .ocommand immediately at startup which you can do by adding the -c command line switch:
windbg.exe -p <PID> -c ".ocommand <Magic>;g"
This approach is a quick any dirty way. #joshpoley`s answer is the cleaner way if you want a long term stable solution.
Note that for .NET the native callstack k might not be what you want. Try !clrstack or !dumpstack of the SOS extension (which you can load using .loadby sos clr or .loadby sos mscorwks depending on your .NET version).
while I learn about p/invoke I could see some noticeable performance gains compared to using .net methods that's because it is querying the information via systems dlls
For instance by importing the dll in this code
[DllImport("psapi.dll", SetLastError = true)]
static extern bool GetProcessMemoryInfo(IntPtr hProcess, out PROCESS_MEMORY_COUNTERS Memcounters, int size);
I could get access to information regarding the process in question so I could question all I need to know about it's memory usage.
But as I could notes in that link The Win32_PerfFormattedData_PerfProc_Process and the Win32_PerfRawData_PerfProc_Process it seems that I could access a class that is not used by P/invoke and query very specific info.
uint64 IODataOperationsPerSec;
uint64 IOOtherOperationsPerSec;
uint64 IOReadBytesPerSec;
uint64 IOReadOperationsPerSec;
uint64 IOWriteBytesPerSec;
uint64 IOWriteOperationsPerSec;
uint64 IODataBytesPerSec;
uint64 IOOtherBytesPerSec;
uint32 PageFaultsPerSec;
uint64 PageFileBytes;
uint64 PageFileBytesPeak;
as you could see, there is also separated functions for both 32bit / 64bit processes
So here I could know for sure, that I am getting exactly what I need to query and then I noticed that I could get all I need through that class, which I could find in .net an equivalent one I guess (wmi) but I was searching for exactly that, a class that for 1, I will surely know that I am querying correctly 32bit tasks and 64bit tasks and 2 the counters are all together in one class, I/O , CPU Time, Memory usage and the performance issue that it is quite a notisble performance gain compared to using the .net approach .
So the question is:
how do I get access to that class via using a method like P/invoke and not own .net classes ?
And actually the most interesting link I have found regarding counters for managed .net in details is This Link , I guess that is the equivalent to the win32 links above.
Last time I worked with P/Invoke, it was much easier to accomplish in a managed C++ library, and then import that into my c# app. If you know C++, you will save yourself a lot of trouble when it comes to those kinds of operations.
How do I unload a DLL which has been loaded using DllImport in C#?
The most reliable way to unload an unmanaged DLL from a process that got loaded by a [DllImport] pinvoke declaration is to load it yourself, again, by pinvoking LoadLibrary(). That gives you a reliable handle to the DLL and works correctly even if the module name of the DLL is ambiguous. It doesn't have any affect at runtime, other than the Windows loader increasing the internal reference count on the DLL from 1 to 2.
You can then pinvoke FreeLibrary() twice to decrease the reference count to 0, passing it the IntPtr you got from LoadLibrary(). That unloads the DLL, as well as any dependent DLLs that got loaded.
Beware that you'll get very nasty failure when you try to pinvoke any exported function on the DLL again, any time after doing this. The pinvoke marshaller is unaware that the DLL isn't around anymore and will call the function at the address it thinks is still valid. Which bombs your program with an AccessViolation exception if you are lucky. Or runs a completely random bit of code if you are not so lucky and the address space formerly occupied by the DLL got re-used by another DLL. Anything can happen then, none of it good.
This should free a module previously loaded when you called P/Invoke function.
[DllImport("kernel32", SetLastError=true)]
static extern bool FreeLibrary(IntPtr hModule);
public static void UnloadModule(string moduleName)
{
foreach(ProcessModule mod in Process.GetCurrentProcess().Modules)
{
if(mod.ModuleName == moduleName)
{
FreeLibrary(mod.BaseAddress);
}
}
}
Based on Peters recommendation this works for me:
[DllImport("kernel32", SetLastError = true)]
private static extern bool FreeLibrary(IntPtr hModule);
public static void UnloadImportedDll(string DllPath)
{
foreach (System.Diagnostics.ProcessModule mod in System.Diagnostics.Process.GetCurrentProcess().Modules)
{
if (mod.FileName == DllPath)
{
FreeLibrary(mod.BaseAddress);
}
}
}
Late to the party, but I've made a tool to do this. It's supposed to run in Unity, but I think it can be adopted to other C# solutions. It's available here: https://github.com/mcpiroman/UnityNativeTool.
Please note that it is essentionally a hack (but often used hack, see Harmony), so I don't quite recommend using it at production code.
Since I came across the information here while I was looking around for information I figure I will contribute back what I ended up doing to fix an issue with the Sixense SDK on OSX IN UNITY. You'll see in there an implementation of dynamically loading/unloading a dylib on OSX:
https://gist.github.com/amirebrahimi/d7b02c01bcd3ca7da144
How long is the typical overhead added by calling a .dll written in C++ from a C# application using the following syntax?
[DllImport("abc.dll", EntryPoint = "xcFoo", CallingConvention = CallingConvention.Cdecl)]
public extern static Result Foo(out IntPtr session,
[MarshalAs(UnmanagedType.FunctionPtr)]ObjectCallback callback,
UInt64 turnKey,
string serverAddress,
string userId,
string password);
Is there a more efficient way to do it?
Check out this article on how to improve interop performance. What to do and what best to avoid.
http://msdn.microsoft.com/en-us/library/ms998551.aspx
Are you talking about the overhead of invoking the native method? If so, I dont think it is significant at all, as there are a lot of such calls in the .NET framework class libraries.
Now, whether the overhead is significant for your scenario can only be answered by doing performance measurements, and comparing them against what you expect.
The marshalling into the native method will cost three memory allocations from the NT heap, which is not so bad. It's the delegate back that gets worrysome.
A good method to check this sort of thing is throw in a break point where you make calls. Don't know when the library is loaded, so maybe only check the break point on the second call (unless loading cost is your main concern). Then open up the disassembly window in visual studio and see how many lines there are before your dll function is being invoked.
i know this question is old but ive managed to call native functions blazingly fast with not only using calli CIL instruction but also with special trick, but ofc you need to handle pinnig and/or marshalling arguments yourself if you deal with complex types including strings..