keith bradley
keith bradley

Reputation: 107

pthread_attr_setschedparam() returns non zero but errno = success ... (Linux, C, Ubuntu 18.04.4)

Good day all stack overflow peeps !

Have this code in my program which exits on error ... but with Success? Not sure why?

Output:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/resource.h>



char      strNowTime[26];



//-----------------------------------
// signal Handler stuff.
//-----------------------------------
static
struct  sigaction mySigActTerm;

volatile
int     myTerminate = 0;

void terminateHandler(int signum, siginfo_t *info, void *ptr)
{
  // set a flag here and get out.
  myTerminate = 1;
}



void getNowTime(char* str)
{
  time_t    rawtime;
  time(&rawtime);
  ctime_r(&rawtime, str);

  // clobber the unwanted newline.
  str[24] = '\0';
}



void myResLimit()
{
  struct
  rlimit    procLimit;

  getrlimit(RLIMIT_RTTIME, &procLimit);
  getNowTime(strNowTime);
  fprintf(stderr, "%s - RLIMIT_RTTIME: soft=%lld, hard=%lld\n", strNowTime, (long long) procLimit.rlim_cur, (long long)procLimit.rlim_max);

  getrlimit(RLIMIT_RTPRIO, &procLimit);
  getNowTime(strNowTime);
  fprintf(stderr, "%s - RLIMIT_RTPRIO: soft=%lld, hard=%lld\n", strNowTime, (long long) procLimit.rlim_cur, (long long) procLimit.rlim_max);

  getrlimit(RLIMIT_CPU, &procLimit);
  getNowTime(strNowTime);
  fprintf(stderr, "%s - RLIMIT_CPU: soft=%lld, hard=%lld\n", strNowTime, (long long) procLimit.rlim_cur, (long long) procLimit.rlim_max);
}



void*   serialThread(void* arg)
{
    while (1) {
        
    }
}



//-----------------------------------
// the one and only MAIN.
//-----------------------------------
int main()
{
  //-----------------------------------------------
  // locals.
  int               rtn;
  int               myErr;

  pthread_t         serialThdID;

  pthread_attr_t*   serialAttr;

  struct
  sched_param       serialParam;


  //-----------------------------------------------
  // Log OS resource limits.
  myResLimit();

  //-----------------------------------------------
  // initialize the signals struct.
  // ... and setup signals.
  memset(&mySigActTerm, 0, sizeof(mySigActTerm));
  mySigActTerm.sa_sigaction = terminateHandler;
  mySigActTerm.sa_flags = SA_SIGINFO;

  sigaction(SIGTERM, &mySigActTerm, NULL);


  //-----------------------------------------------
  // setup the pthread attributes struct.
  if ((serialAttr = malloc(sizeof(pthread_attr_t))) == NULL) {
    myErr = errno;
    getNowTime(strNowTime);
    fprintf(stderr, "%s - main() - pthread_attr_t malloc()\n%s\n", strNowTime, strerror(myErr));
    exit(EXIT_FAILURE);
  }
  memset(serialAttr, 0, sizeof(pthread_attr_t));

  //-----------------------------------------------
  // set initial default pthread attr values.
  if (pthread_attr_init(serialAttr) != 0) {
    myErr = errno;
    getNowTime(strNowTime);
    fprintf(stderr, "%s - main() - pthread_attr_init()\n%s\n", strNowTime, strerror(myErr));
    exit(EXIT_FAILURE);
  }

  //-----------------------------------------------
  // set for best near real time policy.
  if (pthread_attr_setschedpolicy(serialAttr, SCHED_FIFO) !=0) {
    myErr = errno;
    getNowTime(strNowTime);
    fprintf(stderr, "%s - main() - pthread_attr_setschedpolicy()\n%s\n", strNowTime, strerror(myErr));
    exit(EXIT_FAILURE);
  }

  //-----------------------------------------------
  // set to explicit inherit or attr obj will be ignored.
  if (pthread_attr_setinheritsched(serialAttr, PTHREAD_EXPLICIT_SCHED) !=0) {
    myErr = errno;
    getNowTime(strNowTime);
    fprintf(stderr, "%s - main() - pthread_attr_setinheritsched()\n%s\n", strNowTime, strerror(myErr));
    exit(EXIT_FAILURE);
  }

  //-----------------------------------------------
  // set to un-limited thread priority.
  serialParam.sched_priority = 0;
  if (pthread_attr_setschedparam(serialAttr, &serialParam) !=0) {
    myErr = errno;
    getNowTime(strNowTime);
    fprintf(stderr, "%s - main() - pthread_attr_setschedparam()\n%s\n", strNowTime, strerror(myErr));
    exit(EXIT_FAILURE);
  }

  //-----------------------------------------------
  // start the new thread.
  rtn = pthread_create(&serialThdID, serialAttr, serialThread, NULL);
  myErr = errno;
  if(rtn  == 0) {
    getNowTime(strNowTime);
    fprintf(stderr, "%s - starting serial thread.\n", strNowTime);
  }
  else {
    getNowTime(strNowTime);
    fprintf(stderr, "%s - main() - pthread_create() returned %d\n%s\n", strNowTime, rtn, strerror(myErr));
    exit(EXIT_FAILURE);
  }

  //-----------------------------------------------
  // no need to keep this junk if pthread_create() succeeded.
  if (pthread_attr_destroy(serialAttr) != 0) {
    myErr = errno;
    getNowTime(strNowTime);
    fprintf(stderr, "%s - main() - pthread_attr_destroy()\n%s\n", strNowTime, strerror(myErr));
  }
  // research proves this is needed if we malloc'ed!
  free(serialAttr);



  while (myTerminate == 0) {

  }
}

Upvotes: 0

Views: 358

Answers (2)

kaylum
kaylum

Reputation: 14044

pthread_attr_setschedpolicy does not set errno. From the manual:

RETURN VALUE

On success, these functions return 0; on error, they return a nonzero error number.

That is, the error number is in the return value itself and not in errno.

In fact, none of the pthread functions set errno. See the pthread_create manual for an example of how it calls perror when a pthread function fails. It actually manually sets errno first:

#define handle_error_en(en, msg) \
           do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

Upvotes: 1

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215607

As clearly documented, pthread_attr_setschedparam returns the error code on failure. It does not set errno. (Technically it's allowed, like most other functions are allowed, to clobber errno with any nonzero value, but this is not "setting" it in the sense of providing a meaningful value.) You need to save the return value and use that, not errno, as the error code to report.

Upvotes: 0

Related Questions