Monday, December 31, 2018

Scheduling of Linux threads based on priorities.

Thread priorities do work on most OS's but they often have minimal effect. Priorities help to order the threads that are in the run queue only and will not change how often the threads are run in any major may unless you are doing a ton of CPU in each of the threads.
Unless you have fewer cores than there are threads, you may not see any change in output order by setting your thread priorities. If there is a free CPU then even a lower priority thread will be scheduled to run.
Also, threads are never starved. Even a lower priority thread will be given time to run quite often in such a situation as this. You should see higher priority threads be given time sliced to run more often but it does not mean lower priority threads will wait for them to finish before running themselves.
Even if priorities do help to give one thread more CPU than the others, threaded programs are subject to race conditions which help inject a large amount of randomness to their execution. What you should see, is the max priority thread is more likely to spit out its message more often than the rest.

In modern computers, many processes run at once. Active processes are placed in an array called a run queue. The run queue may contain priority values for each process, which will be used by the scheduler to determine which process to run next
To ensure each program has a fair share of resources, each one is run for some time period (quantum) before it is paused and placed back into the run queue. When a program is stopped to let another run, the program with the highest priority in the run queue is then allowed to execute.

Processes are also removed from the run queue when they ask to sleep, are waiting on a resource to become available, or have been terminated.

In the Linux operating system (prior to kernel 2.6.23), each CPU in the system is given a run queue, which maintains both an active and expired array of processes. Each array contains 140 (one for each priority level) pointers to doubly linked lists, which in turn reference all processes with the given priority. The scheduler selects the next process from the active array with the highest priority. When a process' quantum expires, it is placed into the expired array with some priority. When the active array contains no more processes, the scheduler swaps the active and expired arrays, hence the name O(1) scheduler.



In UNIX or Linux, the sar command is used to check the run queue.

The vmstat UNIX or Linux command can also be used to determine the number of processes that are queued to run or waiting to run. These appear in the 'r' column.


There are two models for Run queues: one that assigns a Run Queue to each physical processor, and the other has only one Run Queue in the system


Why do we get random results (every time I run it changes):
The output from a threaded program is rarely if ever "perfect" because by definition the threads are running asynchronously. We want the output to be random because we want the threads to be running in parallel independently from each other. That is their power. If you expecting some precise output then you should not be using threads. Still, the following program will give you the desired result every time you run it.
#define _GNU_SOURCE // must be placed prior to sched.h
#include <stdio.h>
#include <linux/errno.h>
#include <pthread.h>
#include <sched.h>
#include <unistd.h>
#include <stdio.h>

void *thread1(void *null)
{
  int policy;
  struct sched_param param;

  pthread_getschedparam(pthread_self(), &policy, &param);
  // 0 - SCHED_OTHERS     1 - SCHED_FIFO          2 - SCHED_RR
  printf("\n thread 1 Current Thread Policy : %d Priority : %d\n", policy,
         param.sched_priority);

  sleep(5);
  pthread_getschedparam(pthread_self(), &policy, &param);
  // 0 - SCHED_OTHERS     1 - SCHED_FIFO          2 - SCHED_RR
  printf("\n thread 1 Current Thread Policy : %d Priority : %d\n", policy,
         param.sched_priority);
  __fpurge();
  pthread_exit(NULL);
}
void * thread2 (void *null)
{
  //printf("i am thread 2\n");
  int policy;
  struct sched_param param;

  pthread_getschedparam(pthread_self(), &policy, &param);
  // 0 - SCHED_OTHERS     1 - SCHED_FIFO          2 - SCHED_RR
  printf("\n thread 2 Current Thread Policy : %d Priority : %d\n", policy,
         param.sched_priority);
  sleep(5);
  pthread_getschedparam(pthread_self(), &policy, &param);
  // 0 - SCHED_OTHERS     1 - SCHED_FIFO          2 - SCHED_RR
  printf("\n thread 2 Current Thread Policy : %d Priority : %d\n", policy,
         param.sched_priority);
  __fpurge();
  pthread_exit(NULL);

}
int main()
{
  int inherit, policy, rc , status;
  pthread_t t1,t2;
  pthread_attr_t attr;
  struct sched_param param;

  pthread_attr_init(&attr);
  /* switch off sched inheritence from parent */
  pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);

  /* Set processor affinity */
  cpu_set_t mask;
  CPU_ZERO(&mask); // Clears set, so that it contains no CPUs.
  CPU_SET (1, &mask);  /* use only 1 CPU core */
  unsigned int len = sizeof(mask);
  status = sched_setaffinity(0, len, &mask);
  if (status < 0) perror("sched_setaffinity");
  status = sched_getaffinity(0, len, &mask);
  if (status < 0) perror("sched_getaffinity");


  /* Assign Sched policy and priority */
  policy = SCHED_FIFO;
  pthread_attr_setschedpolicy(&attr, policy);

  param.sched_priority = 10;
  pthread_attr_setschedparam(&attr, &param);

  /* create thread with choosen attribs */
  pthread_create(&t1, &attr, thread1, NULL);// t1 ie thread object gets initialised here
  pthread_create(&t2, &attr, thread2, NULL);
  /* destroy attribute object */
  pthread_attr_destroy(&attr);
  sleep(2);

/* FOR thread 2 */
  param.sched_priority = 17;
  policy = SCHED_RR;
  pthread_setschedparam(t2, policy, &param);

  /* FOR thread 1 */
  param.sched_priority = 16;
  //policy = SCHED_RR;
  pthread_setschedparam(t1, policy, &param);

  pthread_exit(NULL); // wait for all threads to terminate.

}


References:
1. http://www.informit.com/articles/article.aspx?p=101760&seqNum=2
2. https://en.wikipedia.org/wiki/Run_queue

Tuesday, January 2, 2018

Taxation on Debt and Liquid Funds

Example:
I am coming under tax bracket of 20per cent. If I invest R10 lakh in a liquid or ultra short term debt fund for 4 or 5 years how much tax do I have to pay? Please give your answer with numerical example.
- Ramesh M

If you sell them within 3 years, capital gains on debt funds are treated as short term. It will be added to your income and taxed as per your applicable tax slab. Long term capital gains (if exit is after 3 years) are taxed at 20 per cent with an indexation benefit on your cost.

Investment holding period Taxation
Short Term Capital Gain 36 months or lesser added to income and taxed as per applicable slab rate
Long Term Capital Gain more than 36 months                 20% with indexation

Let us take an example, Since we do not have the Cost Inflation Index for future years, we will take an example of past. Say you invested R10 lakhs in 2010-2011. Assuming the fund returned 9 percent a year, and you redeem it for R15,38,624 in 2016-17, your long term capital gain would be R5,38,624.

However, if you index the cost with the Cost Inflation Index (provided by the IT department) for 2010-11 and 2015-16, then the cost would be R1,52,0393 (R10 Lakh * 1081/711). Then the long term capital gain would be R18231 (1538624-1520393). A 20 percent tax on this would be R3646.

So, as per this example, your capital gains tax for this financial year will be R3646.


I want to know the taxation on liquid fund. If I sell liquid fund and generate gain, is it taxable?
- Vinod Mehra

Yes, capital gains on liquid funds are taxable.

If you sell your funds before three years (36 months), you will have to pay short-term capital gains tax. Short-term capital gains are added to your income and taxed as per the income tax slab applicable to you. If funds are held for more than three years, your gains will qualify for long-term capital gains tax of 20 per cent with indexation benefit on your original investment.

Links: http://cafemutual.com/news/guestcolumn/51-how-to-calculate-tax-on-mutual-funds