EPICS IOC multi-core operation and test

Posted by rich___ on Thu, 23 Sep 2021 05:32:02 +0200

1, Compilation and installation method

1. Compilation and installation environment
(1) Linux operating system
(2)EPICS BASE 3.15 (3.15.1 or later)
(MCoreUtils uses some functions only after EPICS BASE 3.15, such as epicsThreadHookAdd() function)

2. Download the installation package
https://github.com/epics-modules/MCoreUtils

3. Compile and install the mcoreutils library

tar -zxvf MCoreUtils-1.2.2.tar.gz /home/dongxw/modules/MCoreUtils-1.2.2
cd /home/dongxw/modules/MCoreUtils-1.2.2
make

2, Method of use

1. Introduce MCoreUtils into IOC
(1) In the < path to IOC > / configure / release file, add the MCoreUtils path:

MCOREUTILS = /home/dongxw/modules/MCoreUtils-1.2.2

(2) In the < path to IOC > / < IOC > app / SRC / makefile file, add the MCoreUtils library and dbd:

...
<IOC>_DBD += mcoreutils.dbd
...
<IOC>_LIBS += mcoreutils
...

(3) Compile and run IOC
Note: MCoreUtils is only applicable to Linux systems, so only IOC compiled and running under Linux can perform the above operations to use MCoreUtils.

2. Define thread rules in the file
Thread rule files can be preset:
(1) / etc/rtrules file
(2) Epics under $HOME_ MCORE_ Userconfig defined file name or. rtrules file
The thread rule definition format in the file is:

name:policy:priority:affinity:pattern

Via epicsThreadOnce() 1 And epicsThreadHookAdd() functions 2 , complete the following operations before any epicsThreadOnce() function: after reading the thread rule file, generate the threadRules table; Make each thread modify the thread rule of id according to the rule corresponding to the id name in the threadRules table before running.

3. Execute iocsh command to operate thread rules
The shellCommands.c and mcoreutils.dbd files are combined to register some functions as commands that can be executed under iocsh. These commands are registered in the executable command library when the IOC starts 3 , you can execute these commands in the st.cmd file or on the "epics >" command line.
For example, after IOC is started, view the executable command Library under iocsh:

epics> help
...
iocRun          iocshCmd        iocshLoad       iocshRun        mcoreMLock
mcoreMUnlock    mcoreThreadModify               mcoreThreadRuleAdd
mcoreThreadRuleDelete           mcoreThreadRulesShow
mcoreThreadShow mcoreThreadShowAll              on              pft
...

As you can see, some commands about MCoreUtils are also included.
For example, use the mcoreThreadShow command to view the current priority status of the errlog thread:

epics> mcoreThreadShow errlog
mcoreThreadShow errlog
            NAME       EPICS ID   LWP ID   OSIPRI  OSSPRI  STATE  POLICY CPUSET
          errlog       0x73f480    15427     10       0       OK   OTHER 0-3

You can also change the priority of some threads:

epics> mcoreThreadShow scan-10
mcoreThreadShow scan-10
            NAME       EPICS ID   LWP ID   OSIPRI  OSSPRI  STATE  POLICY CPUSET
         scan-10       0x8c4db0    15443     50       0       OK   OTHER 0-3
epics> mcoreThreadModify scan-10 * 40 0   # Change OSIPRI to 40 and CPU affinity to CPU 0
mcoreThreadModify scan-10 * 40 0
epics> mcoreThreadShow scan-10
mcoreThreadShow scan-10
            NAME       EPICS ID   LWP ID   OSIPRI  OSSPRI  STATE  POLICY CPUSET
         scan-10       0x8c4db0    15443     40       0       OK   OTHER 0

3, Multi core operation test

Write a script to test the multi-core operation of IOC multithreading:

#!/bin/bash
# this script can have one or two inputs:
# $1 is for the name of IOC
# $2 is whether or not to use MCoreUtils. If not, input $2 as "no". If yes, no need to input anything as $2.


ioc=$1
using_mcu=$2
pid=`ps -ef|grep st.cmd|grep $ioc | awk '{print $2}'`
file=`[ ${using_mcu} ] && echo ${using_mcu}_`multicore.log
echo "${ioc}'s pid is:$pid \nwritting into $file"


ps -o pid,tid,psr -p $pid -m > $file

attend_psr()
{
        psr=$@
        line=1
        for ppsr in $psr
        do
                if [ $ppsr != "PSR" ]
                then
                        ppsr="  $ppsr"   # Column alignment
                fi
                sed -i ''"$line"' s@$@ '"$ppsr"'@g' $file   # Add new data at the end of each row
                line=$((line+1))
        done
}

while [ 1 ]
do
        sleep 1
        psr=`ps -o psr -p $pid -m`   # Query IOC multi-core operation
        attend_psr $psr   # Add a new column of data in the log file
done

[reference article]

How to view the threads of a process on Linux
Shell ps common combination view thread command
Method for judging which CPU core Linux process runs on
Pthread for Linux multithreading_ setschedparam
C language – Linux multithreaded pthread
How do I get the thread id of a process------ Talk about gettid and pthread_ The difference between self
CPU affinity sched_setaffinity() and sched_getaffinity() CPU_SET() and CPU_ZERO()
affinity of linux process, thread and cpu
sed references variables in shell scripts
Introduction to sed command and the method of using variables in sed command
Which file does linux search for a string
Linux looks for strings in files
C language regular expression explanation regcomp() regexec() regfree() usage explanation

  1. In the epics user manual, the epicsThreadOnce function is described as follows:
    "This is used as follows:

     void myInitFunc(void * arg)
     {
     ...
     }
     epicsThreadOnceId onceFlag = EPICS_THREAD_ONCE_INIT;
     ...
     epicsThreadOnce(&onceFlag,myInitFunc,(void *)myParm);
    

    For each unique epicsThreadOnceId, epicsThreadOnce guarantees

    1. myInitFunc is called only once.
    2. myInitFunc completes before any epicsThreadOnce call completes.
      Note that myInitFunc must not call epicsThreadOnce with the same onceId."
    ↩︎
  2. In the epics user manual, the epicsThreadHookAdd function is described as follows:
    "Register a routine to be called by every new thread before the thread function gets run. Hook routines will often register a thread exit routine with epicsAtThreadExit to release thread-specific resources they have allocated." ↩︎

  3. This function registration mechanism is described in epics user manual as follows:
    " 18.3.3 Registrar Command Registration
    Commands are normally registered with the IOC shell in a registrar function. The application's database description file
    uses the registrar keyword to specify a function which will be called from the EPICS initialization code during the
    application startup process. This function then calls iocshRegister to register its commands with the iocsh.
    ... " ↩︎

Topics: Linux