0

While creating different benchmarks I often aim for the best latency. As you all know, memory in the heap is much more expensive to access than on the stack. We are now in 2021 and when I try ulimit -s I see that I have 8192kbs available. Couldn't it set higher?

I was wondering about how to set it using c code and found setrlimit and getrlimit:

The getrlimit() and setrlimit() system calls get and set resource limits respectively. Each resource has an associated soft and hard limit, as defined by the rlimit structure [...]

I found this answer and this one, and, while they are both very interesting, there are still little things I don't get:

#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/resource.h>
#include <errno.h>

#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char *argv[])
{
    struct rlimit old, new;
    struct rlimit *newp;
    pid_t pid;

    if (!(argc == 2 || argc == 4)) {
        fprintf(stderr, "Usage: %s <pid> [<new-soft-limit> "
        "<new-hard-limit>]\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    pid = atoi(argv[1]); /* PID of target process */

    newp = NULL;
    if (argc == 4) {
        new.rlim_cur = atoi(argv[2]);
        new.rlim_max = atoi(argv[3]);
     //   newp = &new; // I comment this line to avoid messing up with the processes too much;)
    }

/* Set CPU time limit of target process; retrieve and display previous limit */

    if (prlimit(pid, RLIMIT_CPU, newp, &old) == -1)
        errExit("prlimit-1");

      ;
    printf("Previous limits: soft=%lld; hard=%lld\n", (long long) old.rlim_cur, (long long) old.rlim_max);

/* Retrieve and display new CPU time limit */

    if (prlimit(pid, RLIMIT_CPU, NULL, &old) == -1)
        errExit("prlimit-2");
    printf("New limits: soft=%lld; hard=%lld\n", (long long) old.rlim_cur, (long long) old.rlim_max);

    //perror("error:");
    exit(EXIT_FAILURE);
}

If I try on any process, I will see, at least on Ubuntu 18.04 and compiling with gcc, that when it tries to retrieve the current and max limits it will return -1. What is this -1 return value exactly? Does it mean "set to default system value" or "failed to retrieve" and if it is "failed to retrieve", what was the reason for that? Why is if (prlimit(pid, RLIMIT_CPU, newp, &old) == -1) not triggered?

Previous limits: soft=-1; hard=-1

However if I uncomment newp = &new; (commented on purpose), then I can set a new value for the process, both current and max, there is no problem with that and it is quite amazing. What would be the max value that I could theoretically set? I tried with sudo gcc raise_stack.c && ./a.out 9194 8192 16384 but I am too afraid to burn my cpu to try it myself ;)

New limits: soft=8192; hard=16384

Many thanks in advance for helping me to better understand getrlimit.

NB: avoid "if you have to raise your stack memory then you are doing something wrong". This is not an opinion question.

edit: cant figure out where to set errno to get the right result

error:: Success
error:: Success
error:: Success
error:: Success
error:: Success
error:: Success
Previous limits: soft=-1; hard=-1
error:: Success
New limits: soft=-1; hard=-1
error:: Success

I set it after

long long a = prlimit(pid, RLIMIT_CPU, newp, &old);
perror("error:");

but still not the ERRNO that I am looking for.

Antonin GAVREL
  • 9,682
  • 8
  • 54
  • 81
  • *What is this -1 return value exactly*. Read the [manual](https://linux.die.net/man/2/setrlimit). In Linux a common practice is to return 0 on succes and a non-zero for error. Then `errno` is set to indicate a more precise error code. On error, call `perror` to get a string description of the `errno` value. – kaylum Mar 04 '21 at 05:33
  • it is what I did (as you can see its commented) and I got `error: success` so I don't really get it – Antonin GAVREL Mar 04 '21 at 05:48
  • Can you please provide the exact input and output? – kaylum Mar 04 '21 at 05:53
  • @kaylum thanks for taking the time to help out! see my edit – Antonin GAVREL Mar 04 '21 at 05:55
  • `//perror("error:");` I don't understand why you are calling `perror` at that place. There is no error to check at that point. `perror` must be called immediately after the function that failed. In this case `printf` was the last call and it likely set `errno` to success. – kaylum Mar 04 '21 at 06:20
  • yes I figured out this and started to move it everywhere in the function like a brainless chicken, but without any probing result... – Antonin GAVREL Mar 04 '21 at 06:35

1 Answers1

2

The -1 value is RLIM_INFINITY, meaning that there is no imposed limit.

Kevin Thibedeau
  • 3,299
  • 15
  • 26