Category: Clang

New Linux Timing Code

New Linux Timing Code

silver and white round analog watch

For some time, I had a problem with my old Linux timing code. The units hr_time.h/c had to have the includes arranged in the right order and some flags set for it to compile. Plus it never seemed right having to do this in hr_time.h

#include <linux/time.h>
#define __timespec_defined 1
#define __itimerspec_defined 1
#define __timeval_defined 1

But today I found some better code on this SolarianProgrammer website and I’m always happy to give credit where it’s due. I’ve witched to using C17 which clang on Ubuntu (clang 14) and Raspberry Pi (clang 11) both seem to accept.

So now my hr_time.h looks like this:

hr_time.h

#pragma once
#include <stdlib.h>
#include <time.h>

void startTimer();
void stopTimer();
double diff();

hr_time.c

#include "hr_time.h"
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

struct timespec start;
struct timespec end;

void startTimer() {
	if (timespec_get(&start, TIME_UTC) != TIME_UTC) {
		printf("Error in calling timespec_get\n");
		exit(EXIT_FAILURE);
	}
};

void stopTimer() {
	if (timespec_get(&end, TIME_UTC) != TIME_UTC) {
		printf("Error in calling timespec_get\n");
		exit(EXIT_FAILURE);
	}
};

double diff()
{
	return  (double)(end.tv_sec - start.tv_sec) + 
			((double)(end.tv_nsec - start.tv_nsec) / 1000000000L);
}

I’m only ever using one timer, if you want to modify this to pass in a timer in the startTimer and stopTimer then it’s easy enough.

Interesting gcc/clang extensions to C

Interesting gcc/clang extensions to C

C ExampleBoth gcc and clang support extensions to C and while i normally try and make things I write about work on Windows (i.e. Visual Studio), these are useful enough that I thought they deserve a mention. Yes I know you can run gcc/clang on Windows using Cygwin or MinGW, but for various reasons I prefer Visual Studio.

You can add a constructor and destructor functions to a C program; the constructor function runs before main() and the destructor after main().

The syntax is not exactly clean or obvious (those are double underscores before and after the word attribute like Python dunders!) but I got this program to compile/run with clang 10 on Ubuntu as the screenshot shows.  Here’s a listing. I called the two functions ctor and dtor but you can use anything.

#include <stdio.h>

__attribute__((constructor)) void ctor(void)
{
  printf("Constructor runs first\n");
}

__attribute__((destructor)) void dtor(void)
{
  printf("Destructor runs last\n");
}

int main() {
    printf("Main\n");
}

The output  is:

david@DavidPC:~/Projects/Examples$ ./ex1
Constructor runs first
Main
Destructor runs last
Raspberry Pi 4 – Perfect for arcade quality games and development

Raspberry Pi 4 – Perfect for arcade quality games and development

lot s of asteroidsI got my Pi 4 a week ago and have been doing experiments on it with my Asteroids game. If I disable the line of code that kills the player ship in the DestroyObject() function and just add a return after case tPlayer: and uncomment the code that adds Asteroids when you press A then I can have lots of asteroids on screen. Also set the MAXASTEROIDS #define to 128.

Then you get the likes of this screenshot which is a 1024 x 768 size window. It’s still running at 40 fps, there are 116 asteroids on screen, around 60-70 explosions and the Pi’s temperature is still a balmy 44.79 C. I’ve never got the Pi’s temperature (and it does have an internal 3.3V fan) to rise above 51 C.

But what’s also impressive is that with Visual Studio Code and Clang on the PI, I can compile the whole 2,200 lines of C on the PI in about a second. This makes the Pi very usable for developing games. And I say this as someone who is used to powerful Windows PCs for compiling code.

This is it running in debug mode; that’s all the numbers and wire frame bounding boxes around every moving object.

Further experimenting and removing the limitations (I used a While loop to limit it to 60 fps back before I had enabled the hardware video flyback). With that while removed and the hardware video flyback disabled, I was getting over 100 fps with 100 asteroids on screen at once.  I pushed it up to 6,000 asteroids and the frame rate dropped to 10 fps. Given the amount of stuff that was colliding and blowing up, that’s still very good.

Building Asteroids on a Raspberry-Pi

Building Asteroids on a Raspberry-Pi

My asteroids running on a Raspberry-Pi 3B+Silly me completely forgot that Raspberry Pis have a different CPU architecture compared to my PC. You just get used to something working on Linux and it was only after copying and it didn’t run that I realised my mistake. So I now have to recompile Asteroids (from Chapter-48.zip).

I’ve had a Raspberry-Pi 3 B+ for a year and wanted to run the Linux asteroids on it, now that I have it working on Ubuntu.

To do that I had to setup  Pi, running Raspbian downloaded from the Raspberry Pi website onto my Windows PC and then I used Win32 DiskImager (free Windows software) to burn the Raspbian OS onto a SD Card. Raspberry-Pis boot from SD Cards and the better and faster the SD card, the quicker the OS runs. Get a class 10 with A1 SD Card if you can.

After the Pi booted and Raspbian was installed and configured I had to enable SSH on the Pi; it’s disabled by default.

So now my PC was talking to the Pi using the excellent free WinSCP.  I copied all the files over, including the masks, sounds and images folders and all the source code and my exe built on Ubuntu which was the wrong file type. (Trying to run Intel code on an ARM- good luck with that!)

Now it turns out that the Raspbian version I installed (I’d gone for the Raspbian Buster with desktop and recommended software-2.5 GB download) included the non-dev version of SDL2. But as I needed to recompile the whole program, I had to install Visual Studio Code, Clang and the dev versions of SDL2, image and mixer.

Visual Studio Code on Arm?

Haedmelted VS Code running on Raspberry Pi 3b+Microsoft don’t do an official version for Raspberry-Pi or other ARM boards. However I discovered that a developer called Jay Rodgers has taken their source code (VS Code is open source) and  you can get a version from his site. It’s very usable on the Pi. Almost but not quite identical.

After installing the dev versions of libsdl2, image and mixer, I was almost able to compile it. I’d installed Clang but unlike the version on Ubuntu which was Clang-6, the version on Raspbian (based on Debian Buster) is Clang-7.

This means you have to edit the tasks.json file in the hidden .vscode folder. On line 25 where it says “command”: change the path to “/usr/bin/clang-7”.

That built ok, but when I ran it, it stopped with an error in the errorlog.txt file. For some reason, it failed loading the file “masks/am2.msk”.  Now I’d had no errors copying files from Windows to the Pi. This had been a very intermittent problem when copying several files in one go from Windows 10 to Ubuntu running under Hyper-V. Occasionally it would come up with some weird error but usually copied OK on the second go.

Despite several attempts, I could not get it to load that mask so as a temp fix I commented the line out. This means that one of the four asteroids sizes can never collide with anything. But it now ran.

However, I’m only getting about 25-27 fps with it in the early levels, not the 60 fps that I get on Ubuntu on other hardware. Given that the bulk of the work is blitting graphics, I suspect the GPU is just a bit under powered. Apparently on the Raspberry Pi 4, the GPU is newer and twice as fast as on the 3B+ so I’ll have to try it on a 4 when I get one. But the game works and is just about playable.

Now I’ll have to try and figure out why it won’t load that one mask. This has the makings of an interesting bug…

 

Install Clang and Visual Studio Code on Ubuntu

Install Clang and Visual Studio Code on Ubuntu

Visual Studio CodeClang is very easy to install. Open a terminal and issue this command:

sudo apt install clang

It takes a little bit more for Visual Studio Code (aka VS Code). Start on the download page of VS Code. Just google for download Visual Studio Code or click here. Click the Deb rectangle and pick the Open with Software install (default) and that will install it.

After that is installed, run VS Code (open a terminal and type code) and click the extensions icon (5th down on the left) and type in C++ in the search box. The first result is by Microsoft so select it and click install.

Now I created a Projects folder under my home, so click on open Folder in the File menu and select Projects. You can create individual folders for applications under that. If you look closely you can see Asteroids, AsteroidsDND and Examples with Asteroids being open and containing two .c files.

To compile, make sure the open tab is the file you wish to compile then click Terminal on the top menu and Run Build Task…  You’ll see the compiled programs on the left under the Asteroids folder (decnot and ex1).

There’s a bit more for configuring Builds and Debugging but I’ll cover that another time.

 

 

Comparing MSVC vs Clang

Comparing MSVC vs Clang

Listing of some C codeI originally created Asteroids for Windows using Visual Studio 2017 Community Edition. Since then I’ve started the Clang version on Ubuntu and there haven’t been too many differences but there are just a few so in this post I’ll list what I’ve found so far.

Include Paths

On Windows, I was able to get away with #include <SDL.h> but on Linux, I’ve had to include the path so it’s #include <SDL2/SDL.h>. This was probably because I included the full path in the MSVC configuration.

Link Failures

The asteroids.c code in chapter 29 uses sin and cos for the first time and the linker was unhappy with that. So in tasks.json, I’ve explicitly had to add it into args, along with SDL2 and SDL2_image,

            "args": [
                "-g",
                "${file}","${workspaceFolder}/Asteroids/hr_time.c",
                "-o",
                "${fileDirname}/asteroids",                
                "-lSDL2",
                "-lSDL2_image",
                "-lm"
            ],

That “-lm” does that for maths.

Safe functions

Microsoft has its own set of safe functions many with an _s and extra length parameter.

On Linux, there don’t seem to be so many.

So sprintf_s on Windows becomes snprintf.

fopen_s just becomes standard fopen

linux/time.h

As well as time.h in the includes, I needed to add linux/time.h as well.

I’m considering switching to C11

I’m considering switching to C11

Programming image
Image by Gerd Altmann from Pixabay

All C code I write in the books is currently to the C99 standard. All the compilers involved (Visual C++ on Windows and Clang on Ubuntu) support C99 but C11 support seems restricted to GCC and Clang.

Microsoft has traditionally supported C++ but their C support seems a bit grudging; realistically they don’t prioritise it which I can understand.

Given though that I’m not going to republish my first e-book for a while (I’d like to add a WebAssembly chapter or two first), I’m going to investigate whether it’s worth switching to C11 for the 2nd book. From what I’ve read all it needs is a flag to tll it to compile to C11 standards. This is for Clang.

-std=c11

But the other question is what will I gain by doing this and I can’t actually see there’s that much benefit.. I don’t need Unicode, I don’t think alignment will really make much difference. You can read about the C11 changes on WikiChip.

So I’ve made the decision. I’ll stick with C99 for now. But for an alternative view, I recommend Danny Kalev’s 2012 article on C11.

 

That Clang C compilation

That Clang C compilation

I spent about five hours trying to get the timing code to compile before I got it compiling and working. Now I’m used to the concept of include guards in C. Those are the #ifndef that you see like this:

#ifndef _timeh
  #include <linux/time.h>
  #define _timeh 1
#endif

But in the hr_time.c file these include guards are on steroids. Not only did I need to include <time.h>, I also had to include <linux/time.h> but with a couple of extra #defines in there. It doesn’t seem right and wasn’t needed with the Windows version.  I’d welcome any comments on this.

#ifndef _timeh
  #include <linux/time.h>
  #define __timespec_defined 1 
  #define __itimerspec_defined 1
  #include <time.h>
  #define _timeh 1
#endif

The sdldemo program with timing whown in the window caption.Without these, I’d get compile errors like __timespec redefined errors.

I’ve uploaded the source files and Visual Studio Code JSON files for this in the file asteroids_ch25.zip in the new repository for the Learn C on Linux Ebook

So feel free to try it. The only difference between this and the version shown in an earlier post is the time (in the window caption) to draw all 100,000 rectangles,  You’ll need to install SDL2 if you want to compile and run the program.