0

I decided to simplify my other post, simplifying the code so that it will be easier for you to help me.

So, the objective of the code is to run 3 threads using only 1 core, so that i can use it to schedule tasks, and to measure computation and response times. Each one have different priorities so that there's always only 1 thread running.

Instead, the 3 threads run at the same time, so that I can conclude that the there are at least 3 cores being used by the program.

There's the code: #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include

    #define SCHED SCHED_FIFO

    #define NUM_THREADS 3
    #include "func.h"

    struct timespec start1;
    int result_code;

    void *ff1(void* arg){
            u_int64_t diff;
            struct timespec start, end;
            struct sched_param param;

            // Periority
            param.sched_priority=sched_get_priority_max(SCHED_FIFO);
            result_code = sched_setscheduler(0,SCHED,&param);
            assert(!result_code);

            printf("Running Task 1\n");

            clock_gettime(CLOCK_MONOTONIC, &start);
            f1(1,5);    
            clock_gettime(CLOCK_MONOTONIC, &end);

            diff = pow(10,9) * (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec);
        printf("1st Task elapsed time = %ld ns => %f s\n", diff, diff / (pow(10,9)));


        diff = pow(10,9) * (end.tv_sec - start1.tv_sec) + (end.tv_nsec - start1.tv_nsec);
        printf("1st Task response time = %ld ns => %f s\n", diff, diff / (pow(10,9)));

            printf("Task 1 finished\n");

    }

    void *ff2 (void* arg){
            u_int64_t diff;
            struct timespec start, end;
            struct sched_param param;

            // sched
            param.sched_priority=sched_get_priority_max(SCHED_FIFO)-1;
            result_code = sched_setscheduler(0,SCHED,&param);
            assert(!result_code);

            printf("Running Task 2\n");

            clock_gettime(CLOCK_MONOTONIC, &start);
            f2(1,5);    
            clock_gettime(CLOCK_MONOTONIC, &end);

            diff = pow(10,9) * (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec);
           printf("2nd Task elapsed time = %ld ns => %f s\n", diff, diff / (pow(10,9)));

           diff = pow(10,9) * (end.tv_sec - start1.tv_sec) + (end.tv_nsec - start1.tv_nsec);
           printf("2nd Task response time = %ld ns => %f s\n", diff, diff / (pow(10,9)));

            printf("Task 2 finished\n");
    }

    void *ff3 (void* arg){
            u_int64_t diff;
            struct timespec start, end;
            struct sched_param param;

            // sched
            param.sched_priority=sched_get_priority_max(SCHED_FIFO)-2;
            result_code = sched_setscheduler(0,SCHED,&param);
            assert(!result_code);

            printf("Running Task 3\n");

            clock_gettime(CLOCK_MONOTONIC, &start);
            f3(1,5);    
            clock_gettime(CLOCK_MONOTONIC, &end);

            diff = pow(10,9) * (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec);
           printf("3rd Task elapsed time = %ld ns => %f s\n", diff, diff / (pow(10,9)));

           // Cálculo do tempo de resposta da tarefa 2
           diff = pow(10,9) * (end.tv_sec - start1.tv_sec) + (end.tv_nsec - start1.tv_nsec);
           printf("3rd Task response time = %ld ns => %f s\n", diff, diff / (pow(10,9)));

            printf("Task 3 finished\n");

    }

    int main(){
            pthread_t threads[3];
            short i;


            // Affinity
            cpu_set_t mask;
            CPU_ZERO(&mask);
            CPU_SET(0,&mask);
            result_code = sched_setaffinity(0, sizeof(cpu_set_t), &mask);
            assert(!result_code);

            pthread_attr_t attr[3];


            // Start time
            clock_gettime(CLOCK_MONOTONIC, &start1);

            for (i = 0; i < 3; i++){
                result_code = pthread_attr_init(&attr[i]);
                assert(!result_code);

                result_code = pthread_attr_setaffinity_np(&attr[i], sizeof(cpu_set_t), &mask);
                assert(!result_code);
            }

            result_code=pthread_create(&threads[0],&attr[0],&ff1,NULL);
                assert(!result_code);
            result_code=pthread_create(&threads[1],&attr[1],&ff2,NULL);
                assert(!result_code);
            result_code=pthread_create(&threads[2],&attr[2],&ff3,NULL);
                assert(!result_code);

            //wait for each thread to complete
            for(i=0;i<NUM_THREADS;i++){
                result_code=pthread_join(threads[i],NULL);
                assert(!result_code);
            }

            printf("Main -> Finished\n");

            return(EXIT_SUCCESS);
    }

The file func.h got the followed functions:

f1(int, int);
f2(int, int);
f3(int, int);

The object file was given by the teacher so all i can do is to upload it for you guys to download. The functions only do some tasks for some miliseconds.

func.o: https://ufile.io/uzhwf Note: I had an previous post that was too confusing (sorry, first time posting on Stackoverflow). Thanks everyone that spent some time trying to help me.

UPDATE: Updated the code and uploaded func.o. UPDATE1: Added some error checks and changed the sched_priority using sched_get_priority_max. Now it i get a "core dumped" in ff3 (function)'s sched_setscheduler.

  • We prefer that you edit the question rather than delete it and start a new one. The original question's comments and editing history can be useful so we don't repeat the same issues. – Barmar Oct 12 '18 at 21:20
  • You're right, thanks for the tip. – Dylan Lopes Oct 12 '18 at 21:21
  • that's true pm100, but i used pthread_attr_setaffinity_np to limit the number of cores used by the program – Dylan Lopes Oct 12 '18 at 21:23
  • 1
    In particular, another thread can run on the same core when it calls `sleep()`. Priority only matters if all the threads are actually trying to use the CPU. – Barmar Oct 12 '18 at 21:23
  • oh that's right lemme check that Barmar – Dylan Lopes Oct 12 '18 at 21:24
  • You should use mutual exclusion to control which thread runs when. Maybe a semaphore is what you need. – Barmar Oct 12 '18 at 21:25
  • the objetive is to use a object file given by the teacher that does tasks for a specific time, but even with those functions instead of sleep it works badly – Dylan Lopes Oct 12 '18 at 21:29
  • the code is updated. We can check that the 3 threads are running the same time comparing response time with computation time – Dylan Lopes Oct 12 '18 at 21:44

1 Answers1

0

So, the objective of the code is to run 3 threads using only 1 core, so that i can use it to schedule tasks, and to measure computation and response times.

If you limit to one core, then at most one thread will be running at a time. But that doesn't prevent the core from switching from one task to another rapidly or slowly.

Each one have different priorities so that there's always only 1 thread running.

That's not how priorities work. If you assign someone three tasks and tell them that one of them is lower priority, that does not mean they will do no work on that task until the others are complete. That means they will prefer to do other tasks when they have a choice. But sometimes they won't have a choice.

In your code, when one thread is sleeping, the core cannot make forward progress on that task until the sleep is complete. So it may have to make progress on a lower-priority task. If you don't want a task to be done at all until something happens, don't ask the system to do that task until you want it to be done.

It's not clear what your actual goal is, so it's not obvious what advice to give you. But if you absolutely must prevent some work from being done, you must clearly write code that prevents that code from executing by waiting for something else to happen before executing that code.

It seems counter-productive to create three threads if you don't want one of those threads to do any work until one of the others finishes. If you have work that you want to be done purely serially, have the same thread do it.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • you guys are right, let me edit so that you'll all understand, thanks for the explanation – Dylan Lopes Oct 12 '18 at 21:34
  • the code is updated. We can check that the 3 threads are running the same time comparing response time with computation time – Dylan Lopes Oct 12 '18 at 21:44
  • You don't do any error checking. For example, you don't check if `sched_setscheduler` succeeds. Also, you don't start timing until the task has started, so you're not measuring time waiting for other tasks to finish before starting. – David Schwartz Oct 12 '18 at 21:59
  • ok ill do the rest of error checking. On the other hand, 'start1' measure the time once the program is started so that i can measure the response time (task has finished - program's start time measurement) – Dylan Lopes Oct 12 '18 at 22:00
  • @DylanLopes Yep, so your call to set the scheduler was failing. Follow the documentation to figure out why. I'm betting it's EPERM. – David Schwartz Oct 12 '18 at 23:10
  • thanks for the tip. I read the manuals, tried 'pthread_setschedparam' but its still bugged, im trying to use sched_setattr but I can't use it right. Do you have any tip on how can I solve this bug? thanks for all you help – Dylan Lopes Oct 13 '18 at 00:42
  • Update: i followed this guide: https://stackoverflow.com/questions/45692699/build-against-newer-linux-headers-than-libc-is-built-using/45693337#45693337; when attr got the default settings it works, but once i change its priority or policy it crashes. – Dylan Lopes Oct 13 '18 at 01:06