Skip to content

Commit a3bc8af

Browse files
committed
fix(wasi): update wasi stubs
Signed-off-by: Bailey Hayes <[email protected]>
1 parent 482a974 commit a3bc8af

File tree

5 files changed

+205
-0
lines changed

5 files changed

+205
-0
lines changed

absl/base/internal/low_level_alloc.cc

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ struct LowLevelAlloc::Arena {
224224

225225
// ---------------------------------------------------------------
226226
// An async-signal-safe arena for LowLevelAlloc
227+
#ifndef __wasi__
227228
static std::atomic<base_internal::LowLevelAlloc::Arena *> g_sig_safe_arena;
228229

229230
base_internal::LowLevelAlloc::Arena *SigSafeArena() {
@@ -247,6 +248,7 @@ void InitSigSafeArena() {
247248
}
248249
}
249250
}
251+
#endif // __wasi__
250252

251253
namespace {
252254
// Static storage space for the lazily-constructed, default global arena
@@ -535,6 +537,7 @@ static void AddToFreelist(void *v, LowLevelAlloc::Arena *arena)
535537

536538
// Frees storage allocated by LowLevelAlloc::Alloc().
537539
// L < arena->mu
540+
#ifndef __wasi__
538541
void LowLevelAlloc::Free(void *v) {
539542
if (v != nullptr) {
540543
AllocList *f = reinterpret_cast<AllocList *>(reinterpret_cast<char *>(v) -
@@ -547,6 +550,7 @@ void LowLevelAlloc::Free(void *v) {
547550
section.Leave();
548551
}
549552
}
553+
#endif // __wasi__
550554

551555
// allocates and returns a block of size bytes, to be freed with Free()
552556
// L < arena->mu
@@ -643,6 +647,7 @@ static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) {
643647
return result;
644648
}
645649

650+
#ifndef __wasi__
646651
void *LowLevelAlloc::Alloc(size_t request) {
647652
void *result = DoAllocWithArena(request, DefaultArena());
648653
return result;
@@ -653,9 +658,49 @@ void *LowLevelAlloc::AllocWithArena(size_t request, Arena *arena) {
653658
void *result = DoAllocWithArena(request, arena);
654659
return result;
655660
}
661+
#endif // __wasi__
656662

657663
} // namespace base_internal
658664
ABSL_NAMESPACE_END
659665
} // namespace absl
660666

661667
#endif // ABSL_LOW_LEVEL_ALLOC_MISSING
668+
669+
// WASI-specific implementations
670+
// WASI doesn't support mmap, so we use malloc/free for LowLevelAlloc
671+
#ifdef __wasi__
672+
673+
#include "absl/base/internal/low_level_alloc.h"
674+
675+
namespace absl {
676+
ABSL_NAMESPACE_BEGIN
677+
namespace base_internal {
678+
679+
void *LowLevelAlloc::Alloc(size_t request) {
680+
return malloc(request);
681+
}
682+
683+
void LowLevelAlloc::Free(void *v) {
684+
free(v);
685+
}
686+
687+
void *LowLevelAlloc::AllocWithArena(size_t request, Arena* /*arena*/) {
688+
// Ignore arena parameter and use malloc
689+
return malloc(request);
690+
}
691+
692+
// Signal-safe arena stubs for WASI
693+
void InitSigSafeArena() {
694+
// No-op: WASI doesn't need arena initialization
695+
}
696+
697+
LowLevelAlloc::Arena *SigSafeArena() {
698+
// Return nullptr - arenas are ignored in WASI's AllocWithArena
699+
return nullptr;
700+
}
701+
702+
} // namespace base_internal
703+
ABSL_NAMESPACE_END
704+
} // namespace absl
705+
706+
#endif // __wasi__

absl/synchronization/internal/create_thread_identity.cc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,15 +138,39 @@ static base_internal::ThreadIdentity* NewThreadIdentity() {
138138
// Allocates and attaches ThreadIdentity object for the calling thread. Returns
139139
// the new identity.
140140
// REQUIRES: CurrentThreadIdentity(false) == nullptr
141+
#ifndef __wasi__
141142
base_internal::ThreadIdentity* CreateThreadIdentity() {
142143
base_internal::ThreadIdentity* identity = NewThreadIdentity();
143144
// Associate the value with the current thread, and attach our destructor.
144145
base_internal::SetCurrentThreadIdentity(identity, ReclaimThreadIdentity);
145146
return identity;
146147
}
148+
#endif // __wasi__
147149

148150
} // namespace synchronization_internal
149151
ABSL_NAMESPACE_END
150152
} // namespace absl
151153

152154
#endif // ABSL_LOW_LEVEL_ALLOC_MISSING
155+
156+
// WASI-specific implementation
157+
// WASI is single-threaded, so we use a single static ThreadIdentity
158+
#ifdef __wasi__
159+
160+
#include "absl/base/internal/thread_identity.h"
161+
162+
namespace absl {
163+
ABSL_NAMESPACE_BEGIN
164+
namespace synchronization_internal {
165+
166+
static base_internal::ThreadIdentity g_wasi_thread_identity = {};
167+
168+
base_internal::ThreadIdentity* CreateThreadIdentity() {
169+
return &g_wasi_thread_identity;
170+
}
171+
172+
} // namespace synchronization_internal
173+
ABSL_NAMESPACE_END
174+
} // namespace absl
175+
176+
#endif // __wasi__

absl/synchronization/internal/graphcycles.cc

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ void GraphCycles::TestOnlyAddNodes(uint32_t n) {
370370
}
371371
}
372372

373+
#ifndef __wasi__
373374
GraphCycles::GraphCycles() {
374375
InitArenaIfNecessary();
375376
rep_ = new (base_internal::LowLevelAlloc::AllocWithArena(sizeof(Rep), arena))
@@ -706,9 +707,87 @@ int GraphCycles::GetStackTrace(GraphId id, void*** ptr) {
706707
return n->nstack;
707708
}
708709
}
710+
#endif // __wasi__
709711

710712
} // namespace synchronization_internal
711713
ABSL_NAMESPACE_END
712714
} // namespace absl
713715

714716
#endif // ABSL_LOW_LEVEL_ALLOC_MISSING
717+
718+
// WASI-specific minimal GraphCycles implementation
719+
// WASI is single-threaded, so cycle detection is not necessary
720+
#ifdef __wasi__
721+
722+
#include "absl/synchronization/internal/graphcycles.h"
723+
724+
namespace absl {
725+
ABSL_NAMESPACE_BEGIN
726+
namespace synchronization_internal {
727+
728+
// Minimal implementation that always succeeds
729+
GraphCycles::GraphCycles() : rep_(nullptr) {}
730+
731+
GraphCycles::~GraphCycles() {}
732+
733+
GraphId GraphCycles::GetId(void* /*ptr*/) {
734+
return GraphId{0};
735+
}
736+
737+
void GraphCycles::RemoveNode(void* /*ptr*/) {
738+
// No-op
739+
}
740+
741+
void* GraphCycles::Ptr(GraphId /*id*/) {
742+
return nullptr;
743+
}
744+
745+
bool GraphCycles::InsertEdge(GraphId /*source_node*/, GraphId /*dest_node*/) {
746+
// Always succeed - no cycles in single-threaded WASI
747+
return true;
748+
}
749+
750+
void GraphCycles::RemoveEdge(GraphId /*source_node*/, GraphId /*dest_node*/) {
751+
// No-op
752+
}
753+
754+
bool GraphCycles::HasNode(GraphId /*node*/) {
755+
return false;
756+
}
757+
758+
bool GraphCycles::HasEdge(GraphId /*source_node*/, GraphId /*dest_node*/) const {
759+
return false;
760+
}
761+
762+
bool GraphCycles::IsReachable(GraphId /*source_node*/, GraphId /*dest_node*/) const {
763+
return false;
764+
}
765+
766+
int GraphCycles::FindPath(GraphId /*source*/, GraphId /*dest*/, int /*max_path_len*/,
767+
GraphId /*path*/[]) const {
768+
return 0;
769+
}
770+
771+
void GraphCycles::UpdateStackTrace(GraphId /*id*/, int /*priority*/,
772+
int (*/*get_stack_trace*/)(void**, int)) {
773+
// No-op
774+
}
775+
776+
int GraphCycles::GetStackTrace(GraphId /*id*/, void*** ptr) {
777+
*ptr = nullptr;
778+
return 0;
779+
}
780+
781+
bool GraphCycles::CheckInvariants() const {
782+
return true;
783+
}
784+
785+
void GraphCycles::TestOnlyAddNodes(uint32_t /*n*/) {
786+
// No-op
787+
}
788+
789+
} // namespace synchronization_internal
790+
ABSL_NAMESPACE_END
791+
} // namespace absl
792+
793+
#endif // __wasi__

absl/synchronization/internal/per_thread_sem.cc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,40 @@ ABSL_ATTRIBUTE_WEAK bool ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemWait)(
104104
} // extern "C"
105105

106106
#endif // ABSL_LOW_LEVEL_ALLOC_MISSING
107+
108+
// WASI-specific implementations
109+
// WASI doesn't support threading, so these are no-op implementations
110+
#ifdef __wasi__
111+
112+
#include "absl/synchronization/internal/per_thread_sem.h"
113+
#include "absl/base/attributes.h"
114+
#include "absl/base/internal/thread_identity.h"
115+
#include "absl/synchronization/internal/waiter.h"
116+
117+
extern "C" {
118+
119+
// Override the weak symbols with WASI-specific no-op implementations
120+
void ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemInit)(
121+
absl::base_internal::ThreadIdentity* /*identity*/) {
122+
// No-op: WASI is single-threaded
123+
}
124+
125+
void ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemPost)(
126+
absl::base_internal::ThreadIdentity* /*identity*/) {
127+
// No-op: WASI is single-threaded
128+
}
129+
130+
void ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemPoke)(
131+
absl::base_internal::ThreadIdentity* /*identity*/) {
132+
// No-op: WASI is single-threaded
133+
}
134+
135+
bool ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemWait)(
136+
absl::synchronization_internal::KernelTimeout /*t*/) {
137+
// No-op: WASI is single-threaded, always return true (no timeout)
138+
return true;
139+
}
140+
141+
} // extern "C"
142+
143+
#endif // __wasi__

absl/synchronization/mutex.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,6 +1528,10 @@ static bool TryAcquireWithSpinning(std::atomic<intptr_t>* mu) {
15281528
}
15291529

15301530
void Mutex::lock() {
1531+
#ifdef __wasi__
1532+
// No-op: WASI is single-threaded
1533+
return;
1534+
#endif
15311535
ABSL_TSAN_MUTEX_PRE_LOCK(this, 0);
15321536
GraphId id = DebugOnlyDeadlockCheck(this);
15331537
intptr_t v = mu_.load(std::memory_order_relaxed);
@@ -1546,6 +1550,10 @@ void Mutex::lock() {
15461550
}
15471551

15481552
void Mutex::lock_shared() {
1553+
#ifdef __wasi__
1554+
// No-op: WASI is single-threaded
1555+
return;
1556+
#endif
15491557
ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_read_lock);
15501558
GraphId id = DebugOnlyDeadlockCheck(this);
15511559
intptr_t v = mu_.load(std::memory_order_relaxed);
@@ -1706,6 +1714,10 @@ ABSL_ATTRIBUTE_NOINLINE bool Mutex::ReaderTryLockSlow() {
17061714
}
17071715

17081716
void Mutex::unlock() {
1717+
#ifdef __wasi__
1718+
// No-op: WASI is single-threaded
1719+
return;
1720+
#endif
17091721
ABSL_TSAN_MUTEX_PRE_UNLOCK(this, 0);
17101722
DebugOnlyLockLeave(this);
17111723
intptr_t v = mu_.load(std::memory_order_relaxed);
@@ -1776,6 +1788,10 @@ static bool ExactlyOneReader(intptr_t v) {
17761788
}
17771789

17781790
void Mutex::unlock_shared() {
1791+
#ifdef __wasi__
1792+
// No-op: WASI is single-threaded
1793+
return;
1794+
#endif
17791795
ABSL_TSAN_MUTEX_PRE_UNLOCK(this, __tsan_mutex_read_lock);
17801796
DebugOnlyLockLeave(this);
17811797
intptr_t v = mu_.load(std::memory_order_relaxed);
@@ -2493,6 +2509,10 @@ void Mutex::Fer(PerThreadSynch* w) {
24932509
}
24942510

24952511
void Mutex::AssertHeld() const {
2512+
#ifdef __wasi__
2513+
// No-op: WASI is single-threaded, always held
2514+
return;
2515+
#endif
24962516
if ((mu_.load(std::memory_order_relaxed) & kMuWriter) == 0) {
24972517
SynchEvent* e = GetSynchEvent(this);
24982518
ABSL_RAW_LOG(FATAL, "thread should hold write lock on Mutex %p %s",

0 commit comments

Comments
 (0)