Cleaned up _get_sem_info() and _get_next_sem_info().
Implemented the B_CURRENT_TEAM mechanism for _get_next_sem_info(). git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6691 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+43
-42
@@ -656,6 +656,24 @@ get_sem_count(sem_id id, int32 *thread_count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Fills the thread_info structure with information from the specified
|
||||||
|
* thread.
|
||||||
|
* The thread lock must be held when called.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
fill_sem_info(struct sem_entry *sem, sem_info *info, size_t size)
|
||||||
|
{
|
||||||
|
info->sem = sem->id;
|
||||||
|
info->team = sem->u.used.owner;
|
||||||
|
strlcpy(info->name, sem->u.used.name, sizeof(info->name));
|
||||||
|
info->count = sem->u.used.count;
|
||||||
|
info->latest_holder = sem->u.used.q.head->id;
|
||||||
|
// ToDo: not sure if this is the latest holder, or the next
|
||||||
|
// holder...
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** The underscore is needed for binary compatibility with BeOS.
|
/** The underscore is needed for binary compatibility with BeOS.
|
||||||
* OS.h contains the following macro:
|
* OS.h contains the following macro:
|
||||||
* #define get_sem_info(sem, info) \
|
* #define get_sem_info(sem, info) \
|
||||||
@@ -663,17 +681,18 @@ get_sem_count(sem_id id, int32 *thread_count)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_get_sem_info(sem_id id, struct sem_info *info, size_t sz)
|
_get_sem_info(sem_id id, struct sem_info *info, size_t size)
|
||||||
{
|
{
|
||||||
|
status_t status = B_OK;
|
||||||
int state;
|
int state;
|
||||||
int slot;
|
int slot;
|
||||||
|
|
||||||
if (gSemsActive == false)
|
if (!gSemsActive)
|
||||||
return B_NO_MORE_SEMS;
|
return B_NO_MORE_SEMS;
|
||||||
if (id < 0)
|
if (id < 0)
|
||||||
return B_BAD_SEM_ID;
|
return B_BAD_SEM_ID;
|
||||||
if (info == NULL)
|
if (info == NULL || size != sizeof(sem_info))
|
||||||
return EINVAL;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
slot = id % MAX_SEMS;
|
slot = id % MAX_SEMS;
|
||||||
|
|
||||||
@@ -681,23 +700,15 @@ _get_sem_info(sem_id id, struct sem_info *info, size_t sz)
|
|||||||
GRAB_SEM_LOCK(gSems[slot]);
|
GRAB_SEM_LOCK(gSems[slot]);
|
||||||
|
|
||||||
if (gSems[slot].id != id) {
|
if (gSems[slot].id != id) {
|
||||||
RELEASE_SEM_LOCK(gSems[slot]);
|
status = B_BAD_SEM_ID;
|
||||||
restore_interrupts(state);
|
|
||||||
TRACE(("get_sem_info: invalid sem_id %ld\n", id));
|
TRACE(("get_sem_info: invalid sem_id %ld\n", id));
|
||||||
return B_BAD_SEM_ID;
|
} else
|
||||||
}
|
fill_sem_info(&gSems[slot], info, size);
|
||||||
|
|
||||||
info->sem = gSems[slot].id;
|
|
||||||
info->team = gSems[slot].u.used.owner;
|
|
||||||
strncpy(info->name, gSems[slot].u.used.name, SYS_MAX_OS_NAME_LEN-1);
|
|
||||||
info->count = gSems[slot].u.used.count;
|
|
||||||
info->latest_holder = gSems[slot].u.used.q.head->id;
|
|
||||||
// XXX not sure if this is correct
|
|
||||||
|
|
||||||
RELEASE_SEM_LOCK(gSems[slot]);
|
RELEASE_SEM_LOCK(gSems[slot]);
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
|
|
||||||
return B_NO_ERROR;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -708,31 +719,27 @@ _get_sem_info(sem_id id, struct sem_info *info, size_t sz)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_get_next_sem_info(team_id team, int32 *cookie, struct sem_info *info, size_t sz)
|
_get_next_sem_info(team_id team, int32 *_cookie, struct sem_info *info, size_t size)
|
||||||
{
|
{
|
||||||
int state;
|
int state;
|
||||||
int slot;
|
int slot;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
if (gSemsActive == false)
|
if (!gSemsActive)
|
||||||
return B_NO_MORE_SEMS;
|
return B_NO_MORE_SEMS;
|
||||||
if (cookie == NULL)
|
if (_cookie == NULL || info == NULL || size != sizeof(sem_info))
|
||||||
return EINVAL;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
if (team == B_CURRENT_TEAM)
|
||||||
|
team = team_get_current_team_id();
|
||||||
/* prevents gSems[].owner == -1 >= means owned by a port */
|
/* prevents gSems[].owner == -1 >= means owned by a port */
|
||||||
if (team < 0)
|
if (team < 0 || !team_is_valid(team))
|
||||||
return B_BAD_TEAM_ID;
|
return B_BAD_TEAM_ID;
|
||||||
|
|
||||||
if (*cookie == 0) {
|
slot = *_cookie;
|
||||||
// return first found
|
if (slot >= MAX_SEMS)
|
||||||
slot = 0;
|
return B_BAD_VALUE;
|
||||||
}
|
|
||||||
else {
|
|
||||||
// start at index cookie, but check cookie against MAX_SEMS
|
|
||||||
slot = *cookie;
|
|
||||||
if (slot >= MAX_SEMS)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
}
|
|
||||||
// spinlock
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_SEM_LIST_LOCK();
|
GRAB_SEM_LIST_LOCK();
|
||||||
|
|
||||||
@@ -741,14 +748,7 @@ _get_next_sem_info(team_id team, int32 *cookie, struct sem_info *info, size_t sz
|
|||||||
GRAB_SEM_LOCK(gSems[slot]);
|
GRAB_SEM_LOCK(gSems[slot]);
|
||||||
if (gSems[slot].id != -1 && gSems[slot].u.used.owner == team) {
|
if (gSems[slot].id != -1 && gSems[slot].u.used.owner == team) {
|
||||||
// found one!
|
// found one!
|
||||||
info->sem = gSems[slot].id;
|
fill_sem_info(&gSems[slot], info, size);
|
||||||
info->team = gSems[slot].u.used.owner;
|
|
||||||
strncpy(info->name, gSems[slot].u.used.name,
|
|
||||||
SYS_MAX_OS_NAME_LEN-1);
|
|
||||||
info->count = gSems[slot].u.used.count;
|
|
||||||
info->latest_holder = gSems[slot].u.used.q.head->id;
|
|
||||||
// XXX not sure if this is the latest holder, or the next
|
|
||||||
// holder...
|
|
||||||
|
|
||||||
RELEASE_SEM_LOCK(gSems[slot]);
|
RELEASE_SEM_LOCK(gSems[slot]);
|
||||||
slot++;
|
slot++;
|
||||||
@@ -764,8 +764,9 @@ _get_next_sem_info(team_id team, int32 *cookie, struct sem_info *info, size_t sz
|
|||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
*cookie = slot;
|
|
||||||
return B_NO_ERROR;
|
*_cookie = slot;
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user