Compare commits
No commits in common. "755d41ca4ea3b31137ba00d27833699faefd153f" and "2b48933f2984d95c5bfd46fe330fbe172613e434" have entirely different histories.
755d41ca4e
...
2b48933f29
|
@ -18,7 +18,7 @@ namespace BAN::UTF8
|
||||||
return 3;
|
return 3;
|
||||||
if ((first_byte & 0xF8) == 0xF0)
|
if ((first_byte & 0xF8) == 0xF0)
|
||||||
return 4;
|
return 4;
|
||||||
return UTF8::invalid;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> requires (sizeof(T) == 1)
|
template<typename T> requires (sizeof(T) == 1)
|
||||||
|
|
|
@ -98,9 +98,7 @@ namespace Kernel
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ThreadBlocker m_thread_blocker;
|
ThreadBlocker m_thread_blocker;
|
||||||
SpinLock m_ready_lock;
|
|
||||||
BAN::HashMap<BAN::RefPtr<Inode>, uint32_t, InodeRefPtrHash> m_ready_events;
|
BAN::HashMap<BAN::RefPtr<Inode>, uint32_t, InodeRefPtrHash> m_ready_events;
|
||||||
BAN::HashMap<BAN::RefPtr<Inode>, uint32_t, InodeRefPtrHash> m_processing_events;
|
|
||||||
BAN::HashMap<BAN::RefPtr<Inode>, ListenEventList, InodeRefPtrHash> m_listening_events;
|
BAN::HashMap<BAN::RefPtr<Inode>, ListenEventList, InodeRefPtrHash> m_listening_events;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,6 @@ namespace Kernel
|
||||||
FlushTLB,
|
FlushTLB,
|
||||||
NewThread,
|
NewThread,
|
||||||
UnblockThread,
|
UnblockThread,
|
||||||
StackTrace,
|
|
||||||
};
|
};
|
||||||
SMPMessage* next { nullptr };
|
SMPMessage* next { nullptr };
|
||||||
Type type;
|
Type type;
|
||||||
|
@ -46,7 +45,6 @@ namespace Kernel
|
||||||
} flush_tlb;
|
} flush_tlb;
|
||||||
SchedulerQueue::Node* new_thread;
|
SchedulerQueue::Node* new_thread;
|
||||||
SchedulerQueue::Node* unblock_thread;
|
SchedulerQueue::Node* unblock_thread;
|
||||||
bool dummy;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,26 +29,18 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
case EPOLL_CTL_ADD:
|
case EPOLL_CTL_ADD:
|
||||||
{
|
{
|
||||||
bool contains_inode = (it != m_listening_events.end());
|
if (it == m_listening_events.end())
|
||||||
if (!contains_inode)
|
|
||||||
it = TRY(m_listening_events.emplace(inode));
|
it = TRY(m_listening_events.emplace(inode));
|
||||||
if (it->value.has_fd(fd))
|
if (it->value.has_fd(fd))
|
||||||
return BAN::Error::from_errno(EEXIST);
|
return BAN::Error::from_errno(EEXIST);
|
||||||
|
TRY(m_ready_events.reserve(m_listening_events.size()));
|
||||||
{
|
TRY(inode->add_epoll(this));
|
||||||
SpinLockGuard _(m_ready_lock);
|
|
||||||
TRY(m_ready_events.reserve(m_listening_events.size()));
|
|
||||||
}
|
|
||||||
TRY(m_processing_events.reserve(m_listening_events.size()));
|
|
||||||
|
|
||||||
if (!contains_inode)
|
|
||||||
TRY(inode->add_epoll(this));
|
|
||||||
it->value.add_fd(fd, event);
|
it->value.add_fd(fd, event);
|
||||||
|
|
||||||
auto processing_it = m_processing_events.find(inode);
|
auto ready_it = m_ready_events.find(inode);
|
||||||
if (processing_it == m_processing_events.end())
|
if (ready_it == m_ready_events.end())
|
||||||
processing_it = MUST(m_processing_events.insert(inode, 0));
|
ready_it = MUST(m_ready_events.insert(inode, 0));
|
||||||
processing_it->value |= event.events;
|
ready_it->value |= event.events;
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -58,13 +50,12 @@ namespace Kernel
|
||||||
return BAN::Error::from_errno(ENOENT);
|
return BAN::Error::from_errno(ENOENT);
|
||||||
if (!it->value.has_fd(fd))
|
if (!it->value.has_fd(fd))
|
||||||
return BAN::Error::from_errno(ENOENT);
|
return BAN::Error::from_errno(ENOENT);
|
||||||
|
|
||||||
it->value.events[fd] = event;
|
it->value.events[fd] = event;
|
||||||
|
|
||||||
auto processing_it = m_processing_events.find(inode);
|
auto ready_it = m_ready_events.find(inode);
|
||||||
if (processing_it == m_processing_events.end())
|
if (ready_it == m_ready_events.end())
|
||||||
processing_it = MUST(m_processing_events.insert(inode, 0));
|
ready_it = MUST(m_ready_events.insert(inode, 0));
|
||||||
processing_it->value |= event.events;
|
ready_it->value |= event.events;
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -77,10 +68,7 @@ namespace Kernel
|
||||||
it->value.remove_fd(fd);
|
it->value.remove_fd(fd);
|
||||||
if (it->value.empty())
|
if (it->value.empty())
|
||||||
{
|
{
|
||||||
inode->del_epoll(this);
|
|
||||||
m_listening_events.remove(it);
|
m_listening_events.remove(it);
|
||||||
m_processing_events.remove(inode);
|
|
||||||
SpinLockGuard _(m_ready_lock);
|
|
||||||
m_ready_events.remove(inode);
|
m_ready_events.remove(inode);
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
|
@ -95,76 +83,53 @@ namespace Kernel
|
||||||
if (event_span.empty())
|
if (event_span.empty())
|
||||||
return BAN::Error::from_errno(EINVAL);
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
|
||||||
size_t event_count = 0;
|
size_t count = 0;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
bool failed_lock = false;
|
||||||
|
|
||||||
{
|
{
|
||||||
LockGuard _(m_mutex);
|
LockGuard _(m_mutex);
|
||||||
|
|
||||||
{
|
for (auto it = m_ready_events.begin(); it != m_ready_events.end() && count < event_span.size();)
|
||||||
SpinLockGuard _(m_ready_lock);
|
|
||||||
|
|
||||||
while (!m_ready_events.empty())
|
|
||||||
{
|
|
||||||
auto [inode, events] = *m_ready_events.begin();
|
|
||||||
m_ready_events.remove(m_ready_events.begin());
|
|
||||||
|
|
||||||
ASSERT(events);
|
|
||||||
|
|
||||||
if (auto it = m_processing_events.find(inode); it != m_processing_events.end())
|
|
||||||
it->value |= events;
|
|
||||||
else
|
|
||||||
MUST(m_processing_events.insert(inode, events));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto it = m_processing_events.begin(); it != m_processing_events.end() && event_count < event_span.size();)
|
|
||||||
{
|
{
|
||||||
auto& [inode, events] = *it;
|
auto& [inode, events] = *it;
|
||||||
|
|
||||||
#define REMOVE_IT_AND_CONTINUE() \
|
auto& listen = m_listening_events[inode];
|
||||||
({ \
|
|
||||||
m_processing_events.remove(it); \
|
|
||||||
it = m_processing_events.begin(); \
|
|
||||||
continue; \
|
|
||||||
})
|
|
||||||
|
|
||||||
auto listen_it = m_listening_events.find(inode);
|
uint32_t listen_mask = EPOLLERR | EPOLLHUP;
|
||||||
if (listen_it == m_listening_events.end())
|
for (int fd = 0; fd < OPEN_MAX; fd++)
|
||||||
REMOVE_IT_AND_CONTINUE();
|
if (listen.has_fd(fd))
|
||||||
auto& listen = listen_it->value;
|
listen_mask |= listen.events[fd].events;
|
||||||
|
events &= listen_mask;
|
||||||
|
|
||||||
|
// This prevents a possible deadlock
|
||||||
|
if (!inode->m_mutex.try_lock())
|
||||||
{
|
{
|
||||||
uint32_t listen_mask = EPOLLERR | EPOLLHUP;
|
failed_lock = true;
|
||||||
for (size_t fd = 0; fd < listen.events.size(); fd++)
|
continue;
|
||||||
if (listen.has_fd(fd))
|
|
||||||
listen_mask |= listen.events[fd].events;
|
|
||||||
events &= listen_mask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (events == 0)
|
|
||||||
REMOVE_IT_AND_CONTINUE();
|
|
||||||
|
|
||||||
{
|
|
||||||
LockGuard inode_locker(inode->m_mutex);
|
|
||||||
|
|
||||||
#define CHECK_EVENT_BIT(mask, func) \
|
#define CHECK_EVENT_BIT(mask, func) \
|
||||||
if ((events & mask) && !inode->func()) \
|
if ((events & mask) && !inode->func()) \
|
||||||
events &= ~mask;
|
events &= ~mask;
|
||||||
CHECK_EVENT_BIT(EPOLLIN, can_read);
|
CHECK_EVENT_BIT(EPOLLIN, can_read);
|
||||||
CHECK_EVENT_BIT(EPOLLOUT, can_write);
|
CHECK_EVENT_BIT(EPOLLOUT, can_write);
|
||||||
CHECK_EVENT_BIT(EPOLLERR, has_error);
|
CHECK_EVENT_BIT(EPOLLERR, has_error);
|
||||||
CHECK_EVENT_BIT(EPOLLHUP, has_hungup);
|
CHECK_EVENT_BIT(EPOLLHUP, has_hungup);
|
||||||
#undef CHECK_EVENT_BIT
|
#undef CHECK_EVENT_BIT
|
||||||
}
|
|
||||||
|
inode->m_mutex.unlock();
|
||||||
|
|
||||||
if (events == 0)
|
if (events == 0)
|
||||||
REMOVE_IT_AND_CONTINUE();
|
{
|
||||||
|
m_ready_events.remove(it);
|
||||||
|
it = m_ready_events.begin();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
#undef REMOVE_IT_AND_CONTINUE
|
for (int fd = 0; fd < OPEN_MAX && count < event_span.size(); fd++)
|
||||||
|
|
||||||
for (size_t fd = 0; fd < listen.events.size() && event_count < event_span.size(); fd++)
|
|
||||||
{
|
{
|
||||||
if (!listen.has_fd(fd))
|
if (!listen.has_fd(fd))
|
||||||
continue;
|
continue;
|
||||||
|
@ -174,7 +139,7 @@ namespace Kernel
|
||||||
if (new_events == 0)
|
if (new_events == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
event_span[event_count++] = {
|
event_span[count++] = {
|
||||||
.events = new_events,
|
.events = new_events,
|
||||||
.data = listen_event.data,
|
.data = listen_event.data,
|
||||||
};
|
};
|
||||||
|
@ -190,29 +155,32 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event_count > 0)
|
if (count)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
const uint64_t current_ns = SystemTimer::get().ns_since_boot();
|
const uint64_t current_ns = SystemTimer::get().ns_since_boot();
|
||||||
if (current_ns >= waketime_ns)
|
if (current_ns >= waketime_ns)
|
||||||
break;
|
break;
|
||||||
|
if (failed_lock)
|
||||||
|
continue;
|
||||||
const uint64_t timeout_ns = BAN::Math::min<uint64_t>(100'000'000, waketime_ns - current_ns);
|
const uint64_t timeout_ns = BAN::Math::min<uint64_t>(100'000'000, waketime_ns - current_ns);
|
||||||
TRY(Thread::current().block_or_eintr_or_timeout_ns(m_thread_blocker, timeout_ns, false));
|
TRY(Thread::current().block_or_eintr_or_timeout_ns(m_thread_blocker, timeout_ns, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
return event_count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Epoll::notify(BAN::RefPtr<Inode> inode, uint32_t event)
|
void Epoll::notify(BAN::RefPtr<Inode> inode, uint32_t event)
|
||||||
{
|
{
|
||||||
ASSERT(event);
|
LockGuard _(m_mutex);
|
||||||
|
|
||||||
SpinLockGuard _(m_ready_lock);
|
if (!m_listening_events.contains(inode))
|
||||||
|
return;
|
||||||
|
|
||||||
if (auto it = m_ready_events.find(inode); it != m_ready_events.end())
|
auto ready_it = m_ready_events.find(inode);
|
||||||
it->value |= event;
|
if (ready_it == m_ready_events.end())
|
||||||
else
|
ready_it = MUST(m_ready_events.insert(inode, 0));
|
||||||
MUST(m_ready_events.insert(inode, event));
|
ready_it->value |= event;
|
||||||
|
|
||||||
m_thread_blocker.unblock();
|
m_thread_blocker.unblock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,8 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> Pipe::read_impl(off_t, BAN::ByteSpan buffer)
|
BAN::ErrorOr<size_t> Pipe::read_impl(off_t, BAN::ByteSpan buffer)
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
|
|
||||||
while (m_buffer_size == 0)
|
while (m_buffer_size == 0)
|
||||||
{
|
{
|
||||||
if (m_writing_count == 0)
|
if (m_writing_count == 0)
|
||||||
|
@ -101,6 +103,8 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> Pipe::write_impl(off_t, BAN::ConstByteSpan buffer)
|
BAN::ErrorOr<size_t> Pipe::write_impl(off_t, BAN::ConstByteSpan buffer)
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
|
|
||||||
while (m_buffer_size >= m_buffer.size())
|
while (m_buffer_size >= m_buffer.size())
|
||||||
{
|
{
|
||||||
if (m_reading_count == 0)
|
if (m_reading_count == 0)
|
||||||
|
|
|
@ -114,37 +114,7 @@ namespace Kernel
|
||||||
auto& key_event = event.as<const LibInput::RawKeyEvent>();
|
auto& key_event = event.as<const LibInput::RawKeyEvent>();
|
||||||
if (key_event.modifier & LibInput::KeyEvent::Modifier::Pressed)
|
if (key_event.modifier & LibInput::KeyEvent::Modifier::Pressed)
|
||||||
{
|
{
|
||||||
if (key_event.modifier & LibInput::KeyEvent::Modifier::LCtrl)
|
switch (key_event.keycode)
|
||||||
{
|
|
||||||
const auto processor_count = Processor::count();
|
|
||||||
switch (key_event.keycode)
|
|
||||||
{
|
|
||||||
#define DUMP_CPU_STACK_TRACE(idx) \
|
|
||||||
case LibInput::keycode_function(idx + 1): \
|
|
||||||
if (idx >= processor_count) \
|
|
||||||
break; \
|
|
||||||
Processor::send_smp_message(Processor::id_from_index(idx), { \
|
|
||||||
.type = Processor::SMPMessage::Type::StackTrace, \
|
|
||||||
.dummy = false, \
|
|
||||||
}); \
|
|
||||||
break
|
|
||||||
// F1-F12
|
|
||||||
DUMP_CPU_STACK_TRACE(0);
|
|
||||||
DUMP_CPU_STACK_TRACE(1);
|
|
||||||
DUMP_CPU_STACK_TRACE(2);
|
|
||||||
DUMP_CPU_STACK_TRACE(3);
|
|
||||||
DUMP_CPU_STACK_TRACE(4);
|
|
||||||
DUMP_CPU_STACK_TRACE(5);
|
|
||||||
DUMP_CPU_STACK_TRACE(6);
|
|
||||||
DUMP_CPU_STACK_TRACE(7);
|
|
||||||
DUMP_CPU_STACK_TRACE(8);
|
|
||||||
DUMP_CPU_STACK_TRACE(9);
|
|
||||||
DUMP_CPU_STACK_TRACE(10);
|
|
||||||
DUMP_CPU_STACK_TRACE(11);
|
|
||||||
#undef DUMP_CPU_STACK_TRACE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else switch (key_event.keycode)
|
|
||||||
{
|
{
|
||||||
case LibInput::keycode_function(1):
|
case LibInput::keycode_function(1):
|
||||||
Processor::toggle_should_print_cpu_load();
|
Processor::toggle_should_print_cpu_load();
|
||||||
|
|
|
@ -244,10 +244,6 @@ namespace Kernel
|
||||||
case SMPMessage::Type::UnblockThread:
|
case SMPMessage::Type::UnblockThread:
|
||||||
processor.m_scheduler->unblock_thread(message->unblock_thread);
|
processor.m_scheduler->unblock_thread(message->unblock_thread);
|
||||||
break;
|
break;
|
||||||
case SMPMessage::Type::StackTrace:
|
|
||||||
dwarnln("Stack trace of CPU {}", current_id().as_u32());
|
|
||||||
Debug::dump_stack_trace();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
last_handled = message;
|
last_handled = message;
|
||||||
|
@ -279,6 +275,7 @@ namespace Kernel
|
||||||
|
|
||||||
void Processor::send_smp_message(ProcessorID processor_id, const SMPMessage& message, bool send_ipi)
|
void Processor::send_smp_message(ProcessorID processor_id, const SMPMessage& message, bool send_ipi)
|
||||||
{
|
{
|
||||||
|
ASSERT(processor_id != current_id());
|
||||||
|
|
||||||
auto state = get_interrupt_state();
|
auto state = get_interrupt_state();
|
||||||
set_interrupt_state(InterruptState::Disabled);
|
set_interrupt_state(InterruptState::Disabled);
|
||||||
|
@ -310,12 +307,7 @@ namespace Kernel
|
||||||
);
|
);
|
||||||
|
|
||||||
if (send_ipi)
|
if (send_ipi)
|
||||||
{
|
InterruptController::get().send_ipi(processor_id);
|
||||||
if (processor_id == current_id())
|
|
||||||
handle_smp_messages();
|
|
||||||
else
|
|
||||||
InterruptController::get().send_ipi(processor_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
set_interrupt_state(state);
|
set_interrupt_state(state);
|
||||||
}
|
}
|
||||||
|
|
|
@ -623,9 +623,6 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
Processor::set_interrupt_state(InterruptState::Disabled);
|
Processor::set_interrupt_state(InterruptState::Disabled);
|
||||||
setup_process_cleanup();
|
setup_process_cleanup();
|
||||||
// This is super hacky but prevents a crash in yield :D
|
|
||||||
if (m_signal_lock.current_processor_has_lock())
|
|
||||||
m_signal_lock.unlock(InterruptState::Disabled);
|
|
||||||
Processor::yield();
|
Processor::yield();
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
diff -ruN openssl-3.3.1/crypto/bio/bss_dgram.c openssl-3.3.1-banan_os/crypto/bio/bss_dgram.c
|
|
||||||
--- openssl-3.3.1/crypto/bio/bss_dgram.c 2024-06-04 15:53:04.000000000 +0300
|
|
||||||
+++ openssl-3.3.1-banan_os/crypto/bio/bss_dgram.c 2025-06-01 19:48:55.088806701 +0300
|
|
||||||
@@ -61,7 +61,7 @@
|
|
||||||
# define NO_RECVMMSG
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
-# if defined(__GNU__)
|
|
||||||
+# if defined(__GNU__) || defined(__banan_os__)
|
|
||||||
/* GNU/Hurd does not have IP_PKTINFO yet */
|
|
||||||
#undef NO_RECVMSG
|
|
||||||
#define NO_RECVMSG
|
|
|
@ -37,7 +37,8 @@ build_target () {
|
||||||
echo "No target provided"
|
echo "No target provided"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
run_fakeroot $BANAN_CMAKE --build $BANAN_BUILD_DIR -- -j$(nproc) $1
|
cd $BANAN_BUILD_DIR
|
||||||
|
run_fakeroot ninja $1
|
||||||
}
|
}
|
||||||
|
|
||||||
build_toolchain () {
|
build_toolchain () {
|
||||||
|
|
|
@ -19,7 +19,7 @@ endif ()
|
||||||
set(TOOLCHAIN_PREFIX $ENV{BANAN_ROOT_DIR}/toolchain/local)
|
set(TOOLCHAIN_PREFIX $ENV{BANAN_ROOT_DIR}/toolchain/local)
|
||||||
|
|
||||||
set(CMAKE_SYSTEM_NAME banan-os)
|
set(CMAKE_SYSTEM_NAME banan-os)
|
||||||
set(CMAKE_SYSTEM_PROCESSOR ${BANAN_ARCH})
|
set(CMAKE_SYSTEM_PROCESSOR AMD64)
|
||||||
|
|
||||||
set(CMAKE_SYSROOT ${BANAN_SYSROOT})
|
set(CMAKE_SYSROOT ${BANAN_SYSROOT})
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,6 @@ build_gcc () {
|
||||||
--prefix="$BANAN_TOOLCHAIN_PREFIX" \
|
--prefix="$BANAN_TOOLCHAIN_PREFIX" \
|
||||||
--with-sysroot="$BANAN_SYSROOT" \
|
--with-sysroot="$BANAN_SYSROOT" \
|
||||||
--enable-initfini-array \
|
--enable-initfini-array \
|
||||||
--enable-threads=posix \
|
|
||||||
--enable-shared \
|
--enable-shared \
|
||||||
--enable-lto \
|
--enable-lto \
|
||||||
--disable-nls \
|
--disable-nls \
|
||||||
|
|
|
@ -5,8 +5,6 @@ set(USERSPACE_LIBRARIES
|
||||||
LibGUI
|
LibGUI
|
||||||
LibImage
|
LibImage
|
||||||
LibInput
|
LibInput
|
||||||
LibMath
|
|
||||||
LibPthread
|
|
||||||
)
|
)
|
||||||
|
|
||||||
foreach(library ${USERSPACE_LIBRARIES})
|
foreach(library ${USERSPACE_LIBRARIES})
|
||||||
|
|
|
@ -27,10 +27,28 @@ uint16_t ntohs(uint16_t netshort)
|
||||||
|
|
||||||
in_addr_t inet_addr(const char* cp)
|
in_addr_t inet_addr(const char* cp)
|
||||||
{
|
{
|
||||||
in_addr addr;
|
uint32_t a, b, c, d, n;
|
||||||
if (inet_aton(cp, &addr) == 0)
|
const int ret = sscanf(cp, "%i%n.%i%n.%i%n.%i%n",
|
||||||
|
&a, &n, &b, &n, &c, &n, &d, &n
|
||||||
|
);
|
||||||
|
|
||||||
|
if (ret < 1 || ret > 4 || cp[n] != '\0')
|
||||||
return INADDR_NONE;
|
return INADDR_NONE;
|
||||||
return addr.s_addr;
|
if (ret == 1 && (a > 0xFFFFFFFF))
|
||||||
|
return INADDR_NONE;
|
||||||
|
if (ret == 2 && (a > 0xFF || b > 0xFFFFFF))
|
||||||
|
return INADDR_NONE;
|
||||||
|
if (ret == 3 && (a > 0xFF || b > 0xFF || c > 0xFFFF))
|
||||||
|
return INADDR_NONE;
|
||||||
|
if (ret == 4 && (a > 0xFF || b > 0xFF || c > 0xFF || d > 0xFF))
|
||||||
|
return INADDR_NONE;
|
||||||
|
|
||||||
|
uint32_t result = 0;
|
||||||
|
result |= (ret == 1) ? a : a << 24;
|
||||||
|
result |= (ret == 2) ? b : b << 16;
|
||||||
|
result |= (ret == 3) ? c : c << 8;
|
||||||
|
result |= (ret == 4) ? d : d << 0;
|
||||||
|
return htonl(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* inet_ntoa(struct in_addr in)
|
char* inet_ntoa(struct in_addr in)
|
||||||
|
@ -46,33 +64,6 @@ char* inet_ntoa(struct in_addr in)
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
int inet_aton(const char* cp, struct in_addr* inp)
|
|
||||||
{
|
|
||||||
uint32_t a, b, c, d, n;
|
|
||||||
const int ret = sscanf(cp, "%i%n.%i%n.%i%n.%i%n",
|
|
||||||
&a, &n, &b, &n, &c, &n, &d, &n
|
|
||||||
);
|
|
||||||
|
|
||||||
if (ret < 1 || ret > 4 || cp[n] != '\0')
|
|
||||||
return 0;
|
|
||||||
if (ret == 1 && (a > 0xFFFFFFFF))
|
|
||||||
return 0;
|
|
||||||
if (ret == 2 && (a > 0xFF || b > 0xFFFFFF))
|
|
||||||
return 0;
|
|
||||||
if (ret == 3 && (a > 0xFF || b > 0xFF || c > 0xFFFF))
|
|
||||||
return 0;
|
|
||||||
if (ret == 4 && (a > 0xFF || b > 0xFF || c > 0xFF || d > 0xFF))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
uint32_t result = 0;
|
|
||||||
result |= (ret == 1) ? a : a << 24;
|
|
||||||
result |= (ret == 2) ? b : b << 16;
|
|
||||||
result |= (ret == 3) ? c : c << 8;
|
|
||||||
result |= (ret == 4) ? d : d << 0;
|
|
||||||
inp->s_addr = htonl(result);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* inet_ntop(int af, const void* __restrict src, char* __restrict dst, socklen_t size)
|
const char* inet_ntop(int af, const void* __restrict src, char* __restrict dst, socklen_t size)
|
||||||
{
|
{
|
||||||
if (af == AF_INET)
|
if (af == AF_INET)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <limits.h>
|
|
||||||
|
#define ATEXIT_MAX_FUNCS 128
|
||||||
|
|
||||||
struct atexit_func_entry_t
|
struct atexit_func_entry_t
|
||||||
{
|
{
|
||||||
|
@ -8,12 +9,12 @@ struct atexit_func_entry_t
|
||||||
void* dso_handle;
|
void* dso_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
static atexit_func_entry_t s_atexit_funcs[ATEXIT_MAX];
|
static atexit_func_entry_t s_atexit_funcs[ATEXIT_MAX_FUNCS];
|
||||||
static size_t s_atexit_func_count = 0;
|
static size_t s_atexit_func_count = 0;
|
||||||
|
|
||||||
extern "C" int __cxa_atexit(void(*func)(void*), void* arg, void* dso_handle)
|
extern "C" int __cxa_atexit(void(*func)(void*), void* arg, void* dso_handle)
|
||||||
{
|
{
|
||||||
if (s_atexit_func_count >= ATEXIT_MAX)
|
if (s_atexit_func_count >= ATEXIT_MAX_FUNCS)
|
||||||
return -1;
|
return -1;
|
||||||
s_atexit_funcs[s_atexit_func_count++] = {
|
s_atexit_funcs[s_atexit_func_count++] = {
|
||||||
.func = func,
|
.func = func,
|
||||||
|
|
|
@ -11,7 +11,6 @@ __BEGIN_DECLS
|
||||||
#include <bits/types/socklen_t.h>
|
#include <bits/types/socklen_t.h>
|
||||||
|
|
||||||
in_addr_t inet_addr(const char* cp);
|
in_addr_t inet_addr(const char* cp);
|
||||||
int inet_aton(const char* cp, struct in_addr* inp);
|
|
||||||
char* inet_ntoa(struct in_addr in);
|
char* inet_ntoa(struct in_addr in);
|
||||||
const char* inet_ntop(int af, const void* __restrict src, char* __restrict dst, socklen_t size);
|
const char* inet_ntop(int af, const void* __restrict src, char* __restrict dst, socklen_t size);
|
||||||
int inet_pton(int af, const char* __restrict src, void* __restrict dst);
|
int inet_pton(int af, const char* __restrict src, void* __restrict dst);
|
||||||
|
|
|
@ -10,54 +10,20 @@ __BEGIN_DECLS
|
||||||
#include <bits/inet_common.h>
|
#include <bits/inet_common.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#define IPPROTO_IP 1
|
#define IPPROTO_IP 1
|
||||||
#define IPPROTO_IPV6 2
|
#define IPPROTO_IPV6 2
|
||||||
#define IPPROTO_ICMP 3
|
#define IPPROTO_ICMP 3
|
||||||
#define IPPROTO_RAW 4
|
#define IPPROTO_RAW 4
|
||||||
#define IPPROTO_TCP 5
|
#define IPPROTO_TCP 5
|
||||||
#define IPPROTO_UDP 6
|
#define IPPROTO_UDP 6
|
||||||
|
|
||||||
enum
|
#define IPV6_JOIN_GROUP 1
|
||||||
{
|
#define IPV6_LEAVE_GROUP 2
|
||||||
IP_ADD_MEMBERSHIP,
|
#define IPV6_MULTICAST_HOPS 3
|
||||||
#define IP_ADD_MEMBERSHIP IP_ADD_MEMBERSHIP
|
#define IPV6_MULTICAST_IF 4
|
||||||
IP_ADD_SOURCE_MEMBERSHIP,
|
#define IPV6_MULTICAST_LOOP 5
|
||||||
#define IP_ADD_SOURCE_MEMBERSHIP IP_ADD_SOURCE_MEMBERSHIP
|
#define IPV6_UNICAST_HOPS 6
|
||||||
IP_DROP_MEMBERSHIP,
|
#define IPV6_V6ONLY 7
|
||||||
#define IP_DROP_MEMBERSHIP IP_DROP_MEMBERSHIP
|
|
||||||
IP_DROP_SOURCE_MEMBERSHIP,
|
|
||||||
#define IP_DROP_SOURCE_MEMBERSHIP IP_DROP_SOURCE_MEMBERSHIP
|
|
||||||
IP_MULTICAST_IF,
|
|
||||||
#define IP_MULTICAST_IF IP_MULTICAST_IF
|
|
||||||
IP_MULTICAST_LOOP,
|
|
||||||
#define IP_MULTICAST_LOOP IP_MULTICAST_LOOP
|
|
||||||
IP_MULTICAST_TTL,
|
|
||||||
#define IP_MULTICAST_TTL IP_MULTICAST_TTL
|
|
||||||
IP_TTL,
|
|
||||||
#define IP_TTL IP_TTL
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
IPV6_ADD_MEMBERSHIP,
|
|
||||||
#define IPV6_ADD_MEMBERSHIP IPV6_ADD_MEMBERSHIP
|
|
||||||
IPV6_DROP_MEMBERSHIP,
|
|
||||||
#define IPV6_DROP_MEMBERSHIP IPV6_DROP_MEMBERSHIP
|
|
||||||
IPV6_JOIN_GROUP,
|
|
||||||
#define IPV6_JOIN_GROUP IPV6_JOIN_GROUP
|
|
||||||
IPV6_LEAVE_GROUP,
|
|
||||||
#define IPV6_LEAVE_GROUP IPV6_LEAVE_GROUP
|
|
||||||
IPV6_MULTICAST_HOPS,
|
|
||||||
#define IPV6_MULTICAST_HOPS IPV6_MULTICAST_HOPS
|
|
||||||
IPV6_MULTICAST_IF,
|
|
||||||
#define IPV6_MULTICAST_IF IPV6_MULTICAST_IF
|
|
||||||
IPV6_MULTICAST_LOOP,
|
|
||||||
#define IPV6_MULTICAST_LOOP IPV6_MULTICAST_LOOP
|
|
||||||
IPV6_UNICAST_HOPS,
|
|
||||||
#define IPV6_UNICAST_HOPS IPV6_UNICAST_HOPS
|
|
||||||
IPV6_V6ONLY,
|
|
||||||
#define IPV6_V6ONLY IPV6_V6ONLY
|
|
||||||
};
|
|
||||||
|
|
||||||
#define INADDR_ANY 0
|
#define INADDR_ANY 0
|
||||||
#define INADDR_NONE 0xFFFFFFFF
|
#define INADDR_NONE 0xFFFFFFFF
|
||||||
|
@ -112,19 +78,6 @@ struct ipv6_mreq
|
||||||
unsigned ipv6mr_interface; /* Interface index. */
|
unsigned ipv6mr_interface; /* Interface index. */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ip_mreq
|
|
||||||
{
|
|
||||||
struct in_addr imr_multiaddr; /* IP multicast group address. */
|
|
||||||
struct in_addr imr_interface; /* IP address of local interface. */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ip_mreq_source
|
|
||||||
{
|
|
||||||
struct in_addr imr_multiaddr; /* IP multicast group address. */
|
|
||||||
struct in_addr imr_interface; /* IP address of local interface. */
|
|
||||||
struct in_addr imr_sourceaddr; /* IP address of multicast source. */
|
|
||||||
};
|
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -14,13 +14,11 @@ __BEGIN_DECLS
|
||||||
|
|
||||||
struct passwd
|
struct passwd
|
||||||
{
|
{
|
||||||
char* pw_name; /* User's login name. */
|
char* pw_name; /* User's login name. */
|
||||||
char* pw_passwd; /* User's hashed password. */
|
uid_t pw_uid; /* Numerical user ID. */
|
||||||
uid_t pw_uid; /* Numerical user ID. */
|
gid_t pw_gid; /* Numerical group ID. */
|
||||||
gid_t pw_gid; /* Numerical group ID. */
|
char* pw_dir; /* Initial working directory. */
|
||||||
char* pw_gecos; /* User's information. */
|
char* pw_shell; /* Program to use as shell. */
|
||||||
char* pw_dir; /* Initial working directory. */
|
|
||||||
char* pw_shell; /* Program to use as shell. */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void endpwent(void);
|
void endpwent(void);
|
||||||
|
|
|
@ -50,33 +50,16 @@ struct cmsghdr
|
||||||
socklen_t cmsg_len; /* Data byte count, including the cmsghdr. */
|
socklen_t cmsg_len; /* Data byte count, including the cmsghdr. */
|
||||||
int cmsg_level; /* Originating protocol. */
|
int cmsg_level; /* Originating protocol. */
|
||||||
int cmsg_type; /* Protocol-specific type. */
|
int cmsg_type; /* Protocol-specific type. */
|
||||||
unsigned char __cmg_data[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SCM_RIGHTS 1
|
// FIXME
|
||||||
|
#if 0
|
||||||
|
#define SCM_RIGHTS
|
||||||
|
|
||||||
#define CMSG_DATA(cmsg) ((cmsg)->__cmg_data)
|
#define CMSG_DATA(cmsg)
|
||||||
|
#define CMSG_NXTHDR(mhdr, cmsg)
|
||||||
#define __CMSG_NXTHDR_ADDR(cmsg) \
|
#define CMSG_FIRSTHDR(mhdr)
|
||||||
((unsigned char*)(cmsg) + (cmsg)->cmsg_len)
|
#endif
|
||||||
#define __CMSG_NXTHDR_OFFSET(mhdr, cmsg) \
|
|
||||||
(__CMSG_NXTHDR_ADDR(cmsg) - (unsigned char*)(mhdr)->msg_control)
|
|
||||||
#define CMSG_NXTHDR(mhdr, cmsg) \
|
|
||||||
((size_t)(mhdr)->msg_controllen \
|
|
||||||
>= __CMSG_NXTHDR_OFFSET(mhdr, cmsg) + sizeof(struct cmsghdr) \
|
|
||||||
? (struct cmsghdr*)__CMSG_NXTHDR_ADDR(cmsg) \
|
|
||||||
: (struct cmsghdr*)0)
|
|
||||||
|
|
||||||
#define CMSG_FIRSTHDR(mhdr) \
|
|
||||||
((size_t)(mhdr)->msg_controllen >= sizeof(struct cmsghdr) \
|
|
||||||
? (struct cmsghdr*)((mhdr)->msg_control) \
|
|
||||||
: (struct cmsghdr*)0)
|
|
||||||
|
|
||||||
#define CMSG_SPACE(length) \
|
|
||||||
(socklen_t)((length) + sizeof(struct cmsghdr))
|
|
||||||
|
|
||||||
#define CMSG_LEN(length) \
|
|
||||||
(socklen_t)((length) + sizeof(struct cmsghdr))
|
|
||||||
|
|
||||||
struct linger
|
struct linger
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#include <BAN/Debug.h>
|
#include <BAN/Debug.h>
|
||||||
#include <BAN/Math.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -96,12 +95,6 @@ static bool allocate_pool(size_t pool_index)
|
||||||
node->prev_free = nullptr;
|
node->prev_free = nullptr;
|
||||||
node->next_free = nullptr;
|
node->next_free = nullptr;
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
|
||||||
#pragma GCC diagnostic ignored "-Wstringop-overflow"
|
|
||||||
node->data[-1] = 0;
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
pool.free_list = node;
|
pool.free_list = node;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -150,12 +143,6 @@ static void shrink_node_if_needed(malloc_pool_t& pool, malloc_node_t* node, size
|
||||||
next->size = node_end - (uint8_t*)next;
|
next->size = node_end - (uint8_t*)next;
|
||||||
next->last = node->last;
|
next->last = node->last;
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
|
||||||
#pragma GCC diagnostic ignored "-Wstringop-overflow"
|
|
||||||
next->data[-1] = 0;
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
node->last = false;
|
node->last = false;
|
||||||
|
|
||||||
// insert excess node to free list
|
// insert excess node to free list
|
||||||
|
@ -196,29 +183,6 @@ static void* allocate_from_pool(size_t pool_index, size_t size)
|
||||||
|
|
||||||
static malloc_node_t* node_from_data_pointer(void* data_pointer)
|
static malloc_node_t* node_from_data_pointer(void* data_pointer)
|
||||||
{
|
{
|
||||||
if (((uint8_t*)data_pointer)[-1])
|
|
||||||
{
|
|
||||||
malloc_pool_t* pool = nullptr;
|
|
||||||
for (size_t i = 0; i < s_malloc_pool_count; i++)
|
|
||||||
{
|
|
||||||
if (!s_malloc_pools[i].start)
|
|
||||||
continue;
|
|
||||||
if (data_pointer < s_malloc_pools[i].start)
|
|
||||||
continue;
|
|
||||||
if (data_pointer > s_malloc_pools[i].end())
|
|
||||||
continue;
|
|
||||||
pool = &s_malloc_pools[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
assert(pool);
|
|
||||||
|
|
||||||
auto* node = (malloc_node_t*)pool->start;
|
|
||||||
for (; (uint8_t*)node < pool->end(); node = node->next())
|
|
||||||
if (node->data < data_pointer && data_pointer < node->next())
|
|
||||||
return node;
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (malloc_node_t*)((uint8_t*)data_pointer - sizeof(malloc_node_t));
|
return (malloc_node_t*)((uint8_t*)data_pointer - sizeof(malloc_node_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,27 +332,3 @@ void* calloc(size_t nmemb, size_t size)
|
||||||
memset(ptr, 0, total);
|
memset(ptr, 0, total);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int posix_memalign(void** memptr, size_t alignment, size_t size)
|
|
||||||
{
|
|
||||||
dprintln_if(DEBUG_MALLOC, "posix_memalign({}, {})", alignment, size);
|
|
||||||
|
|
||||||
if (alignment < sizeof(void*) || alignment % sizeof(void*) || !BAN::Math::is_power_of_two(alignment / sizeof(void*)))
|
|
||||||
{
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* unaligned = (uint8_t*)malloc(size + alignment);
|
|
||||||
if (unaligned == nullptr)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (auto rem = (uintptr_t)unaligned % alignment)
|
|
||||||
{
|
|
||||||
unaligned += alignment - rem;
|
|
||||||
unaligned[-1] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*memptr = unaligned;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -147,9 +147,11 @@ error_close_socket:
|
||||||
return EAI_FAIL;
|
return EAI_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <BAN/Debug.h>
|
||||||
|
|
||||||
int getnameinfo(const struct sockaddr* __restrict sa, socklen_t salen, char* __restrict node, socklen_t nodelen, char* __restrict service, socklen_t servicelen, int flags)
|
int getnameinfo(const struct sockaddr* __restrict sa, socklen_t salen, char* __restrict node, socklen_t nodelen, char* __restrict service, socklen_t servicelen, int flags)
|
||||||
{
|
{
|
||||||
(void)flags;
|
printf("getnameinfo(%p, %p, %p, 0x%X)\n", sa, node, service, flags);
|
||||||
|
|
||||||
switch (sa->sa_family)
|
switch (sa->sa_family)
|
||||||
{
|
{
|
||||||
|
|
|
@ -71,14 +71,12 @@ struct passwd* getpwent(void)
|
||||||
switch (i)
|
switch (i)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
s_pwent_struct.pw_name = strndup(ptr, field_len + 1);
|
s_pwent_struct.pw_name = (char*)malloc(field_len + 1);
|
||||||
if (!s_pwent_struct.pw_name)
|
if (!s_pwent_struct.pw_name)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
strcpy(s_pwent_struct.pw_name, ptr);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
s_pwent_struct.pw_passwd = strndup(ptr, field_len + 1);
|
|
||||||
if (!s_pwent_struct.pw_passwd)
|
|
||||||
return nullptr;
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
ASSERT(1 <= field_len && field_len <= 9);
|
ASSERT(1 <= field_len && field_len <= 9);
|
||||||
|
@ -93,19 +91,18 @@ struct passwd* getpwent(void)
|
||||||
s_pwent_struct.pw_gid = atoi(ptr);
|
s_pwent_struct.pw_gid = atoi(ptr);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
s_pwent_struct.pw_gecos = strndup(ptr, field_len + 1);
|
|
||||||
if (!s_pwent_struct.pw_gecos)
|
|
||||||
return nullptr;
|
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
s_pwent_struct.pw_dir = strndup(ptr, field_len + 1);
|
s_pwent_struct.pw_dir = (char*)malloc(field_len + 1);
|
||||||
if (!s_pwent_struct.pw_dir)
|
if (!s_pwent_struct.pw_dir)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
strcpy(s_pwent_struct.pw_dir, ptr);
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
s_pwent_struct.pw_shell = strndup(ptr, field_len + 1);
|
s_pwent_struct.pw_shell = (char*)malloc(field_len + 1);
|
||||||
if (!s_pwent_struct.pw_shell)
|
if (!s_pwent_struct.pw_shell)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
strcpy(s_pwent_struct.pw_shell, ptr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -560,12 +560,9 @@ int mblen(const char* s, size_t n)
|
||||||
case LOCALE_POSIX:
|
case LOCALE_POSIX:
|
||||||
return 1;
|
return 1;
|
||||||
case LOCALE_UTF8:
|
case LOCALE_UTF8:
|
||||||
const auto bytes = BAN::UTF8::byte_length(*s);
|
if (const auto bytes = BAN::UTF8::byte_length(*s); n >= bytes)
|
||||||
if (bytes == BAN::UTF8::invalid)
|
return bytes;
|
||||||
return -1;
|
return -1;
|
||||||
if (n < bytes)
|
|
||||||
return -1;
|
|
||||||
return bytes;
|
|
||||||
}
|
}
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,7 +176,7 @@ namespace LibFont
|
||||||
|
|
||||||
uint32_t len = BAN::UTF8::byte_length(bytes[0]);
|
uint32_t len = BAN::UTF8::byte_length(bytes[0]);
|
||||||
|
|
||||||
if (len == BAN::UTF8::invalid)
|
if (len == 0)
|
||||||
{
|
{
|
||||||
invalid_utf = true;
|
invalid_utf = true;
|
||||||
byte_index = 0;
|
byte_index = 0;
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
set(SOURCES
|
|
||||||
dummy.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(libmath-static STATIC ${SOURCES})
|
|
||||||
add_library(libmath-shared SHARED ${SOURCES})
|
|
||||||
|
|
||||||
target_link_options(libmath-static PRIVATE -nolibc)
|
|
||||||
target_link_options(libmath-shared PRIVATE -nolibc)
|
|
||||||
|
|
||||||
banan_link_library(libmath-static libc)
|
|
||||||
banan_link_library(libmath-shared libc)
|
|
||||||
|
|
||||||
set_target_properties(libmath-static PROPERTIES OUTPUT_NAME libm)
|
|
||||||
set_target_properties(libmath-shared PROPERTIES OUTPUT_NAME libm)
|
|
||||||
|
|
||||||
install(TARGETS libmath-static OPTIONAL)
|
|
||||||
install(TARGETS libmath-shared OPTIONAL)
|
|
|
@ -1,18 +0,0 @@
|
||||||
set(SOURCES
|
|
||||||
dummy.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(libpthread-static STATIC ${SOURCES})
|
|
||||||
add_library(libpthread-shared SHARED ${SOURCES})
|
|
||||||
|
|
||||||
target_link_options(libpthread-static PRIVATE -nolibc)
|
|
||||||
target_link_options(libpthread-shared PRIVATE -nolibc)
|
|
||||||
|
|
||||||
banan_link_library(libpthread-static libc)
|
|
||||||
banan_link_library(libpthread-shared libc)
|
|
||||||
|
|
||||||
set_target_properties(libpthread-static PROPERTIES OUTPUT_NAME libpthread)
|
|
||||||
set_target_properties(libpthread-shared PROPERTIES OUTPUT_NAME libpthread)
|
|
||||||
|
|
||||||
install(TARGETS libpthread-static OPTIONAL)
|
|
||||||
install(TARGETS libpthread-shared OPTIONAL)
|
|
|
@ -500,7 +500,6 @@ BAN::Optional<BAN::String> Input::get_input(BAN::Optional<BAN::StringView> custo
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
break;
|
break;
|
||||||
case '\n':
|
case '\n':
|
||||||
case '\r':
|
|
||||||
{
|
{
|
||||||
BAN::String input;
|
BAN::String input;
|
||||||
MUST(input.append(m_buffers[m_buffer_index]));
|
MUST(input.append(m_buffers[m_buffer_index]));
|
||||||
|
|
|
@ -748,7 +748,7 @@ Rectangle Terminal::putchar(uint8_t ch)
|
||||||
m_utf8_bytes[m_utf8_index++] = ch;
|
m_utf8_bytes[m_utf8_index++] = ch;
|
||||||
|
|
||||||
const size_t utf8_len = BAN::UTF8::byte_length(m_utf8_bytes[0]);
|
const size_t utf8_len = BAN::UTF8::byte_length(m_utf8_bytes[0]);
|
||||||
if (utf8_len == BAN::UTF8::invalid)
|
if (utf8_len == 0)
|
||||||
{
|
{
|
||||||
dwarnln("invalid utf8 leading byte 0x{2H}", ch);
|
dwarnln("invalid utf8 leading byte 0x{2H}", ch);
|
||||||
m_utf8_index = 0;
|
m_utf8_index = 0;
|
||||||
|
|
|
@ -39,29 +39,6 @@ bool is_sorted(BAN::Vector<T>& vec)
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define TEST_ALGORITHM_QSORT(ms) do { \
|
|
||||||
uint64_t duration_us = 0; \
|
|
||||||
printf("qsort\n"); \
|
|
||||||
for (size_t size = 100; duration_us < ms * 1000; size *= 10) { \
|
|
||||||
BAN::Vector<unsigned> data(size, 0); \
|
|
||||||
for (auto& val : data) \
|
|
||||||
val = rand() % 100; \
|
|
||||||
uint64_t start_ns = CURRENT_NS(); \
|
|
||||||
qsort(data.data(), data.size(), sizeof(unsigned), [](const void* a, const void* b) -> int { return *(unsigned*)a - *(unsigned*)b; }); \
|
|
||||||
uint64_t stop_ns = CURRENT_NS(); \
|
|
||||||
if (!is_sorted(data)) { \
|
|
||||||
printf(" \e[31mFAILED!\e[m\n"); \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
duration_us = (stop_ns - start_ns) / 1'000; \
|
|
||||||
printf(" %5d.%03d ms (%zu)\n", \
|
|
||||||
(int)(duration_us / 1000), \
|
|
||||||
(int)(duration_us % 1000), \
|
|
||||||
size \
|
|
||||||
); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
srand(time(0));
|
srand(time(0));
|
||||||
|
@ -72,5 +49,4 @@ int main()
|
||||||
TEST_ALGORITHM(100, BAN::sort::intro_sort);
|
TEST_ALGORITHM(100, BAN::sort::intro_sort);
|
||||||
TEST_ALGORITHM(1000, BAN::sort::sort);
|
TEST_ALGORITHM(1000, BAN::sort::sort);
|
||||||
TEST_ALGORITHM(1000, BAN::sort::radix_sort);
|
TEST_ALGORITHM(1000, BAN::sort::radix_sort);
|
||||||
TEST_ALGORITHM_QSORT(100);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue