Notes from the UnsafeCSharp Presentation

At work each month a set of hours are set aside/scheduled for employees to learn something new. I have worked at more than a dozen companies and have never seen a periodic time scheduled in the company calendar for it. Yesterday we had eight hours scheduled for learning. During that time an invite for a one hour presentation UnsafeCSharp showed up. I watched and enjoyed it. In addition most presentations at work are recorded so I am planning on watching it again later today.

As I am writing this post I am not sure if there are things that were presented that are company confidential. For that reason, at this time I am not disclosing the name of the presenter or will dive into specific topics.

A few minutes ago I sent the author of the presentation a message via Teams. If needed, I will update this post later based on his input.

Some of the items in the presentation are interesting to me due to work that I did on a storage server that I started developing in the 1980s (and yes, I am not a young pup). At that time a set of products under the umbrella of Hierarchical Storage Management (HSM) started appearing on the market. 

For some reason or another, they were implemented on different flavors of the UNIX operating system. At work I got a copy of one of such products and spent some time experimenting and looking at source code. It was complicated and very specific to the UNIX flavor and version. Not simple and hard to implement and support.

I learned of the Data Management Interfaces Group (DMIG) and was able to join it and learn more about the implementation approaches and challenges. I signed up for the group and attended a couple meetings. In one I suggested contacting and attempting to involve Microsoft. Given that Windows was not UNIX, my suggestion was briefly discussed and dismissed. At least it was during a one week long meeting in Hawaii.

A couple months later I came up with an HSM approach for archiving data that would not require specialized drivers and could run on any computer including Windows.

I decided on four main modules. Three of them to take care of the archive operations, and the fourth to handle the DICOM images. The idea behind was that an archive alone would be hard to promote (and sell) without a specific module that would handle objects of interest.

Users would access the DICOM archive via third party viewers and scanners.

The DICOM archive would access storage via an API in the storage module. The storage module would access the disk manager to store on-line data and the disk manager would access the library manager to store data on near-line media i.e., MOD, CD, DVD, Blu-ray, and tape. The fourth module would provide a set of DLLs to facilitate the implementation of the other three modules.

I am a firm believer of the KISS principle and embraced it earlier in my professional career. One of the things that came out of it is that during the time the archive was in production as a stand alone, a distributed server, and later offered on the cloud, only once I experienced an issue with a Windows update. I was able to solve the issue with a simple code change that took a morning to debug, implement and start testing.

I have used several operating systems on different projects. They all have slightly different approaches/ways to do pretty much the same thing. Some are more complicated than others. Some are better suited for some uses than others.

I decided to use the POSIX subsystem in Windows and write most of the code (about 4.5M LOC in the storage server and 1.5M for the DICOM module) using the C programming language. With time other languages were included i.e., C++, C#, Java and Perl.

The initial interface to the storage server was via RPC calls. At the time there were two competing standards. A few years back I found out that Google was interfacing some modules in their cloud using RPC calls.

After a year or so, for simplicity I decided to change the interface to use sockets which are able to handle commands and data more efficiently and in a uniform way.

The initial set of APIs for the storage server implemented `store` an object, `query` for an object, and `retrieve` an object. As you should infer, with time many other operations were needed (i.e., `delete` and `migrate` to mention just a few). The last time I worked on the software it had about 65 API calls.

Some components in the DICOM module were written in C#. We had to develop a simple DICOM viewer and C# and .NET were the proper choice. As previously mentioned, the DICOM module could only interface with the on-line storage module. So I had to address how C# code would interface with C/C++. 

I wanted to do as little as possible on the C# side and do as much as needed in the C/C++ code. Most programming languages have an interface to call code written in different unmanaged languages.

I do not recall the exact names of the calls I used in the C# side, but I had to marshal data before calling P/Invoke to access the API in a DLL. Once data was returned it had to be unmarshalled. At the time the C# language did not have the richness in the functionality that was described during the one hour presentation UnsafeCSharp. Now you can see my interest and excitement in watching the presentation. It brought me some nice memories.

Given that the C language is very close to assembly and it is commonly used when implementing code for custom hardware, that it has collected many operators similar to what was described for C# during the presentation. For example, in C you can pack a set of fields in a data structure. As I learned during the presentation, C# has a similar operator.

While I was implementing and enhancing the storage server that was mentioned earlier, I found that the C implementation by Microsoft for Visual Studio, supported the try{} catch() operators. As far as I understand it is not part of the standard, but Microsoft found the need for it and was (not sure if still does) such a feature.

While living in the Midwest, I spent about four years as a team member and lead in custom hardware projects in which I used mostly C and occasionally some assembly language using real-time operating systems (i.e, RTOS, CTOS) using Motorola CPUs. I then moved to the East Coast and spent two years developing software for custom hardware, this time using a different Intel CPU. I was the lead on two different projects. Each time I learned new things about the real-time operating systems, the C language and of course the different microprocessors and peripheral chips.

In life one should always question things in order to come up with the best possible approach and in some cases be able to specify newer and better options. I try to read and learn as much as possible. You never know when such knowledge might come up to solve a problem.

During my research for writing this post I read the following on-line documents:

o Unsafe code 

o Unsafe (C# Reference) 

o Unsafe code, pointer types, and function pointers

o Platform Invoke (P/Invoke)

UPDATE: I did receive a response from the author of the presentation. His name is Dennis Dietrich and you can find the materials he developed for the presentation at his GitHub repo UnsafeCSharp.

Hope you enjoyed this post. It is not a bad idea to take a look at the presentation materials and experiment with the code. The links to the documents might prove of interest. I find that one of the best ways to learn is to read and experiment.

I would like to disclose that both Dennis Dietrich and I are at this time Microsoft employees.



Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.