* Renamed fs/vfs_select.cpp to wait_for_objects.cpp and got rid of

vfs_select.h, respectively moved most of it into the new kernel
  private header wait_for_objects.h.
* Added new experimental API functions wait_for_objects[_etc](). They
  work pretty much like poll(), but also for semaphores, ports, and
  threads.
* Removed the "ref" parameter from notify_select_events() and the
  select_sync_pool functions as well as from fd_ops::fd_[de]select(). It
  is no longer needed. The FS interface select() hook still has it,
  though -- the VFS will always pass 0.
* de]select_fd() take a select_info* instead of a select_sync* + ref
  pair, now. Added respective functions for semaphores, ports, and
  threads.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22416 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2007-10-02 19:47:31 +00:00
parent a82d70c719
commit 636bfc08ae
37 changed files with 717 additions and 160 deletions
+82 -8
View File
@@ -9,8 +9,19 @@
/*! Threading routines */
#include <thread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/resource.h>
#include <OS.h>
#include <util/AutoLock.h>
#include <util/khash.h>
#include <boot/kernel_args.h>
#include <condition_variable.h>
#include <cpu.h>
#include <int.h>
@@ -20,20 +31,13 @@
#include <smp.h>
#include <syscalls.h>
#include <team.h>
#include <thread.h>
#include <tls.h>
#include <user_runtime.h>
#include <vfs.h>
#include <vm.h>
#include <vm_address_space.h>
#include <wait_for_objects.h>
#include <boot/kernel_args.h>
#include <util/khash.h>
#include <sys/resource.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
//#define TRACE_THREAD
#ifdef TRACE_THREAD
@@ -249,6 +253,7 @@ create_thread_struct(struct thread *inthread, const char *name,
thread->exit.reason = 0;
thread->exit.signal = 0;
list_init(&thread->exit.waiters);
thread->select_infos = NULL;
sprintf(temp, "thread_0x%lx_retcode_sem", thread->id);
thread->exit.sem = create_sem(0, temp);
@@ -1223,11 +1228,25 @@ thread_exit(void)
debugInfo = thread->debug_info;
clear_thread_debug_info(&thread->debug_info, true);
// Remove the select infos. We notify them a little later.
select_info* selectInfos = thread->select_infos;
thread->select_infos = NULL;
RELEASE_THREAD_LOCK();
restore_interrupts(state);
destroy_thread_debug_info(&debugInfo);
// notify select infos
select_info* info = selectInfos;
while (info != NULL) {
select_sync* sync = info->sync;
notify_select_events(info, B_EVENT_INVALID);
info = info->next;
put_select_sync(sync);
}
// shutdown the thread messaging
status = acquire_sem_etc(thread->msg.write_sem, 1, B_RELATIVE_TIMEOUT, 0);
@@ -1613,6 +1632,61 @@ wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout,
}
status_t
select_thread(int32 id, struct select_info* info, bool kernel)
{
InterruptsSpinLocker locker(thread_spinlock);
// get thread
struct thread* thread = thread_get_thread_struct_locked(id);
if (thread == NULL)
return B_BAD_THREAD_ID;
// We support only B_EVENT_INVALID at the moment.
info->selected_events &= B_EVENT_INVALID;
// add info to list
if (info->selected_events != 0) {
info->next = thread->select_infos;
thread->select_infos = info;
// we need a sync reference
atomic_add(&info->sync->ref_count, 1);
}
return B_OK;
}
status_t
deselect_thread(int32 id, struct select_info* info, bool kernel)
{
InterruptsSpinLocker locker(thread_spinlock);
// get thread
struct thread* thread = thread_get_thread_struct_locked(id);
if (thread == NULL)
return B_BAD_THREAD_ID;
// remove info from list
select_info** infoLocation = &thread->select_infos;
while (*infoLocation != NULL && *infoLocation != info)
infoLocation = &(*infoLocation)->next;
if (*infoLocation != info)
return B_OK;
*infoLocation = info->next;
locker.Unlock();
// surrender sync reference
put_select_sync(info->sync);
return B_OK;
}
int32
thread_max_threads(void)
{