[kernel] Add object_wait_many syscall
Add the object_wait_many syscall to allow programs to wait for signals on multiple objects at once. Also removed the object argument to thread::wait_on_signals, which does nothing with it. That information is saved in the thread being in the object's blocked threads list.
This commit is contained in:
@@ -37,7 +37,7 @@ object_wait(j6_handle_t handle, j6_signal_t mask, j6_signal_t *sigs)
|
||||
|
||||
thread &th = thread::current();
|
||||
obj->add_blocked_thread(&th);
|
||||
th.wait_on_signals(obj, mask);
|
||||
th.wait_on_signals(mask);
|
||||
|
||||
j6_status_t result = th.get_wait_result();
|
||||
if (result == j6_status_ok) {
|
||||
@@ -46,6 +46,55 @@ object_wait(j6_handle_t handle, j6_signal_t mask, j6_signal_t *sigs)
|
||||
return result;
|
||||
}
|
||||
|
||||
j6_status_t
|
||||
object_wait_many(j6_handle_t *handles, uint32_t count, j6_signal_t mask, j6_handle_t *handle, j6_signal_t *sigs)
|
||||
{
|
||||
kutil::vector<kobject*> objects {count};
|
||||
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
j6_handle_t h = handles[i];
|
||||
if (h == j6_handle_invalid)
|
||||
continue;
|
||||
|
||||
kobject *obj = get_handle<kobject>(h);
|
||||
if (!obj)
|
||||
return j6_err_invalid_arg;
|
||||
|
||||
j6_signal_t current = obj->signals();
|
||||
if ((current & mask) != 0) {
|
||||
*sigs = current;
|
||||
*handle = h;
|
||||
return j6_status_ok;
|
||||
}
|
||||
|
||||
objects.append(obj);
|
||||
}
|
||||
|
||||
thread &th = thread::current();
|
||||
for (auto *obj : objects)
|
||||
obj->add_blocked_thread(&th);
|
||||
|
||||
th.wait_on_signals(mask);
|
||||
|
||||
j6_status_t result = th.get_wait_result();
|
||||
if (result != j6_status_ok)
|
||||
return result;
|
||||
|
||||
*handle = j6_handle_invalid;
|
||||
*sigs = th.get_wait_data();
|
||||
j6_koid_t koid = th.get_wait_object();
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
if (koid == objects[i]->koid())
|
||||
*handle = handles[i];
|
||||
else
|
||||
objects[i]->remove_blocked_thread(&th);
|
||||
}
|
||||
|
||||
kassert(*handle != j6_handle_invalid,
|
||||
"Somehow woke on a handle that was not waited on");
|
||||
return j6_status_ok;
|
||||
}
|
||||
|
||||
j6_status_t
|
||||
object_signal(j6_handle_t handle, j6_signal_t signals)
|
||||
{
|
||||
|
||||
@@ -40,7 +40,7 @@ j6_status_t
|
||||
thread_pause()
|
||||
{
|
||||
thread &th = thread::current();
|
||||
th.wait_on_signals(&th, -1ull);
|
||||
th.wait_on_signals(-1ull);
|
||||
return j6_status_ok;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user