LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel
User Name
Password
Linux - Kernel This forum is for all discussion relating to the Linux kernel.

Notices


Reply
  Search this Thread
Old 03-11-2009, 08:40 PM   #1
tara
Member
 
Registered: Aug 2005
Location: Australia
Distribution: Centos 7
Posts: 58

Rep: Reputation: 15
Question Scheduling, sigaction - program no longer works after change of kernel


Hi,

I use to run Mandrake 10.2 kernel 2.6.11-6.
I now run Mandriva 2007.1 kernel 2.6.17-14.

I am new to scheduling, i have taken over looking after a test program that every 1 second will output up to 1000 udp data messages (each packet 46 bytes). The program was written using scheduling and using a nanosleep to try to balance the load of the data across 1 second as best it could by (to avoid it overwritting data in the buffer as all 1000 data message were being output in 0.01 of a second.)
Without the nanosleep in the code in the loop that outputs the data the 1000 data messages all come out in 0.03, which is fine, but tcpdump can only record approximately 630, so the rest are being overwritten.

In Mandrake 10.2 the scheduling all worked fine, the data would be spread across 1 second. A change to Mandriva 2007.1 with a new kernel has resulted in the data spreading across 4-5 seconds now and that is not exceptable, it must be 1 second or less.
The source code has not changed at all, the only change is kernel and o/s.

Any ideas would be greatly appreciated.

In the code where it states "do stuff" i have removed a part of the code as it is not important to this problem, the .h file is also in this boat.

thank you
Tara

p.s. Some Qt is used in the code.

Code:
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <qapplication.h>
#include <qdir.h>
#include <qsettings.h>
#include <qstring.h>
#include <time.h>
#include <sched.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <iostream>
#include <fstream>
#include "Log.h"
#include "Profiler.h"
#include "loadtest.h"

using namespace std;

int no_of_points;
struct sockaddr_in addr;
struct ip_mreq mreq;
Profiler profiler;
struct timespec delay;

void onTimer(int);

int main(int argc, char **argv)
{


  struct itimerval timer;
  struct itimerval otimer;
  struct sigaction action;
  struct sigaction oaction;

  struct sched_param param;

  struct tm *t;
 
  Q_UINT16 Port;

  QSettings settings;  

  QString Dir = QDir::currentDirPath();
  settings.insertSearchPath(QSettings::Unix, Dir);

  if(argc < 4)
  {
    cout << "Not enough params: loadtest <inifile> <number of data> <delay>" << endl;
    exit(1);
  }

  printf("Max Priority %d Min Priority %d\n", sched_get_priority_max(SCHED_FIFO), sched_get_priority_min(SCHED_FIFO));

  param.sched_priority = 1;

  if(sched_setscheduler(0, SCHED_FIFO, &param) == -1)
  {
    perror("sched_setscheduler");
  }

  delay.tv_sec = 0;
  delay.tv_nsec = atoi(argv[3]) * 1000;


  if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
  {
    perror("socket");
    exit(1);
  }

  //read in the ip address from the rc file
  QString file(argv[1]);
  QString address = settings.readEntry(QString(file) + "/common/ip");
  Port = settings.readNumEntry(file + "/common/port");

  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = inet_addr(address);
  addr.sin_port = htons(Port);

  // setup the signal handler 

  action.sa_handler = onTimer;
  sigemptyset(&action.sa_mask);
  action.sa_flags = 0;
  sigaction(SIGALRM, &action, &oaction);

  timer.it_interval.tv_sec = 1;
  timer.it_interval.tv_usec = 0;
  timer.it_value.tv_sec = 1;
  timer.it_value.tv_usec = 0; 

  Data = atoi(argv[2]);

  
  for(int p = 0; p < Data; p++)
  {
    try
    {
      //do stuff
      new Mess;
    }
    catch(std::bad_alloc)
    {
      cout << "Bad Alloc" << endl;
    }
    catch(...)
    {
      cout << "Unknown" << endl;
    }

    try
    {
      //do more stuff
    }
    catch(EAsterixObject & e)
    {
      std::cout << time
        << "Untrapped Asterix Exception: " << e.what() << std::endl
        << "Exiting" << std::endl;
    }
    catch(std::exception & e)
    {
      std::cout << time
        << "Untrapped standard Exception: " << e.what() << std::endl
        << "Exiting" << std::endl;
    }
    catch(...)
    {
      std::cout << time
        << "Unknown Exception caught!" << std::endl << "Exiting" << std::endl;
    }
  }

  setitimer(ITIMER_REAL, &timer, &otimer);

  while(1)
    pause();

  return 0;
}

void onTimer(int a)
{
  profiler.start();
  struct timeval now;
  struct tm *t;
  time_t midnight;

  // calculate time at midnight

  gettimeofday(&now, NULL);
  t = gmtime(&now.tv_sec);
  t->tm_sec = 0;
  t->tm_min = 0;
  t->tm_hour = 0;
  midnight = mktime(t);

  for(int p = 0; p < NumTrack; p++)
  {
   //do stuff

    if(sendto(fd, Message, Mess[p].record->getLength() + 3, 0, (struct sockaddr *)&addr, sizeof(addr)) < 0)
    {
      perror("sendto");
    }

    nanosleep(&delay, NULL);
  }

  secs++;
  cout << "Loop time " << profiler.elapsed() << std::endl;
}
 
Old 03-12-2009, 06:58 AM   #2
sunr2007
Member
 
Registered: Jan 2009
Location: Bangalore , India
Distribution: Fedora 12
Posts: 65

Rep: Reputation: 17
Quote:
Originally Posted by tara View Post
Hi,

I use to run Mandrake 10.2 kernel 2.6.11-6.
I now run Mandriva 2007.1 kernel 2.6.17-14.

I am new to scheduling, i have taken over looking after a test program that every 1 second will output up to 1000 udp data messages (each packet 46 bytes). The program was written using scheduling and using a nanosleep to try to balance the load of the data across 1 second as best it could by (to avoid it overwritting data in the buffer as all 1000 data message were being output in 0.01 of a second.)
Without the nanosleep in the code in the loop that outputs the data the 1000 data messages all come out in 0.03, which is fine, but tcpdump can only record approximately 630, so the rest are being overwritten.

In Mandrake 10.2 the scheduling all worked fine, the data would be spread across 1 second. A change to Mandriva 2007.1 with a new kernel has resulted in the data spreading across 4-5 seconds now and that is not exceptable, it must be 1 second or less.
The source code has not changed at all, the only change is kernel and o/s.

Any ideas would be greatly appreciated.

In the code where it states "do stuff" i have removed a part of the code as it is not important to this problem, the .h file is also in this boat.

thank you
Tara

p.s. Some Qt is used in the code.

Code:
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <qapplication.h>
#include <qdir.h>
#include <qsettings.h>
#include <qstring.h>
#include <time.h>
#include <sched.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <iostream>
#include <fstream>
#include "Log.h"
#include "Profiler.h"
#include "loadtest.h"

using namespace std;

int no_of_points;
struct sockaddr_in addr;
struct ip_mreq mreq;
Profiler profiler;
struct timespec delay;

void onTimer(int);

int main(int argc, char **argv)
{


  struct itimerval timer;
  struct itimerval otimer;
  struct sigaction action;
  struct sigaction oaction;

  struct sched_param param;

  struct tm *t;
 
  Q_UINT16 Port;

  QSettings settings;  

  QString Dir = QDir::currentDirPath();
  settings.insertSearchPath(QSettings::Unix, Dir);

  if(argc < 4)
  {
    cout << "Not enough params: loadtest <inifile> <number of data> <delay>" << endl;
    exit(1);
  }

  printf("Max Priority %d Min Priority %d\n", sched_get_priority_max(SCHED_FIFO), sched_get_priority_min(SCHED_FIFO));

  param.sched_priority = 1;

  if(sched_setscheduler(0, SCHED_FIFO, &param) == -1)
  {
    perror("sched_setscheduler");
  }

  delay.tv_sec = 0;
  delay.tv_nsec = atoi(argv[3]) * 1000;


  if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
  {
    perror("socket");
    exit(1);
  }

  //read in the ip address from the rc file
  QString file(argv[1]);
  QString address = settings.readEntry(QString(file) + "/common/ip");
  Port = settings.readNumEntry(file + "/common/port");

  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = inet_addr(address);
  addr.sin_port = htons(Port);

  // setup the signal handler 

  action.sa_handler = onTimer;
  sigemptyset(&action.sa_mask);
  action.sa_flags = 0;
  sigaction(SIGALRM, &action, &oaction);

  timer.it_interval.tv_sec = 1;
  timer.it_interval.tv_usec = 0;
  timer.it_value.tv_sec = 1;
  timer.it_value.tv_usec = 0; 

  Data = atoi(argv[2]);

  
  for(int p = 0; p < Data; p++)
  {
    try
    {
      //do stuff
      new Mess;
    }
    catch(std::bad_alloc)
    {
      cout << "Bad Alloc" << endl;
    }
    catch(...)
    {
      cout << "Unknown" << endl;
    }

    try
    {
      //do more stuff
    }
    catch(EAsterixObject & e)
    {
      std::cout << time
        << "Untrapped Asterix Exception: " << e.what() << std::endl
        << "Exiting" << std::endl;
    }
    catch(std::exception & e)
    {
      std::cout << time
        << "Untrapped standard Exception: " << e.what() << std::endl
        << "Exiting" << std::endl;
    }
    catch(...)
    {
      std::cout << time
        << "Unknown Exception caught!" << std::endl << "Exiting" << std::endl;
    }
  }

  setitimer(ITIMER_REAL, &timer, &otimer);

  while(1)
    pause();

  return 0;
}

void onTimer(int a)
{
  profiler.start();
  struct timeval now;
  struct tm *t;
  time_t midnight;

  // calculate time at midnight

  gettimeofday(&now, NULL);
  t = gmtime(&now.tv_sec);
  t->tm_sec = 0;
  t->tm_min = 0;
  t->tm_hour = 0;
  midnight = mktime(t);

  for(int p = 0; p < NumTrack; p++)
  {
   //do stuff

    if(sendto(fd, Message, Mess[p].record->getLength() + 3, 0, (struct sockaddr *)&addr, sizeof(addr)) < 0)
    {
      perror("sendto");
    }

    nanosleep(&delay, NULL);
  }

  secs++;
  cout << "Loop time " << profiler.elapsed() << std::endl;
}
I would to suggest u to look at options required to enable in your kernel by using menuconfig. it some time happens that some options of a same distro are not enabled in different versions.
 
Old 03-12-2009, 05:50 PM   #3
tara
Member
 
Registered: Aug 2005
Location: Australia
Distribution: Centos 7
Posts: 58

Original Poster
Rep: Reputation: 15
I have run make meunconfig and have found the following

Processor type and features> Preemption Mode

Preemption Mode is set to "No Forced Preemption (Server))"

i believe it should be set to "(Complete Preemption (Real-Time))", but this option is missing from the list of expected 4 options (my list only has 3, No forced preemption, Voluntary Kernel and Preemptible Kernel)

Do I need to have the kernel-rt-source-2.6.17.14 installed not just linux-2.6.17-14mdv? Only problem i have is that this does not seem to exist... or is there a different rpm or patch that can do this?

Is it possible to use one of the other Preemption mode options?


Excuse any stupid comments, this is the first time i have done anything like this.

Thanks
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Kernel Update - Ndiswrapper no longer works Speng Linux - Wireless Networking 1 01-17-2009 01:32 AM
/dev/input/mice no longer works after kernel update Namegduf Live Linux - Hardware 0 03-18-2007 01:48 AM
How do I change scheduling priorities? (2.6 kernel) prcarp Programming 3 04-19-2006 03:24 AM
Debian: Upgrade to 2.6.4 Kernel, SMC Card No Longer Works pfizur Linux - Networking 0 04-08-2004 07:51 AM
Upgraded Kernel 2 2.6.3 But mouse no longer works :( londonboi Debian 2 03-15-2004 07:56 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel

All times are GMT -5. The time now is 05:33 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration