27
27
#endif
28
28
#include " julia_assert.h"
29
29
30
+ #include < mutex>
31
+ #include < condition_variable>
32
+ #include < thread>
33
+
30
34
namespace {
31
35
32
36
static size_t get_block_size (size_t size)
@@ -763,8 +767,10 @@ class RTDyldMemoryManagerJL : public SectionMemoryManager {
763
767
RWAllocator rw_alloc;
764
768
std::unique_ptr<ROAllocator<false >> ro_alloc;
765
769
std::unique_ptr<ROAllocator<true >> exe_alloc;
766
- bool code_allocated ;
770
+ std::thread::id allocating_thread ;
767
771
size_t total_allocated;
772
+ std::mutex mutex;
773
+ std::condition_variable freed;
768
774
769
775
public:
770
776
RTDyldMemoryManagerJL ()
@@ -773,8 +779,9 @@ class RTDyldMemoryManagerJL : public SectionMemoryManager {
773
779
rw_alloc(),
774
780
ro_alloc(),
775
781
exe_alloc(),
776
- code_allocated(false ),
777
- total_allocated(0 )
782
+ allocating_thread(),
783
+ total_allocated(0 ),
784
+ mutex()
778
785
{
779
786
#ifdef _OS_LINUX_
780
787
if (!ro_alloc && get_self_mem_fd () != -1 ) {
@@ -790,7 +797,10 @@ class RTDyldMemoryManagerJL : public SectionMemoryManager {
790
797
~RTDyldMemoryManagerJL () override
791
798
{
792
799
}
793
- size_t getTotalBytes () { return total_allocated; }
800
+ size_t getTotalBytes () {
801
+ std::lock_guard<std::mutex> lock (mutex);
802
+ return total_allocated;
803
+ }
794
804
void registerEHFrames (uint8_t *Addr, uint64_t LoadAddr,
795
805
size_t Size) override ;
796
806
#if 0
@@ -811,6 +821,7 @@ class RTDyldMemoryManagerJL : public SectionMemoryManager {
811
821
template <typename DL, typename Alloc>
812
822
void mapAddresses (DL &Dyld, Alloc &&allocator)
813
823
{
824
+ std::lock_guard<std::mutex> lock (mutex);
814
825
for (auto &alloc: allocator->allocations ) {
815
826
if (alloc.rt_addr == alloc.wr_addr || alloc.relocated )
816
827
continue ;
@@ -830,6 +841,7 @@ class RTDyldMemoryManagerJL : public SectionMemoryManager {
830
841
template <typename Alloc>
831
842
void *lookupWriteAddressFor (void *rt_addr, Alloc &&allocator)
832
843
{
844
+ std::lock_guard<std::mutex> lock (mutex);
833
845
for (auto &alloc: allocator->allocations ) {
834
846
if (alloc.rt_addr == rt_addr) {
835
847
return alloc.wr_addr ;
@@ -855,9 +867,13 @@ uint8_t *RTDyldMemoryManagerJL::allocateCodeSection(uintptr_t Size,
855
867
unsigned SectionID,
856
868
StringRef SectionName)
857
869
{
858
- // allocating more than one code section can confuse libunwind.
859
- assert (!code_allocated);
860
- code_allocated = true ;
870
+ std::unique_lock<std::mutex> lock (mutex);
871
+ if (allocating_thread != std::thread::id ()) {
872
+ assert (allocating_thread != std::this_thread::get_id () && " allocating more than one code section can confuse libunwind!" );
873
+ // Will deadlock if the above assert is removed
874
+ freed.wait (lock, [&](){ return allocating_thread == std::thread::id (); });
875
+ }
876
+ allocating_thread = std::this_thread::get_id ();
861
877
total_allocated += Size;
862
878
if (exe_alloc)
863
879
return (uint8_t *)exe_alloc->alloc (Size, Alignment);
@@ -871,6 +887,7 @@ uint8_t *RTDyldMemoryManagerJL::allocateDataSection(uintptr_t Size,
871
887
StringRef SectionName,
872
888
bool isReadOnly)
873
889
{
890
+ std::lock_guard<std::mutex> lock (mutex);
874
891
total_allocated += Size;
875
892
if (!isReadOnly)
876
893
return (uint8_t *)rw_alloc.alloc (Size, Alignment);
@@ -885,6 +902,7 @@ void RTDyldMemoryManagerJL::notifyObjectLoaded(RuntimeDyld &Dyld,
885
902
{
886
903
if (!ro_alloc) {
887
904
assert (!exe_alloc);
905
+ std::lock_guard<std::mutex> lock (mutex);
888
906
SectionMemoryManager::notifyObjectLoaded (Dyld, Obj);
889
907
return ;
890
908
}
@@ -894,26 +912,31 @@ void RTDyldMemoryManagerJL::notifyObjectLoaded(RuntimeDyld &Dyld,
894
912
895
913
bool RTDyldMemoryManagerJL::finalizeMemory (std::string *ErrMsg)
896
914
{
897
- code_allocated = false ;
915
+ std::lock_guard<std::mutex> lock (mutex);
916
+ bool failure;
917
+ allocating_thread = std::thread::id ();
898
918
if (ro_alloc) {
899
919
ro_alloc->finalize ();
900
920
assert (exe_alloc);
901
921
exe_alloc->finalize ();
902
922
for (auto &frame: pending_eh)
903
923
register_eh_frames (frame.addr , frame.size );
904
924
pending_eh.clear ();
905
- return false ;
925
+ failure = false ;
906
926
}
907
927
else {
908
928
assert (!exe_alloc);
909
- return SectionMemoryManager::finalizeMemory (ErrMsg);
929
+ failure = SectionMemoryManager::finalizeMemory (ErrMsg);
910
930
}
931
+ freed.notify_one ();
932
+ return failure;
911
933
}
912
934
913
935
void RTDyldMemoryManagerJL::registerEHFrames (uint8_t *Addr,
914
936
uint64_t LoadAddr,
915
937
size_t Size)
916
938
{
939
+ std::lock_guard<std::mutex> lock (mutex);
917
940
if (uintptr_t (Addr) == LoadAddr) {
918
941
register_eh_frames (Addr, Size);
919
942
}
@@ -927,6 +950,7 @@ void RTDyldMemoryManagerJL::deregisterEHFrames(uint8_t *Addr,
927
950
uint64_t LoadAddr,
928
951
size_t Size)
929
952
{
953
+ std::lock_guard<std::mutex> lock(mutex);
930
954
deregister_eh_frames((uint8_t*)LoadAddr, Size);
931
955
}
932
956
#endif
0 commit comments