From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

NI Linux Real-Time Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

How to set CPU core for running C application - sbRIO-9651

Solved!
Go to solution

Hi,

 

Is there a way to assign the CPU for a C application or possibly implement the timed loop structure in C? The idea behind this is to separate critical LabVIEW loops on core 1 and the C code on core 0.

 

I've done some research and found some related articles but not exactly what I'd like to do. A point in the right direction would be helpful.

 

Process Isolation: http://www.ni.com/white-paper/53015/en/
Threads in Real-Time: https://forums.ni.com/t5/NI-Linux-Real-Time-Discussions/Threads-in-Real-Time/m-p/3437586
Deploying RT applications: https://forums.ni.com/t5/Real-Time-Measurement-and/Questions-for-Deploying-RT-applications/m-p/32984...

 

Thanks

Oliver

0 Kudos
Message 1 of 4
(5,581 Views)

Will the C threads be in external processes (programs called from SystemExec or otherwise externally launched) or from CLFN calls from LabVIEW code? If so, is it a simple linear-executed thread for a library call or will that call spawn other threads?

 

In either case, you can certainly use cgroups as detailed in the "Isolation" article you posted. Otherwise, there's some management that needs to be done externally or, if you have access to the source code, can be managed by the code itself using sched_setaffinity()

0 Kudos
Message 2 of 4
(5,547 Views)
Solution
Accepted by Oliver_15

The C program is called by the System Exec and as far as I'm aware it is a simple linear-executed thread. I have access to the source code, so I did some research around the sched_setaffinity()  function and worked out a solution adapted for my needs below;

 

#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

	// We want to camp on the 1st CPU. The ID of that core is #0
	const int core_id = 0;
	const pid_t pid = getpid();

	// cpu_set_t: This data set is a bitset where each bit represents a CPU.
	cpu_set_t  cpuset;
	// CPU_ZERO: This macro initializes the CPU set set to be the empty set.
	CPU_ZERO(&cpuset);
	// CPU_SET: This macro adds cpu to the CPU set set.
	CPU_SET(core_id, &cpuset);
	
	/*
	sched_setaffinity: This function installs the cpusetsize bytes long affinity mask pointed 
	to by cpuset for the process or thread with the ID pid. If successful the function returns 
	zero and the scheduler will in future take the affinity information into account.
	*/
	
	const int set_result = sched_setaffinity(pid, sizeof(cpu_set_t), &cpuset);
	if (set_result != 0) {printf("sched_setaffinity ERROR: %d \n", set_result);exit(1);}
	
	/*
	Check what is the actual affinity mask that was assigned to the thread.
	
	sched_getaffinity: This functions stores the CPU affinity mask for the process or thread 
	with the ID pid in the cpusetsize bytes long bitmap pointed to by cpuset. If successful, 
	the function always initializes all bits in the cpu_set_t object and returns zero.
	*/
	
	const int get_affinity = sched_getaffinity(pid, sizeof(cpu_set_t), &cpuset);
	if (get_affinity != 0) {printf("sched_getaffinity ERROR: %d \n", get_affinity);exit(1);}

	/*
	CPU_ISSET: This macro returns a nonzero value (true) if cpu is a member of the CPU set 
	set, and zero (false) otherwise.
	*/
	
	if (CPU_ISSET(core_id, &cpuset)) {
    printf("Successfully set thread %d to affinity to CPU %d\n", pid, core_id);
	} else {
    printf("Failed to set thread %d to affinity to CPU %d\n", pid, core_id);
	}

The original example I found is here: https://bytefreaks.net/programming-2/c/cc-set-affinity-to-process-thread-example-code

0 Kudos
Message 3 of 4
(5,541 Views)

This is a reasonable solution, however you'll need to make sure to manage whatever SMP affinitizing you do within LVRT with how you call the code (which, using the example code you listed, is not flexible).

 

Since the program is a completely separate program that's being run, you may want to check into using taskset instead when launching the C application to set the affinity (taskset is included in NI Linux RT), this allows for more flexibility when launching the program

0 Kudos
Message 4 of 4
(5,531 Views)