Compare commits
4 Commits
d824449ddb
...
918657b658
Author | SHA1 | Date |
---|---|---|
Bananymous | 918657b658 | |
Bananymous | 9781cc5d16 | |
Bananymous | 6ed6fb6f78 | |
Bananymous | 39170a437e |
|
@ -121,9 +121,10 @@ namespace Kernel
|
|||
virtual BAN::ErrorOr<void> chmod_impl(mode_t) { return BAN::Error::from_errno(ENOTSUP); }
|
||||
virtual bool has_data_impl() const { dwarnln("nonblock not supported"); return true; }
|
||||
|
||||
private:
|
||||
mutable RecursiveSpinLock m_lock;
|
||||
protected:
|
||||
mutable RecursivePrioritySpinLock m_lock;
|
||||
|
||||
private:
|
||||
BAN::WeakPtr<SharedFileData> m_shared_region;
|
||||
friend class FileBackedRegion;
|
||||
};
|
||||
|
|
|
@ -29,8 +29,6 @@ namespace Kernel
|
|||
Thread& current_thread();
|
||||
static pid_t current_tid();
|
||||
|
||||
static bool is_valid_tid(pid_t tid);
|
||||
|
||||
[[noreturn]] void execute_current_thread();
|
||||
[[noreturn]] void _execute_current_thread();
|
||||
[[noreturn]] void delete_current_process_and_thread();
|
||||
|
|
|
@ -39,4 +39,24 @@ namespace Kernel
|
|||
SpinLock m_lock;
|
||||
};
|
||||
|
||||
}
|
||||
class RecursivePrioritySpinLock
|
||||
{
|
||||
BAN_NON_COPYABLE(RecursivePrioritySpinLock);
|
||||
BAN_NON_MOVABLE(RecursivePrioritySpinLock);
|
||||
|
||||
public:
|
||||
RecursivePrioritySpinLock() = default;
|
||||
void lock();
|
||||
void unlock();
|
||||
bool is_locked() const;
|
||||
|
||||
uint32_t lock_depth() const { return m_lock_depth; }
|
||||
|
||||
private:
|
||||
pid_t m_locker = -1;
|
||||
uint32_t m_queue_length = 0;
|
||||
uint32_t m_lock_depth = 0;
|
||||
SpinLock m_lock;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -56,8 +56,6 @@ namespace Kernel
|
|||
void do_backspace();
|
||||
|
||||
protected:
|
||||
mutable Kernel::RecursiveSpinLock m_lock;
|
||||
|
||||
TerminalDriver::Color m_foreground { TerminalColor::BRIGHT_WHITE };
|
||||
TerminalDriver::Color m_background { TerminalColor::BLACK };
|
||||
termios m_termios;
|
||||
|
|
|
@ -378,26 +378,4 @@ namespace Kernel
|
|||
}
|
||||
}
|
||||
|
||||
bool Scheduler::is_valid_tid(pid_t tid)
|
||||
{
|
||||
CriticalScope _;
|
||||
|
||||
if (s_instance == nullptr)
|
||||
return tid == 0;
|
||||
|
||||
for (auto& thread : s_instance->m_active_threads)
|
||||
if (thread.thread->tid() == tid)
|
||||
return true;
|
||||
|
||||
for (auto& thread : s_instance->m_sleeping_threads)
|
||||
if (thread.thread->tid() == tid)
|
||||
return true;
|
||||
|
||||
for (auto& thread : s_instance->m_blocking_threads)
|
||||
if (thread.thread->tid() == tid)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Kernel
|
|||
{
|
||||
CriticalScope _;
|
||||
ASSERT(m_locker != tid);
|
||||
if (m_locker == -1 || !Scheduler::is_valid_tid(m_locker))
|
||||
if (m_locker == -1)
|
||||
{
|
||||
m_locker = tid;
|
||||
break;
|
||||
|
@ -48,7 +48,7 @@ namespace Kernel
|
|||
m_lock_depth++;
|
||||
break;
|
||||
}
|
||||
if (m_locker == -1 || !Scheduler::is_valid_tid(m_locker))
|
||||
if (m_locker == -1)
|
||||
{
|
||||
m_locker = tid;
|
||||
m_lock_depth = 1;
|
||||
|
@ -80,4 +80,61 @@ namespace Kernel
|
|||
return m_locker != -1;
|
||||
}
|
||||
|
||||
void RecursivePrioritySpinLock::lock()
|
||||
{
|
||||
pid_t tid = Scheduler::current_tid();
|
||||
|
||||
bool has_priority = !Thread::current().is_userspace();
|
||||
|
||||
if (has_priority)
|
||||
{
|
||||
m_lock.lock();
|
||||
m_queue_length++;
|
||||
m_lock.unlock();
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
m_lock.lock();
|
||||
if (m_locker == tid)
|
||||
{
|
||||
m_lock_depth++;
|
||||
break;
|
||||
}
|
||||
if (m_locker == -1 && (has_priority || m_queue_length == 0))
|
||||
{
|
||||
m_locker = tid;
|
||||
m_lock_depth = 1;
|
||||
break;
|
||||
}
|
||||
m_lock.unlock();
|
||||
}
|
||||
|
||||
m_lock.unlock();
|
||||
}
|
||||
|
||||
void RecursivePrioritySpinLock::unlock()
|
||||
{
|
||||
m_lock.lock();
|
||||
|
||||
ASSERT(m_lock_depth > 0);
|
||||
ASSERT(m_locker == Scheduler::current_tid());
|
||||
|
||||
bool has_priority = !Thread::current().is_userspace();
|
||||
if (has_priority)
|
||||
m_queue_length--;
|
||||
|
||||
m_lock_depth--;
|
||||
|
||||
if (m_lock_depth == 0)
|
||||
m_locker = -1;
|
||||
|
||||
m_lock.unlock();
|
||||
}
|
||||
|
||||
bool RecursivePrioritySpinLock::is_locked() const
|
||||
{
|
||||
return m_locker != -1;
|
||||
}
|
||||
|
||||
}
|
|
@ -303,9 +303,13 @@ namespace Kernel
|
|||
LockGuard _(m_lock);
|
||||
while (!m_output.flush)
|
||||
{
|
||||
m_lock.unlock();
|
||||
// FIXME: this is very hacky way to unlock lock temporarily
|
||||
uint32_t depth = m_lock.lock_depth();
|
||||
for (uint32_t i = 0; i < depth; i++)
|
||||
m_lock.unlock();
|
||||
bool eintr = Thread::current().block_or_eintr(m_output.semaphore);
|
||||
m_lock.lock();
|
||||
for (uint32_t i = 0; i < depth; i++)
|
||||
m_lock.lock();
|
||||
if (eintr)
|
||||
return BAN::Error::from_errno(EINTR);
|
||||
}
|
||||
|
|
|
@ -469,30 +469,24 @@ pid_t execute_command_no_wait(BAN::Vector<BAN::String>& args, int fd_in, int fd_
|
|||
|
||||
// do PATH resolution
|
||||
BAN::String executable_file;
|
||||
if (!args.front().empty() && args.front().front() != '.' && args.front().front() != '/')
|
||||
if (!args.front().sv().contains('/'))
|
||||
{
|
||||
char* path_env_cstr = getenv("PATH");
|
||||
if (path_env_cstr)
|
||||
const char* path_env_cstr = getenv("PATH");
|
||||
if (path_env_cstr == nullptr)
|
||||
path_env_cstr = "";
|
||||
|
||||
auto path_env_list = MUST(BAN::StringView(path_env_cstr).split(':'));
|
||||
for (auto path_env : path_env_list)
|
||||
{
|
||||
auto path_env_list = MUST(BAN::StringView(path_env_cstr).split(':'));
|
||||
for (auto path_env : path_env_list)
|
||||
{
|
||||
BAN::String test_file = path_env;
|
||||
MUST(test_file.push_back('/'));
|
||||
MUST(test_file.append(args.front()));
|
||||
BAN::String test_file = path_env;
|
||||
MUST(test_file.push_back('/'));
|
||||
MUST(test_file.append(args.front()));
|
||||
|
||||
struct stat st;
|
||||
if (stat(test_file.data(), &st) == 0)
|
||||
{
|
||||
executable_file = BAN::move(test_file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (executable_file.empty())
|
||||
struct stat st;
|
||||
if (stat(test_file.data(), &st) == 0)
|
||||
{
|
||||
fprintf(stderr, "command not found: %s\n", args.front().data());
|
||||
return -1;
|
||||
executable_file = BAN::move(test_file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -504,7 +498,7 @@ pid_t execute_command_no_wait(BAN::Vector<BAN::String>& args, int fd_in, int fd_
|
|||
// Verify that the file exists is executable
|
||||
{
|
||||
struct stat st;
|
||||
if (stat(executable_file.data(), &st) == -1)
|
||||
if (executable_file.empty() || stat(executable_file.data(), &st) == -1)
|
||||
{
|
||||
fprintf(stderr, "command not found: %s\n", args.front().data());
|
||||
return -1;
|
||||
|
|
Loading…
Reference in New Issue