提交 eaaad263 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

allow disabling exceptions (and panic on out-of-memory):

add "EXCEPTIONS := n" to config.mk
上级 0bca9d1a
...@@ -139,7 +139,7 @@ extern void *__dso_handle; ...@@ -139,7 +139,7 @@ extern void *__dso_handle;
assert(nbytes == sizeof(classname)); \ assert(nbytes == sizeof(classname)); \
void* p = kmalloc(sizeof(classname), #classname); \ void* p = kmalloc(sizeof(classname), #classname); \
if (p == nullptr) \ if (p == nullptr) \
throw std::bad_alloc(); \ throw_bad_alloc(); \
return p; \ return p; \
} \ } \
\ \
...@@ -175,3 +175,13 @@ scoped_cleanup(const T& h) ...@@ -175,3 +175,13 @@ scoped_cleanup(const T& h)
{ {
return scoped_cleanup_obj<T>(h); return scoped_cleanup_obj<T>(h);
} }
static void inline
throw_bad_alloc()
{
#if EXCEPTIONS
throw std::bad_alloc();
#else
panic("bad alloc");
#endif
}
...@@ -82,9 +82,9 @@ $(O)/kernel/%.o: CFLAGS+=-mcmodel=kernel -DXV6_KERNEL ...@@ -82,9 +82,9 @@ $(O)/kernel/%.o: CFLAGS+=-mcmodel=kernel -DXV6_KERNEL
$(O)/kernel/%.o: CXXFLAGS+=-mcmodel=kernel -DXV6_KERNEL $(O)/kernel/%.o: CXXFLAGS+=-mcmodel=kernel -DXV6_KERNEL
ifeq ($(EXCEPTIONS),y) ifeq ($(EXCEPTIONS),y)
$(O)/kernel/%.o: CXXFLAGS+=-fnothrow-opt -Wnoexcept $(O)/kernel/%.o: CXXFLAGS+=-fnothrow-opt -Wnoexcept -DEXCEPTIONS=1
else else
$(O)/kernel/%.o: CXXFLAGS+=-fno-exceptions -fno-rtti $(O)/kernel/%.o: CXXFLAGS+=-fno-exceptions -fno-rtti -DEXCEPTIONS=0
endif endif
$(KERN): $(O)/kernel/boot.o $(OBJS) $(LDEPS) kernel/kernel.ld $(KERN): $(O)/kernel/boot.o $(OBJS) $(LDEPS) kernel/kernel.ld
......
...@@ -221,6 +221,7 @@ extern "C" void __register_frame(u8*); ...@@ -221,6 +221,7 @@ extern "C" void __register_frame(u8*);
void void
initcpprt(void) initcpprt(void)
{ {
#if EXCEPTIONS
extern u8 __EH_FRAME_BEGIN__[]; extern u8 __EH_FRAME_BEGIN__[];
__register_frame(__EH_FRAME_BEGIN__); __register_frame(__EH_FRAME_BEGIN__);
...@@ -234,4 +235,5 @@ initcpprt(void) ...@@ -234,4 +235,5 @@ initcpprt(void)
} }
panic("no catch"); panic("no catch");
#endif
} }
...@@ -352,7 +352,7 @@ fork(int flags) ...@@ -352,7 +352,7 @@ fork(int flags)
// Allocate process. // Allocate process.
if((np = proc::alloc()) == 0) if((np = proc::alloc()) == 0)
throw std::bad_alloc(); throw_bad_alloc();
auto proc_cleanup = scoped_cleanup([&np]() { auto proc_cleanup = scoped_cleanup([&np]() {
if (!xnspid->remove(np->pid, &np)) if (!xnspid->remove(np->pid, &np))
......
...@@ -26,7 +26,7 @@ klockstat::operator new(unsigned long nbytes) ...@@ -26,7 +26,7 @@ klockstat::operator new(unsigned long nbytes)
assert(nbytes == sizeof(klockstat)); assert(nbytes == sizeof(klockstat));
void* p = kmalloc(sizeof(klockstat), "klockstat"); void* p = kmalloc(sizeof(klockstat), "klockstat");
if (!p) if (!p)
throw std::bad_alloc(); throw_bad_alloc();
return p; return p;
} }
......
...@@ -83,7 +83,9 @@ syscall(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num) ...@@ -83,7 +83,9 @@ syscall(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num)
mt_ascope ascope("syscall(%lx,%lx,%lx,%lx,%lx,%lx)", num, a0, a1, a2, a3, a4); mt_ascope ascope("syscall(%lx,%lx,%lx,%lx,%lx,%lx)", num, a0, a1, a2, a3, a4);
for (;;) { for (;;) {
#if EXCEPTIONS
try { try {
#endif
if(num < SYS_ncount && syscalls[num]) { if(num < SYS_ncount && syscalls[num]) {
mtstart(syscalls[num], myproc()); mtstart(syscalls[num], myproc());
mtrec(); mtrec();
...@@ -96,10 +98,12 @@ syscall(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num) ...@@ -96,10 +98,12 @@ syscall(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num)
myproc()->pid, myproc()->name, num); myproc()->pid, myproc()->name, num);
return -1; return -1;
} }
#if EXCEPTIONS
} catch (retryable& e) { } catch (retryable& e) {
cprintf("%d: syscall retry\n", myproc()->pid); cprintf("%d: syscall retry\n", myproc()->pid);
gc_wakeup(); gc_wakeup();
yield(); yield();
} }
#endif
} }
} }
...@@ -99,7 +99,7 @@ vmnode::allocall(bool zero) ...@@ -99,7 +99,7 @@ vmnode::allocall(bool zero)
{ {
for(u64 i = 0; i < npages; i++) for(u64 i = 0; i < npages; i++)
if (allocpg(i, zero) < 0) if (allocpg(i, zero) < 0)
throw std::bad_alloc(); throw_bad_alloc();
} }
vmnode * vmnode *
...@@ -220,7 +220,7 @@ vmap::vmap() : ...@@ -220,7 +220,7 @@ vmap::vmap() :
ksfree(slab_kshared, kshared); ksfree(slab_kshared, kshared);
if (pml4) if (pml4)
freevm(pml4); freevm(pml4);
throw std::bad_alloc(); throw_bad_alloc();
} }
vmap::~vmap() vmap::~vmap()
...@@ -553,7 +553,7 @@ vmap::pagefault(uptr va, u32 err) ...@@ -553,7 +553,7 @@ vmap::pagefault(uptr va, u32 err)
atomic<pme_t> *pte = walkpgdir(pml4, va, 1); atomic<pme_t> *pte = walkpgdir(pml4, va, 1);
if (pte == nullptr) if (pte == nullptr)
throw std::bad_alloc(); throw_bad_alloc();
retry: retry:
pme_t ptev = pte->load(); pme_t ptev = pte->load();
...@@ -596,7 +596,7 @@ vmap::pagefault(uptr va, u32 err) ...@@ -596,7 +596,7 @@ vmap::pagefault(uptr va, u32 err)
// however, our vmnode might include not backed by a file // however, our vmnode might include not backed by a file
// (e.g. the bss section of an ELF segment) // (e.g. the bss section of an ELF segment)
if (m->n->allocpg(npg, true) < 0) if (m->n->allocpg(npg, true) < 0)
throw std::bad_alloc(); throw_bad_alloc();
// XXX(sbw) If m->n->page[npg] has contents (e.g. was loaded in // XXX(sbw) If m->n->page[npg] has contents (e.g. was loaded in
// a parent before fork) we shouldn't call loadpg // a parent before fork) we shouldn't call loadpg
...@@ -635,13 +635,17 @@ pagefault(struct vmap *vmap, uptr va, u32 err) ...@@ -635,13 +635,17 @@ pagefault(struct vmap *vmap, uptr va, u32 err)
#endif #endif
for (;;) { for (;;) {
#if EXCEPTIONS
try { try {
#endif
return vmap->pagefault(va, err); return vmap->pagefault(va, err);
#if EXCEPTIONS
} catch (retryable& e) { } catch (retryable& e) {
cprintf("%d: pagefault retry\n", myproc()->pid); cprintf("%d: pagefault retry\n", myproc()->pid);
gc_wakeup(); gc_wakeup();
yield(); yield();
} }
#endif
} }
} }
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论