Search code examples
processsimultaneoussimgrid

How to properly set properties simultaneously in SimGrid?


There is a process which launches 100 processes:

for (int i = 0; i < 100; ++i) {
        MSG_process_create("w", executor, NULL, MSG_host_self());
    }

An executor creates sample task and execute it. So there are 100 processes which start to execute task at the same time and finish to do it simultaneously. For monitoring the number of processes I have void plusOneActiveProcess() and void minusOneActiveProcess():

Because of all executor processes start simultaneously everything is OK:

[  0.000000] (2:w@Worker) Active process amount is 1
[  0.000000] (3:w@Worker) Active process amount is 2
[  0.000000] (4:w@Worker) Active process amount is 3
....................................................
[  0.000000] (101:w@Worker) Active process amount is 100

Each of processes should decrease(as I expected) step by step amount of active processes when executor finished to execute task. But it didn't happen:

[100.000000] (101:w@Worker) Active process amount is 99
[100.000000] (2:w@Worker) Active process amount is 99
[100.000000] (3:w@Worker) Active process amount is 99
....................................................
[100.000000] (100:w@Worker) Active process amount is 99

How to do it properly?

This is the code of functions plusOneActiveProcess(), minusOneActiveProcess, executor():

int executor(){
    plusOneActiveProcess();
    msg_error_t a = MSG_task_execute(MSG_task_create("", 1e9, 0, NULL));
    minusOneActiveProcess();
    MSG_process_kill(MSG_process_self());
    return 0;
}

void plusOneActiveProcess(){
    char kot[50];
    long number;
    number = xbt_str_parse_int(MSG_host_get_property_value(MSG_host_self(), "activeProcess"), "error");
    number++;
    sprintf(kot, "%ld", number);
    MSG_host_set_property_value(MSG_host_self(), "activeProcess", xbt_strdup(kot), NULL);
    XBT_INFO("Active process amount is %s", MSG_host_get_property_value(MSG_host_self(), "activeProcess"));
    memset(kot, 0, 50);
}

void minusOneActiveProcess(){
    char kot[50];
    long number;
    number = xbt_str_parse_int(MSG_host_get_property_value(MSG_host_self(), "activeProcess"), "error");
    number--;
    sprintf(kot, "%ld", number);
    MSG_host_set_property_value(MSG_host_self(), "activeProcess", xbt_strdup(kot), NULL);
    //XBT_INFO("Active process amount is %s", MSG_host_get_property_value(MSG_host_self(), "activeProcess"));
    memset(kot, 0, 50);
}

Solution

  • Aha, that's interesting. The thing is that set_property() is a SimGrid simcall, so you have the guarantee that all calls to set_property() will always be linearized in the same order. But get_property() is a regular function call that returns the value at the beginning of the scheduling round. Since all processes ask the value in the same scheduling round, they all get the same value (which is 100), decrement it and then do the simcall to push the new value (all processes want to push 99).

    You want to make the get+set atomic, ie make sure that any process pushes the updated value before someone else does the get_property(). For that, I advise to use SimGrid Mutexes or something.