NI Linux Real-Time Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

increase stack size from 256 to 4096 KB

Solved!
Go to solution

I have a LabVIEW RT Application that calls functions from a shared object. These need a bit more than the standard 250 KB of stack Size that are set on the cRIO.

 

My first instinct was to use the System Exec.vi to execute the ulimit -s command, which looks like this:

2017-02-09 14_50_50-shelltest.vi Front Panel on BLASTEST.png2017-02-09 14_50_50-shelltest.vi Front Panel on BLASTEST.png

 

I then tried altering the limits in etc/security/limits.conf

with the entry

lvuser hard stack 4096

but it didn't seem to do anything for me, as I still get the dreaded 256 output.

Any way I can tell my controller to raise the stack size at startup?

 

Robert

0 Kudos
Message 1 of 5
(5,605 Views)

Try the steps again but as root user instead of lvuser:

 

  • As root, stop the lvrt process     /etc/rc5.d/S98nilvrt stop
  • As root, set the stack size         ulimit –s ###
  • You can confirm that the stack size has been updated using ulimit: ulimit -a
  • Then restart the lvrt process    ./usr/local/natinst/labview/lvrt &
Deborah Burke
NI Hardware and Drivers Product Manager
Certified LabVIEW Architect
0 Kudos
Message 2 of 5
(5,574 Views)

Hello Deborah,

 

I stopped the process and set the stack size like you described, but couldn't restart it.

I thought I would try something different and I created a startup script and placed it in /etc/init.d/

the script looks something like this: increasestack

#!/bin/bash

ulimit -s 4096

chmod 755 increasestack

 

to set execution permissions

 

then I set up a symlink in the rc2.d directory:

ln -s /etc/init.d/increasestack /etc/rc2.d/S98increasestack

 after reboot i checked with the ulimit -s command and it did nothing.

 

Afterwards I tried to alter nilvrt from /etc/init.d  by editing it to:

#!/bin/sh
# Copyright (c) 2013 National Instruments.
# All rights reserved.

MAX_CRASHES=2
PID_RUNLVRT=/var/run/runlvrt.pid
PID_LVRT_WRAPPER=/var/run/lvrt_wrapper.pid
ulimit -s 4096

# runlvrt is a function that:
# - restarts lvrt if it crashes
# - disables statup application and blinks the LED in case of MAX_CRASHES
#   of startup application
# - no limit on crashes for the interactive session
runlvrt() {
  CRASH_COUNT=0

  # "NORMAL_START"               - first run
  # "CRASHED_AND_RESTART"        - lvrt crashed so we have to restart in a
  #                                normal fashion
  # "CRASHED_AND_NO_APP_RESTART" - lvrt crashed and we need to restart lvrt
  #                                without the startup application
  STARTUP_PARAM=NORMAL_START

  UI_ENABLED=`/usr/local/natinst/bin/nirtcfg -g section=SYSTEMSETTINGS,token=ui.enabled | tr "[:upper:]" "[:lower:]"`

  while true
  do
    # nirtcfg only reads from ni-rt.ini, so read lvrt.conf with grep
    STARTUPAPP_ENABLED=false
    grep -Eqi "^RTTarget.LaunchAppAtBoot *= *\"?True\"?$" /etc/natinst/share/lvrt.conf && STARTUPAPP_ENABLED=true

    YOU_ONLY_LIVE_TWICE_TOKEN=`/usr/local/natinst/bin/nirtcfg -g section=Startup,token=YouOnlyLiveTwice | tr "[:upper:]" "[:lower:]"`

    if [[ "$STARTUPAPP_ENABLED" == "true" ]]; then
      if [[ "$YOU_ONLY_LIVE_TWICE_TOKEN" != "false" ]]; then
        if [[ $MAX_CRASHES -le $CRASH_COUNT ]]; then
          echo "Startup application prevented from running at startup. The startup application crashed during previous startup attempts."

          # set LED to 4 blinks constantly repeating
          /usr/local/natinst/bin/status_led blink_count 4

          # disable startup app for the rest of the session (until reboot)
          STARTUP_PARAM=CRASHED_AND_NO_APP_RESTART
        fi
      fi
    fi

    /bin/su -- lvuser -l -c "/etc/init.d/lvrt-wrapper $STARTUP_PARAM $PID_LVRT_WRAPPER $UI_ENABLED"
    EXITCODE=$?
    if [ $EXITCODE != 0 ]; then
        STARTUP_PARAM=CRASHED_AND_RESTART
        CRASH_COUNT=$[CRASH_COUNT+1]
    else
        STARTUP_PARAM=NORMAL_START
        CRASH_COUNT=0
    fi
  done
}

case "$1" in
  start)
    touch $PID_RUNLVRT
    chmod +r $PID_RUNLVRT

    touch $PID_LVRT_WRAPPER
    # we need user lvuser to write its PID
    chown lvuser $PID_LVRT_WRAPPER
    chmod +r $PID_LVRT_WRAPPER

    runlvrt &
    # save runlvrt process PID to /var/run
    echo $! > $PID_RUNLVRT
    ;;
  stop)
    # kill saved PID for runlvrt process
    if [[ -f "$PID_RUNLVRT" ]]; then
      kill `cat $PID_RUNLVRT`
      rm $PID_RUNLVRT
    fi

    # kill saved PID for lvrt_wrapper process
    if [[ -f "$PID_LVRT_WRAPPER" ]]; then
      kill `cat $PID_LVRT_WRAPPER`
      rm $PID_LVRT_WRAPPER
    fi
    ;;
esac

still when I execute the System Exec.vi with the "ulimit -s" argument, i get back 256.

any other ideas?

0 Kudos
Message 3 of 5
(5,569 Views)
Solution
Accepted by topic author tusrob

Hi tusrob,

 

To address the two issues you'd noted, in order,

 

  • Deborah_B left out a fairly important thing that's not immediately obvious, but it's in the wrapper that's called from the startup script that  you modified: you need to be in the directory that contains the lvrt binary when you run it.
    • From the shell:
admin@upandatthem:~# /etc/init.d/nilvrt stop
admin@upandatthem:~# ulimit -s 4096
admin@upandatthem:~# ulimit -s
4096
admin@upandatthem:~# cd /usr/local/natinst/labview/
admin@upandatthem:/usr/local/natinst/labview# ./lvrt

Welcome to LabVIEW Real-Time 15.0
  • From LV:

 stack1.jpg

 

Of course, this change is reverted as soon as you reboot and LVRT is launched normally. Additionally, when run like this, the lvrt runtime is running as admin/root, which has not been tested and is generally discouraged. In other words, DON'T DO THIS

 

You were knocking on the door of how to make the change more persistent, but you missed a couple of things.

 

The biggest issue you missed is the stack limiting that is imposed on each and every new session created as set in /etc/profile.d/ulimit.sh. Setting the stack limits in the nilvrt script get undone ×2: once when becoming the lvuser user in the line su -- lvuser -c "/etc/init.d/lvrt-wrapper..." thanks to the profile.d script noted above, and again in the actual wrapper script, which has ulimit -s 256.

 

Set an appropriate limit in the profile.d/ulimit.sh and remove the limiting in lvrt-wrapper to get a more persistent setting.

  • In /etc/profile.d/ulimit.sh, change ulimit -s 256 to ulimit -s 4096, e.g.
  • In /etc/init.d/lvrt-wrapper, comment/remove ulimit -s 256
  • Note that this will not persist over formats or reinstallations of lvrt from MAX

 

Note: With the way that lvrt handles memory in the name of RT-ness (once pages are mapped to physical memory, they cannot be unmapped/freed) and the number of threads that the LVRT runtime can create, this can quickly eat memory in 4M chunks (less an issue for x64 targets, more a problem for myRIO and low-memory targets)

Message 4 of 5
(5,561 Views)

Hi,

 

I am trying to do the same, setting the stack soze limit for the veristand running a NI RT-Linux. Is te same setup mentioned in this thread can be used veristand? How can i ckeck that?

 

Thanks

 

0 Kudos
Message 5 of 5
(3,278 Views)