Added and implemented new system calls switch_sem() and switch_sem_etc(); even if

they are public now, they might become private later on.
It's almost the same as acquire_sem() but allows you to release another semaphore
atomically. This makes condvar implementations and the like very simple to do.
Added B_CHECK_PERMISSION flags to the user calls, although it's not honored yet.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@11887 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2005-03-17 22:35:00 +00:00
parent 63531836b9
commit 34e92cad76
5 changed files with 70 additions and 8 deletions

View File

@ -170,6 +170,11 @@ extern status_t acquire_sem(sem_id id);
extern status_t acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout);
extern status_t release_sem(sem_id id);
extern status_t release_sem_etc(sem_id id, int32 count, uint32 flags);
// ToDo: the following two calls are not part of the BeOS API, and might be
// changed or even removed for the final release of Haiku R1
extern status_t switch_sem(sem_id semToBeReleased, sem_id id);
extern status_t switch_sem_etc(sem_id semToBeReleased, sem_id id, int32 count,
uint32 flags, bigtime_t timeout);
extern status_t get_sem_count(sem_id id, int32 *threadCount);
extern status_t set_sem_owner(sem_id id, team_id team);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2004, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
@ -12,7 +12,6 @@
#include <OS.h>
#include <thread.h>
struct kernel_args;
@ -33,6 +32,8 @@ sem_id _user_create_sem(int32 count, const char *name);
status_t _user_delete_sem(sem_id id);
status_t _user_acquire_sem(sem_id id);
status_t _user_acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout);
status_t _user_switch_sem(sem_id releaseSem, sem_id id);
status_t _user_switch_sem_etc(sem_id releaseSem, sem_id id, int32 count, uint32 flags, bigtime_t timeout);
status_t _user_release_sem(sem_id id);
status_t _user_release_sem_etc(sem_id id, int32 count, uint32 flags);
status_t _user_get_sem_count(sem_id id, int32* thread_count);

View File

@ -46,6 +46,9 @@ extern status_t _kern_get_safemode_option(const char *parameter, char *buffer,
/* sem functions */
extern sem_id _kern_create_sem(int count, const char *name);
extern status_t _kern_delete_sem(sem_id id);
extern status_t _kern_switch_sem(sem_id releaseSem, sem_id id);
extern status_t _kern_switch_sem_etc(sem_id releaseSem, sem_id id, uint32 count,
uint32 flags, bigtime_t timeout);
extern status_t _kern_acquire_sem(sem_id id);
extern status_t _kern_acquire_sem_etc(sem_id id, uint32 count, uint32 flags, bigtime_t timeout);
extern status_t _kern_release_sem(sem_id id);

View File

@ -407,12 +407,29 @@ sem_timeout(timer *data)
status_t
acquire_sem(sem_id id)
{
return acquire_sem_etc(id, 1, 0, 0);
return switch_sem_etc(-1, id, 1, 0, 0);
}
status_t
acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout)
{
return switch_sem_etc(-1, id, count, flags, timeout);
}
status_t
switch_sem(sem_id toBeReleased, sem_id toBeAcquired)
{
return switch_sem_etc(toBeReleased, toBeAcquired, 1, 0, 0);
}
status_t
switch_sem_etc(sem_id semToBeReleased, sem_id id, int32 count,
uint32 flags, bigtime_t timeout)
{
// ToDo: add support for B_CHECK_PERMISSION
int slot = id % sMaxSems;
int state;
status_t status = B_OK;
@ -494,6 +511,10 @@ acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout)
}
RELEASE_SEM_LOCK(sSems[slot]);
if (semToBeReleased >= B_OK)
release_sem_etc(semToBeReleased, 1, B_DO_NOT_RESCHEDULE);
GRAB_THREAD_LOCK();
// check again to see if a signal is pending.
// it may have been delivered while setting up the sem, though it's pretty unlikely
@ -553,6 +574,7 @@ release_sem(sem_id id)
status_t
release_sem_etc(sem_id id, int32 count, uint32 flags)
{
// ToDo: add support for B_CHECK_PERMISSION
struct thread_queue releaseQueue;
int32 slot = id % sMaxSems;
cpu_status state;
@ -998,28 +1020,42 @@ _user_delete_sem(sem_id id)
status_t
_user_acquire_sem(sem_id id)
{
return _user_acquire_sem_etc(id, 1, 0, 0);
return switch_sem_etc(-1, id, 1, B_CAN_INTERRUPT | B_CHECK_PERMISSION, 0);
}
status_t
_user_acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout)
{
return acquire_sem_etc(id, count, flags | B_CAN_INTERRUPT, timeout);
return switch_sem_etc(-1, id, count, flags | B_CAN_INTERRUPT | B_CHECK_PERMISSION, timeout);
}
status_t
_user_switch_sem(sem_id releaseSem, sem_id id)
{
return switch_sem_etc(releaseSem, id, 1, B_CAN_INTERRUPT | B_CHECK_PERMISSION, 0);
}
status_t
_user_switch_sem_etc(sem_id releaseSem, sem_id id, int32 count, uint32 flags, bigtime_t timeout)
{
return switch_sem_etc(releaseSem, id, count, flags | B_CAN_INTERRUPT | B_CHECK_PERMISSION, timeout);
}
status_t
_user_release_sem(sem_id id)
{
return release_sem_etc(id, 1, 0);
return release_sem_etc(id, 1, B_CHECK_PERMISSION);
}
status_t
_user_release_sem_etc(sem_id id, int32 count, uint32 flags)
{
return release_sem_etc(id, count, flags);
return release_sem_etc(id, count, flags | B_CHECK_PERMISSION);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
@ -36,6 +36,23 @@ acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout)
}
// ToDo: the next two calls (switch_sem()) are not yet public API; no decision
// has been made yet, so they may get changed or removed until R1
status_t
switch_sem(sem_id releaseSem, sem_id id)
{
return _kern_switch_sem(releaseSem, id);
}
status_t
switch_sem_etc(sem_id releaseSem, sem_id id, int32 count, uint32 flags, bigtime_t timeout)
{
return _kern_switch_sem_etc(releaseSem, id, count, flags, timeout);
}
status_t
release_sem(sem_id id)
{