JetByte News: Punch card programming...

The second of our “reanimation” projects has reached a significant milestone. We ran the whole new system on the real hardware last week, and it mostly works. This is a big step for us and the client as the project has been quite complex in terms of how the development has been done. As I said, our secret Industrial Control Client has had us working on a program that compiles in Visual C++ 6 on an XP VM.

Setting the preferred NUMA node for a Windows Service (and making it work after a reboot)

When your machine has multiple NUMA nodes it’s often useful to restrict a process to using just one for performance reasons. It’s sometimes hard to fully utilize multiple NUMA nodes and, if you get it wrong, it can cost in performance as the nodes need to keep their caches consistent and potentially access memory over a slower link than the memory that is closer to the node, these things can be relatively expensive.

JetByte News: Reanimator!

We recently had an old client contact us with an unusual request. We last worked with VEXIS Systems Inc. back in 2010 when we extended the telephony server we’d built for them to support CLR hosting, using The Server Framework’s CLR Hosting Option. We then built a managed plugin system that integrated with the existing unmanaged system so that they could write their business logic in either unmanaged code or in a managed language such as C#.

Multi-threaded testing

I’ve always found testing multi-threaded code in C++ a humbling experience. It’s just so easy to make stupid mistakes and for those mistakes to lurk in code until the circumstances are just right for them to show themselves. This weekend a unit test that has run thousands of times for many years started to fail. The reason for the failure was a fairly obvious race condition in the test code. This issue had lain dormant and only been exposed by running the tests on my new development machine.

Sick PC

I’ve had a sick PC for several weeks now. It has cost me a surprising amount of time and thought. It started with my main work machine randomly hanging. This is Windows 11 with a Ryzen 9 5900X, and it has previously run faultlessly for two years or so. The hangs were, at first, annoying and I assumed that it was some driver that had been updated and was playing up, and initially I hoped that it would just fix itself with another update.

Rust - Borrowing mutable references

Previously published This article was previously published on len-learns-rust.com. A full index of these articles can be found here. In addition to managing the lifetimes of references to variables, the Rust compiler’s borrow checker also deals with enforcing Rust’s guarantees about mutability and so helps to prevent data races. Basically, you can have any number of immutable references to a variable, but only if there are no mutable references to it at the same time, and you can only ever have a single mutable reference.

Rust - Lifetimes

Previously published This article was previously published on len-learns-rust.com. A full index of these articles can be found here. One of the jobs of the Rust compiler’s “borrow checker” is to track the life of each reference to a variable so that it can prevent dangling references. To do this, it annotates each variable and reference with details of the scope in which it is valid. This annotation is called a lifetime.

Debugging network protocols with journaling

One of my long-term clients has hundreds of cloud machines running instances of their server, each server maintains thousands of reliable UDP connections using a custom protocol that we’ve developed over the years. When things go wrong it’s often hard to work out why. Even though we have reasonable unit test coverage of the code that runs the UDP protocol, it’s hard to build tests that cover every possible scenario.

Rust - Deadlocks

Previously published This article was previously published on len-learns-rust.com. A full index of these articles can be found here. One reason that access shared data using locks is a bad idea is that, in complex code, it may be possible to deadlock. At their simplest, deadlocks are caused when one thread (thread a) obtains and holds a lock which another thread (thread b) requires whilst itself being blocked from obtaining a lock that it requires because thread b already holds it… Unfortunately, whilst Rust has eliminated data races in multithreaded code, it doesn’t prevent the possibility of deadlocks.

Rust - Accessing the Id Manager from multiple threads

Previously published This article was previously published on len-learns-rust.com. A full index of these articles can be found here. Since I now understand a little about how to share data between threads I can try and use my Id Manager from multiple threads. Following the same pattern as I’ve been using with the other threading code, something like this might work… #[test] fn test_channel_thread_with_id_manager() { let id_manager = Arc::new(IdManager::<u8>::new(ReuseSlow)); let shared_manager = Arc::clone(&id_manager); let data = Arc::new(Mutex::new(HashMap::<String, Id<u8>>::new())); let shared_data = Arc::clone(&data); let mut thread = ChannelThread::new(move |message| { let id = shared_manager.