|
56 | 56 | #include <llvm/Support/FormatAdapters.h> |
57 | 57 | #include <llvm/Linker/Linker.h> |
58 | 58 |
|
| 59 | +// Include necessary headers for semaphores |
| 60 | +#if defined(_OS_LINUX_) |
| 61 | +#include <semaphore.h> |
| 62 | +#include <fcntl.h> |
| 63 | +#endif |
59 | 64 |
|
60 | 65 | using namespace llvm; |
61 | 66 |
|
@@ -1645,6 +1650,47 @@ void jl_dump_native_impl(void *native_code, |
1645 | 1650 | has_veccall = !!dataM.getModuleFlag("julia.mv.veccall"); |
1646 | 1651 | }); |
1647 | 1652 |
|
| 1653 | +#if defined(_OS_LINUX_) |
| 1654 | + // This flag tracks if the lock was actually acquired to avoid freeing the semaphore |
| 1655 | + // if it was never opened. |
| 1656 | + bool lock_acquired = false; |
| 1657 | + |
| 1658 | + auto cleanup = [&](sem_t* s) { |
| 1659 | + if (s != SEM_FAILED) { |
| 1660 | + if (lock_acquired) { |
| 1661 | + // Only post if the lock was successfully acquired. |
| 1662 | + sem_post(s); |
| 1663 | + } |
| 1664 | + sem_close(s); |
| 1665 | + } |
| 1666 | + }; |
| 1667 | + |
| 1668 | + sem_t *par_precomp_sem = SEM_FAILED; |
| 1669 | + const char *sem_name = getenv("JL_AOT_PRECOMPILE_SEMAPHORE"); |
| 1670 | + if (sem_name != NULL) { |
| 1671 | + // The count for the semaphore will be initialized by the parent process that spawns compilation sub-processes. |
| 1672 | + // This is to ensure that only already created semaphores are used and that we don't end up in a situation |
| 1673 | + // where every spawned compilation subprocess creates its own semaphore. Cleanup is handled by the parent process. |
| 1674 | + par_precomp_sem = sem_open(sem_name, 0); |
| 1675 | + std::unique_ptr<sem_t, decltype(cleanup)> sem_guard(par_precomp_sem, cleanup); |
| 1676 | + if (par_precomp_sem == SEM_FAILED) { |
| 1677 | + jl_errorf("Failed to open parallel precompilation semaphore '%s': %s", sem_name, strerror(errno)); |
| 1678 | + } else { |
| 1679 | + // Wait for the semaphore, retrying if interrupted by a signal (EINTR). |
| 1680 | + int ret; |
| 1681 | + do { |
| 1682 | + ret = sem_wait(par_precomp_sem); |
| 1683 | + } while (ret == -1 && errno == EINTR); |
| 1684 | + |
| 1685 | + if (ret == 0) { |
| 1686 | + lock_acquired = true; |
| 1687 | + } else { |
| 1688 | + jl_errorf("Failed to wait on semaphore '%s': %s", sem_name, strerror(errno)); |
| 1689 | + } |
| 1690 | + } |
| 1691 | + } |
| 1692 | +#endif |
| 1693 | + |
1648 | 1694 | { |
1649 | 1695 | // Don't use withModuleDo here since we delete the TSM midway through |
1650 | 1696 | auto TSCtx = data->M.getContext(); |
|
0 commit comments