Added new syscalls _kern_block_thread()/_kern_unblock_thread[s]().
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25469 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -130,6 +130,11 @@ extern status_t _kern_get_team_info(team_id id, team_info *info);
|
|||||||
extern status_t _kern_get_next_team_info(int32 *cookie, team_info *info);
|
extern status_t _kern_get_next_team_info(int32 *cookie, team_info *info);
|
||||||
extern status_t _kern_get_team_usage_info(team_id team, int32 who, team_usage_info *info, size_t size);
|
extern status_t _kern_get_team_usage_info(team_id team, int32 who, team_usage_info *info, size_t size);
|
||||||
|
|
||||||
|
extern status_t _kern_block_thread(uint32 flags, bigtime_t timeout);
|
||||||
|
extern status_t _kern_unblock_thread(thread_id thread, status_t status);
|
||||||
|
extern status_t _kern_unblock_threads(thread_id* threads, uint32 count,
|
||||||
|
status_t status);
|
||||||
|
|
||||||
// user/group functions
|
// user/group functions
|
||||||
extern gid_t _kern_getgid(bool effective);
|
extern gid_t _kern_getgid(bool effective);
|
||||||
extern uid_t _kern_getuid(bool effective);
|
extern uid_t _kern_getuid(bool effective);
|
||||||
|
|||||||
@@ -117,6 +117,11 @@ thread_id _user_find_thread(const char *name);
|
|||||||
status_t _user_get_thread_info(thread_id id, thread_info *info);
|
status_t _user_get_thread_info(thread_id id, thread_info *info);
|
||||||
status_t _user_get_next_thread_info(team_id team, int32 *cookie, thread_info *info);
|
status_t _user_get_next_thread_info(team_id team, int32 *cookie, thread_info *info);
|
||||||
|
|
||||||
|
status_t _user_block_thread(uint32 flags, bigtime_t timeout);
|
||||||
|
status_t _user_unblock_thread(thread_id thread, status_t status);
|
||||||
|
status_t _user_unblock_threads(thread_id* threads, uint32 count,
|
||||||
|
status_t status);
|
||||||
|
|
||||||
// ToDo: these don't belong here
|
// ToDo: these don't belong here
|
||||||
struct rlimit;
|
struct rlimit;
|
||||||
int _user_getrlimit(int resource, struct rlimit * rlp);
|
int _user_getrlimit(int resource, struct rlimit * rlp);
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include <team.h>
|
#include <team.h>
|
||||||
#include <tls.h>
|
#include <tls.h>
|
||||||
#include <user_runtime.h>
|
#include <user_runtime.h>
|
||||||
|
#include <user_thread.h>
|
||||||
#include <vfs.h>
|
#include <vfs.h>
|
||||||
#include <vm.h>
|
#include <vm.h>
|
||||||
#include <vm_address_space.h>
|
#include <vm_address_space.h>
|
||||||
@@ -2309,6 +2310,23 @@ thread_block_with_timeout_locked(uint32 timeoutFlags, bigtime_t timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Thread spinlock must be held.
|
||||||
|
*/
|
||||||
|
static status_t
|
||||||
|
user_unblock_thread(thread_id threadID, status_t status)
|
||||||
|
{
|
||||||
|
struct thread* thread = thread_get_thread_struct_locked(threadID);
|
||||||
|
if (thread == NULL)
|
||||||
|
return B_BAD_THREAD_ID;
|
||||||
|
if (thread->user_thread == NULL)
|
||||||
|
return B_NOT_ALLOWED;
|
||||||
|
|
||||||
|
thread_unblock_locked(thread, status);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - public kernel API
|
// #pragma mark - public kernel API
|
||||||
|
|
||||||
|
|
||||||
@@ -2903,7 +2921,61 @@ _user_receive_data(thread_id *_userSender, void *buffer, size_t bufferSize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ToDo: the following two functions don't belong here
|
status_t
|
||||||
|
_user_block_thread(uint32 flags, bigtime_t timeout)
|
||||||
|
{
|
||||||
|
syscall_restart_handle_timeout_pre(flags, timeout);
|
||||||
|
flags |= B_CAN_INTERRUPT;
|
||||||
|
|
||||||
|
struct thread* thread = thread_get_current_thread();
|
||||||
|
|
||||||
|
InterruptsSpinLocker locker(thread_spinlock);
|
||||||
|
|
||||||
|
// check, if already done
|
||||||
|
if (thread->user_thread->wait_status <= 0)
|
||||||
|
return thread->user_thread->wait_status;
|
||||||
|
|
||||||
|
// nope, so wait
|
||||||
|
thread_prepare_to_block(thread, flags, THREAD_BLOCK_TYPE_OTHER, "user");
|
||||||
|
status_t status = thread_block_with_timeout_locked(flags, timeout);
|
||||||
|
thread->user_thread->wait_status = status;
|
||||||
|
|
||||||
|
return syscall_restart_handle_timeout_post(status, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
_user_unblock_thread(thread_id threadID, status_t status)
|
||||||
|
{
|
||||||
|
InterruptsSpinLocker locker(thread_spinlock);
|
||||||
|
return user_unblock_thread(threadID, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
_user_unblock_threads(thread_id* userThreads, uint32 count, status_t status)
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
MAX_USER_THREADS_TO_UNBLOCK = 128
|
||||||
|
};
|
||||||
|
|
||||||
|
if (userThreads == NULL || !IS_USER_ADDRESS(userThreads))
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
if (count > MAX_USER_THREADS_TO_UNBLOCK)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
thread_id threads[MAX_USER_THREADS_TO_UNBLOCK];
|
||||||
|
if (user_memcpy(threads, userThreads, count * sizeof(thread_id)) != B_OK)
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < count; i++)
|
||||||
|
user_unblock_thread(threads[i], status);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: the following two functions don't belong here
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|||||||
Reference in New Issue
Block a user