11// This file is a part of Julia. License is MIT: https://julialang.org/license
22
3+ #include < cstdint>
4+ #include < pthread.h>
35#include < string>
46#include < fstream>
57#include < map>
1517
1618using namespace llvm ;
1719
18- static int codegen_imaging_mode (void )
20+ static int codegen_imaging_mode (void ) JL_NOTSAFEPOINT
1921{
2022 return jl_options.image_codegen || (jl_generating_output () && jl_options.use_pkgimages );
2123}
@@ -26,7 +28,9 @@ const int logdata_blocksize = 32; // target getting nearby lines in the same gen
2628typedef uint64_t logdata_block[logdata_blocksize];
2729typedef StringMap< SmallVector<logdata_block*, 0 > > logdata_t ;
2830
29- static uint64_t *allocLine (SmallVector<logdata_block*, 0 > &vec, int line)
31+ pthread_mutex_t coverage_lock = PTHREAD_MUTEX_INITIALIZER;
32+
33+ static uint64_t *allocLine (SmallVector<logdata_block*, 0 > &vec, int line) JL_NOTSAFEPOINT
3034{
3135 unsigned block = line / logdata_blocksize;
3236 line = line % logdata_blocksize;
@@ -45,39 +49,49 @@ static uint64_t *allocLine(SmallVector<logdata_block*, 0> &vec, int line)
4549
4650static logdata_t coverageData;
4751
48- JL_DLLEXPORT void jl_coverage_alloc_line (StringRef filename, int line)
52+ JL_DLLEXPORT void jl_coverage_alloc_line (StringRef filename, int line) JL_NOTSAFEPOINT
4953{
5054 assert (!codegen_imaging_mode ());
5155 if (filename == " " || filename == " none" || filename == " no file" || filename == " <missing>" || line < 0 )
5256 return ;
57+ pthread_mutex_lock (&coverage_lock);
5358 allocLine (coverageData[filename], line);
59+ pthread_mutex_unlock (&coverage_lock);
5460}
5561
56- JL_DLLEXPORT uint64_t *jl_coverage_data_pointer (StringRef filename, int line)
62+ JL_DLLEXPORT uint64_t *jl_coverage_data_pointer (StringRef filename, int line) JL_NOTSAFEPOINT
5763{
58- return allocLine (coverageData[filename], line);
64+ pthread_mutex_lock (&coverage_lock);
65+ uint64_t * ret = allocLine (coverageData[filename], line);
66+ pthread_mutex_unlock (&coverage_lock);
67+ return ret;
5968}
6069
61- extern " C" JL_DLLEXPORT void jl_coverage_visit_line (const char *filename_, size_t len_filename, int line)
70+ extern " C" JL_DLLEXPORT void jl_coverage_visit_line (const char *filename_, size_t len_filename, int line) JL_NOTSAFEPOINT
6271{
6372 StringRef filename = StringRef (filename_, len_filename);
6473 if (codegen_imaging_mode () || filename == " " || filename == " none" || filename == " no file" || filename == " <missing>" || line < 0 )
6574 return ;
75+ pthread_mutex_lock (&coverage_lock);
6676 SmallVector<logdata_block*, 0 > &vec = coverageData[filename];
6777 uint64_t *ptr = allocLine (vec, line);
6878 (*ptr)++;
79+ pthread_mutex_unlock (&coverage_lock);
6980}
7081
7182// Memory allocation log (malloc_log)
7283
7384static logdata_t mallocData;
7485
75- JL_DLLEXPORT uint64_t *jl_malloc_data_pointer (StringRef filename, int line)
86+ JL_DLLEXPORT uint64_t *jl_malloc_data_pointer (StringRef filename, int line) JL_NOTSAFEPOINT
7687{
77- return allocLine (mallocData[filename], line);
88+ pthread_mutex_lock (&coverage_lock);
89+ uint64_t * ret = allocLine (mallocData[filename], line);
90+ pthread_mutex_unlock (&coverage_lock);
91+ return ret;
7892}
7993
80- static void clear_log_data (logdata_t &logData, int resetValue)
94+ static void clear_log_data (logdata_t &logData, int resetValue) JL_NOTSAFEPOINT
8195{
8296 logdata_t ::iterator it = logData.begin ();
8397 for (; it != logData.end (); it++) {
@@ -97,18 +111,22 @@ static void clear_log_data(logdata_t &logData, int resetValue)
97111}
98112
99113// Resets the malloc counts.
100- extern " C" JL_DLLEXPORT void jl_clear_malloc_data (void )
114+ extern " C" JL_DLLEXPORT void jl_clear_malloc_data (void ) JL_NOTSAFEPOINT
101115{
116+ pthread_mutex_lock (&coverage_lock);
102117 clear_log_data (mallocData, 1 );
118+ pthread_mutex_unlock (&coverage_lock);
103119}
104120
105121// Resets the code coverage
106- extern " C" JL_DLLEXPORT void jl_clear_coverage_data (void )
122+ extern " C" JL_DLLEXPORT void jl_clear_coverage_data (void ) JL_NOTSAFEPOINT
107123{
124+ pthread_mutex_lock (&coverage_lock);
108125 clear_log_data (coverageData, 0 );
126+ pthread_mutex_unlock (&coverage_lock);
109127}
110128
111- static void write_log_data (logdata_t &logData, const char *extension)
129+ static void write_log_data (logdata_t &logData, const char *extension) JL_NOTSAFEPOINT
112130{
113131 std::string base = std::string (jl_options.julia_bindir );
114132 base = base + " /../share/julia/base/" ;
@@ -163,7 +181,7 @@ static void write_log_data(logdata_t &logData, const char *extension)
163181 }
164182}
165183
166- static void write_lcov_data (logdata_t &logData, const std::string &outfile)
184+ static void write_lcov_data (logdata_t &logData, const std::string &outfile) JL_NOTSAFEPOINT
167185{
168186 std::ofstream outf (outfile.c_str (), std::ofstream::ate | std::ofstream::out | std::ofstream::binary);
169187 // std::string base = std::string(jl_options.julia_bindir);
@@ -203,8 +221,9 @@ static void write_lcov_data(logdata_t &logData, const std::string &outfile)
203221 outf.close ();
204222}
205223
206- extern " C" JL_DLLEXPORT void jl_write_coverage_data (const char *output)
224+ extern " C" JL_DLLEXPORT void jl_write_coverage_data (const char *output) JL_NOTSAFEPOINT
207225{
226+ pthread_mutex_lock (&coverage_lock);
208227 if (output) {
209228 StringRef output_pattern (output);
210229 if (output_pattern.ends_with (" .info" ))
@@ -215,11 +234,14 @@ extern "C" JL_DLLEXPORT void jl_write_coverage_data(const char *output)
215234 raw_string_ostream (stm) << " ." << uv_os_getpid () << " .cov" ;
216235 write_log_data (coverageData, stm.c_str ());
217236 }
237+ pthread_mutex_unlock (&coverage_lock);
218238}
219239
220- extern " C" void jl_write_malloc_log (void )
240+ extern " C" void jl_write_malloc_log (void ) JL_NOTSAFEPOINT
221241{
242+ pthread_mutex_lock (&coverage_lock);
222243 std::string stm;
223244 raw_string_ostream (stm) << " ." << uv_os_getpid () << " .mem" ;
224245 write_log_data (mallocData, stm.c_str ());
246+ pthread_mutex_unlock (&coverage_lock);
225247}
0 commit comments