Can mutex and its locking and unlocking features be used in CLING interpreter?

Hi @bellenot and @vvassilev ,

I am trying syncronisation between two threads in a cpp script on CLING interpreter.
But, I see that, when I use mutex synchronisation using mtx.lock() and mtx.unlock() in the thread function and execute the scripts, the script terminates abruptly without getting completed.

Here is the script for reference that I am executing on CLING:

// C++ program to illustrate the race conditions 
//#include <iostream> 
#include <thread>
#include <mutex>
//#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <ctime>

//using namespace std; 

// Shared resource 
int number = 0; 

// Create object for mutex 
mutex mtx; 

// function to increment the number 
void increment(){ 
	
	// Lock the thread using lock 
    mtx.lock(); 
	
	// increment number by 1 for 1000000 times 
	for(int i=0; i<1000000; i++){ 
		number++; 
	} 
	
	// Release the lock using unlock() 
    mtx.unlock(); 
} 

int main() 
{ 
	// Create thread t1 to perform increment() 
	FILE* fptr= fopen("C:\\Release_NEW\\ThreadOutput_50\\sum.txt", "a");
	thread t1(increment); 
	
	// Create thread t2 to perform increment() 
	thread t2(increment); 
	
	// Start both threads simultaneously 
	t1.join(); 
	t2.join(); 
	
	// Print the number after the execution of both threads 
	//cout << "Number after execution of t1 and t2 is " << number; 
	fprintf(fptr, "%d", number);
	fputs("\n", fptr);
	fclose(fptr);
	
	return 0; 
}

Hi,

I cannot reproduce your issue with ROOT 6.30.06.
This is a formatted and simplified version of the code you nicely provided [1].
To help @vvassilev and @bellenot , perhaps could you be more explicit about the ROOT (or cling) version you are using? I assume you are on windows.

Cheers,
Danilo

[1]

int number = 0;

// Create object for mutex
mutex mtx;

// function to increment the number
void increment()
{

   // Lock the thread using lock
   mtx.lock();

   // increment number by 1 for 1000000 times
   for (int i = 0; i < 1000000; i++) {
      number++;
   }

   // Release the lock using unlock()
   mtx.unlock();
}

int a()
{
   // Create thread t1 to perform increment()
   FILE  *fptr = fopen("sum.txt", "a");
   thread t1(increment);

   // Create thread t2 to perform increment()
   thread t2(increment);

   // Start both threads simultaneously
   t1.join();
   t2.join();

   // Print the number after the execution of both threads
   // cout << "Number after execution of t1 and t2 is " << number;
   fprintf(fptr, "%d", number);
   fputs("\n", fptr);
   fclose(fptr);

   return 0;
}

Hi @Danilo ,
Yes I am on windows,
the cling version is as below;

cling.exe --version
1.0~dev

I can reproduce the issue on Windows. Investigating

Hi @bellenot ,

Any update related to this? Any possible solution here?

No, no solution foreseen for now. It looks like an issue between the interpreter and the runtime libraries. Need some time to figure out what the real issue is.

So this code:

#include <iostream> 
#include <thread>
#include <mutex>

int number = 0;

// Create object for mutex
std::mutex mtx;

// function to increment the number
void increment()
{
   // Lock the thread using lock
   mtx.lock();
   // increment number by 1 for 1000000 times
   for (int i = 0; i < 1000000; i++) {
      number++;
   }
   // Release the lock using unlock()
   mtx.unlock();
}

int b()
{
   // Create thread t1 to perform increment()
   std::thread t1(increment);
   // Create thread t2 to perform increment()
   std::thread t2(increment);
   // Start both threads simultaneously
   t1.join();
   t2.join();
   // Print the number after the execution of both threads
   std::cout << "Number after execution of t1 and t2 is " << number << std::endl;
   return 0;
}

works just fine with cling, llvm16, x64:

C:\root-dev\rootdev\forum>..\..\install\x64\cling\bin\cling

****************** CLING ******************
* Type C++ code and press enter to run it *
*             Type .q to exit             *
*******************************************
[cling]$ .x b.C
Number after execution of t1 and t2 is 2000000
(int) 0
[cling]$

And this works too:

#include <iostream> 
#include <thread>
#include <mutex>
#include <fstream>

int number = 0;

// Create object for mutex
std::mutex mtx;

// function to increment the number
void increment()
{
   // Lock the thread using lock
   mtx.lock();
   // increment number by 1 for 1000000 times
   for (int i = 0; i < 1000000; i++) {
      number++;
   }
   // Release the lock using unlock()
   mtx.unlock();
}

int a()
{
   // Create thread t1 to perform increment()
   std::thread t1(increment);
   // Create thread t2 to perform increment()
   std::thread t2(increment);
   // Start both threads simultaneously
   t1.join();
   t2.join();
   // Print the number after the execution of both threads
   std::cout << "Number after execution of t1 and t2 is " << number << std::endl;
   std::ofstream out;
   out.open("sum.txt", std::ios_base::app);
   out << number << std::endl;
   out.close();
   return 0;
}

It gives, after several executions:

C:\root-dev\rootdev\forum>..\..\install\x64\cling\bin\cling

****************** CLING ******************
* Type C++ code and press enter to run it *
*             Type .q to exit             *
*******************************************
[cling]$ .x a.C
Number after execution of t1 and t2 is 2000000
(int) 0
[cling]$ .!more sum.txt
2000000
2000000
2000000
2000000
[cling]$

Hi @bellenot ,
What version of cling version are you using here?

And, does it work fine on 32-bit CLING exe(x86) of the same version as well? Because, I need to use 32-bit CLING exe as all my DLL files are of 32 bit(x86 type)

I use the master branch of GitHub. And I didn’t try with 32 bit, I’ll try and let you know.

So yes, it works the same:

C:\root-dev\rootdev\forum>..\..\install\x86\cling\bin\cling.exe

****************** CLING ******************
* Type C++ code and press enter to run it *
*             Type .q to exit             *
*******************************************
[cling]$ .x a.C
Number after execution of t1 and t2 is 2000000
(int) 0
[cling]$ .! more sum.txt
2000000
2000000
2000000
2000000
2000000
2000000
[cling]$

Hi @bellenot ,

Thankyou for the response.
You are saying, you have built this working version of CLING from github and I have also built the CLING in a similar fashion by following the instructions at the below root forum page:

After building as per the above instructions, my CLING exe version is as below:
cling.exe --version
1.0~dev

Can you please let me know if the build instructions which I have followed is correct?
If not, please let me know the instructions, from where I can build the latest CLING version( which can support mutex locking and unlocking and all the other advanced features of C++) for Windows?

Hi @bellenot ,

Any update for the above query related to build instructions?

See Cling Build Instructions - ROOT
And adapt the following part of the recipe for Visual Studio:

mkdir build
cd build
cmake -G"Visual Studio 17 2022" -A x64 -Thost=x64 -DCMAKE_BUILD_TYPE=Release -DLLVM_BUILD_TOOLS=Off -DLLVM_EXTERNAL_PROJECTS=cling -DLLVM_EXTERNAL_CLING_SOURCE_DIR=../cling -DLLVM_ENABLE_PROJECTS=clang -DLLVM_TARGETS_TO_BUILD="host;NVPTX" src/llvm
cmake --build . --config Release

Hi @bellenot ,
I followed the instruction like you specified( I used Visual Studio 16 2019 instead of Visual Studio 17 2022;and -A Win32 instead of -A x64). Please find the below accurate list of instructions that I followed:

  1. Created a directory named CLING_Latest in C drive
    C:\CLING_Latest

  2. Go inside CLING_Latest directory using cd command

  3. git clone -b cling-llvm16 https://github.com/root-project/llvm-project.git src

  4. git clone https://github.com/root-project/cling.git

  5. mkdir build

  6. cd build

  7. C:\CMake\bin\cmake -G"Visual Studio 16 2019" -A Win32 -Thost=x64 -DCMAKE_BUILD_TYPE=Release -DLLVM_BUILD_TOOLS=Off -DLLVM_EXTERNAL_PROJECTS=cling -DLLVM_EXTERNAL_CLING_SOURCE_DIR=…/cling -DLLVM_ENABLE_PROJECTS=clang -DLLVM_TARGETS_TO_BUILD=“host;NVPTX” …/src/llvm

  8. C:\CMake\bin\cmake --build . --config Release

CLING utility was built and the version is as below:
C:\CLING_Latest\build\Release\bin>cling.exe --version
1.1~dev

Even, with this version of CLING, I am finding the same issue of abrupt CLING exe closure when mutex lock and unlock is used.

Please confirm for the build instructions

It looks fine

With my examples? Then it’s maybe a problem with VS 2019… I can make some tests later if you confirm you have the same error with my examples