* Cleanup, no functional change.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34321 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+70
-48
@@ -11,6 +11,8 @@
|
|||||||
/*! Team functions */
|
/*! Team functions */
|
||||||
|
|
||||||
|
|
||||||
|
#include <team.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -39,7 +41,6 @@
|
|||||||
#include <syscall_process_info.h>
|
#include <syscall_process_info.h>
|
||||||
#include <syscall_restart.h>
|
#include <syscall_restart.h>
|
||||||
#include <syscalls.h>
|
#include <syscalls.h>
|
||||||
#include <team.h>
|
|
||||||
#include <tls.h>
|
#include <tls.h>
|
||||||
#include <tracing.h>
|
#include <tracing.h>
|
||||||
#include <user_runtime.h>
|
#include <user_runtime.h>
|
||||||
@@ -386,7 +387,8 @@ dump_team_info(int argc, char **argv)
|
|||||||
// walk through the thread list, trying to match name or id
|
// walk through the thread list, trying to match name or id
|
||||||
hash_open(sTeamHash, &iterator);
|
hash_open(sTeamHash, &iterator);
|
||||||
while ((team = (struct team*)hash_next(sTeamHash, &iterator)) != NULL) {
|
while ((team = (struct team*)hash_next(sTeamHash, &iterator)) != NULL) {
|
||||||
if ((team->name && strcmp(argv[1], team->name) == 0) || team->id == id) {
|
if ((team->name && strcmp(argv[1], team->name) == 0)
|
||||||
|
|| team->id == id) {
|
||||||
_dump_team_info(team);
|
_dump_team_info(team);
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
@@ -485,9 +487,11 @@ insert_team_into_parent(struct team *parent, struct team *team)
|
|||||||
static void
|
static void
|
||||||
remove_team_from_parent(struct team* parent, struct team* team)
|
remove_team_from_parent(struct team* parent, struct team* team)
|
||||||
{
|
{
|
||||||
struct team *child, *last = NULL;
|
struct team* child;
|
||||||
|
struct team* last = NULL;
|
||||||
|
|
||||||
for (child = parent->children; child != NULL; child = child->siblings_next) {
|
for (child = parent->children; child != NULL;
|
||||||
|
child = child->siblings_next) {
|
||||||
if (child == team) {
|
if (child == team) {
|
||||||
if (last == NULL)
|
if (last == NULL)
|
||||||
parent->children = child->siblings_next;
|
parent->children = child->siblings_next;
|
||||||
@@ -624,7 +628,8 @@ release_process_group_ref(pid_t groupID)
|
|||||||
|
|
||||||
/*! You must hold the team lock when calling this function. */
|
/*! You must hold the team lock when calling this function. */
|
||||||
static void
|
static void
|
||||||
insert_group_into_session(struct process_session *session, struct process_group *group)
|
insert_group_into_session(struct process_session* session,
|
||||||
|
struct process_group* group)
|
||||||
{
|
{
|
||||||
if (group == NULL)
|
if (group == NULL)
|
||||||
return;
|
return;
|
||||||
@@ -657,13 +662,15 @@ static void
|
|||||||
remove_team_from_group(struct team* team)
|
remove_team_from_group(struct team* team)
|
||||||
{
|
{
|
||||||
struct process_group* group = team->group;
|
struct process_group* group = team->group;
|
||||||
struct team *current, *last = NULL;
|
struct team* current;
|
||||||
|
struct team* last = NULL;
|
||||||
|
|
||||||
// the team must be in any team to let this function have any effect
|
// the team must be in any team to let this function have any effect
|
||||||
if (group == NULL)
|
if (group == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (current = group->teams; current != NULL; current = current->group_next) {
|
for (current = group->teams; current != NULL;
|
||||||
|
current = current->group_next) {
|
||||||
if (current == team) {
|
if (current == team) {
|
||||||
if (last == NULL)
|
if (last == NULL)
|
||||||
group->teams = current->group_next;
|
group->teams = current->group_next;
|
||||||
@@ -686,7 +693,8 @@ remove_team_from_group(struct team *team)
|
|||||||
static struct process_group*
|
static struct process_group*
|
||||||
create_process_group(pid_t id)
|
create_process_group(pid_t id)
|
||||||
{
|
{
|
||||||
struct process_group *group = (struct process_group *)malloc(sizeof(struct process_group));
|
struct process_group* group
|
||||||
|
= (struct process_group*)malloc(sizeof(struct process_group));
|
||||||
if (group == NULL)
|
if (group == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -990,26 +998,26 @@ static int32
|
|||||||
team_create_thread_start(void* args)
|
team_create_thread_start(void* args)
|
||||||
{
|
{
|
||||||
status_t err;
|
status_t err;
|
||||||
struct thread *t;
|
struct thread* thread;
|
||||||
struct team* team;
|
struct team* team;
|
||||||
struct team_arg* teamArgs = (struct team_arg*)args;
|
struct team_arg* teamArgs = (struct team_arg*)args;
|
||||||
const char* path;
|
const char* path;
|
||||||
addr_t entry;
|
addr_t entry;
|
||||||
char ustack_name[128];
|
char userStackName[128];
|
||||||
uint32 sizeLeft;
|
uint32 sizeLeft;
|
||||||
char** userArgs;
|
char** userArgs;
|
||||||
char** userEnv;
|
char** userEnv;
|
||||||
struct user_space_program_args* programArgs;
|
struct user_space_program_args* programArgs;
|
||||||
uint32 argCount, envCount, i;
|
uint32 argCount, envCount, i;
|
||||||
|
|
||||||
t = thread_get_current_thread();
|
thread = thread_get_current_thread();
|
||||||
team = t->team;
|
team = thread->team;
|
||||||
cache_node_launched(teamArgs->arg_count, teamArgs->flat_args);
|
cache_node_launched(teamArgs->arg_count, teamArgs->flat_args);
|
||||||
|
|
||||||
TRACE(("team_create_thread_start: entry thread %ld\n", t->id));
|
TRACE(("team_create_thread_start: entry thread %ld\n", thread->id));
|
||||||
|
|
||||||
// get a user thread for the main thread
|
// get a user thread for the main thread
|
||||||
t->user_thread = team_allocate_user_thread(team);
|
thread->user_thread = team_allocate_user_thread(team);
|
||||||
|
|
||||||
// create an initial primary stack area
|
// create an initial primary stack area
|
||||||
|
|
||||||
@@ -1023,37 +1031,39 @@ team_create_thread_start(void *args)
|
|||||||
// | loader
|
// | loader
|
||||||
// flat arguments size | flat process arguments and environment
|
// flat arguments size | flat process arguments and environment
|
||||||
|
|
||||||
// ToDo: ENV_SIZE is a) limited, and b) not used after libroot copied it to the heap
|
// TODO: ENV_SIZE is a) limited, and b) not used after libroot copied it to
|
||||||
// ToDo: we could reserve the whole USER_STACK_REGION upfront...
|
// the heap
|
||||||
|
// TODO: we could reserve the whole USER_STACK_REGION upfront...
|
||||||
|
|
||||||
sizeLeft = PAGE_ALIGN(USER_MAIN_THREAD_STACK_SIZE
|
sizeLeft = PAGE_ALIGN(USER_MAIN_THREAD_STACK_SIZE
|
||||||
+ USER_STACK_GUARD_PAGES * B_PAGE_SIZE + TLS_SIZE
|
+ USER_STACK_GUARD_PAGES * B_PAGE_SIZE + TLS_SIZE
|
||||||
+ sizeof(struct user_space_program_args) + teamArgs->flat_args_size);
|
+ sizeof(struct user_space_program_args) + teamArgs->flat_args_size);
|
||||||
t->user_stack_base = USER_STACK_REGION + USER_STACK_REGION_SIZE - sizeLeft;
|
thread->user_stack_base
|
||||||
t->user_stack_size = USER_MAIN_THREAD_STACK_SIZE
|
= USER_STACK_REGION + USER_STACK_REGION_SIZE - sizeLeft;
|
||||||
|
thread->user_stack_size = USER_MAIN_THREAD_STACK_SIZE
|
||||||
+ USER_STACK_GUARD_PAGES * B_PAGE_SIZE;
|
+ USER_STACK_GUARD_PAGES * B_PAGE_SIZE;
|
||||||
// the exact location at the end of the user stack area
|
// the exact location at the end of the user stack area
|
||||||
|
|
||||||
sprintf(ustack_name, "%s_main_stack", team->name);
|
sprintf(userStackName, "%s_main_stack", team->name);
|
||||||
t->user_stack_area = create_area_etc(team->id, ustack_name,
|
thread->user_stack_area = create_area_etc(team->id, userStackName,
|
||||||
(void **)&t->user_stack_base, B_EXACT_ADDRESS, sizeLeft, B_NO_LOCK,
|
(void**)&thread->user_stack_base, B_EXACT_ADDRESS, sizeLeft, B_NO_LOCK,
|
||||||
B_READ_AREA | B_WRITE_AREA | B_STACK_AREA, 0, 0);
|
B_READ_AREA | B_WRITE_AREA | B_STACK_AREA, 0, 0);
|
||||||
if (t->user_stack_area < 0) {
|
if (thread->user_stack_area < 0) {
|
||||||
dprintf("team_create_thread_start: could not create default user stack "
|
dprintf("team_create_thread_start: could not create default user stack "
|
||||||
"region: %s\n", strerror(t->user_stack_area));
|
"region: %s\n", strerror(thread->user_stack_area));
|
||||||
|
|
||||||
free_team_arg(teamArgs);
|
free_team_arg(teamArgs);
|
||||||
return t->user_stack_area;
|
return thread->user_stack_area;
|
||||||
}
|
}
|
||||||
|
|
||||||
// now that the TLS area is allocated, initialize TLS
|
// now that the TLS area is allocated, initialize TLS
|
||||||
arch_thread_init_tls(t);
|
arch_thread_init_tls(thread);
|
||||||
|
|
||||||
argCount = teamArgs->arg_count;
|
argCount = teamArgs->arg_count;
|
||||||
envCount = teamArgs->env_count;
|
envCount = teamArgs->env_count;
|
||||||
|
|
||||||
programArgs = (struct user_space_program_args *)(t->user_stack_base
|
programArgs = (struct user_space_program_args*)(thread->user_stack_base
|
||||||
+ t->user_stack_size + TLS_SIZE);
|
+ thread->user_stack_size + TLS_SIZE);
|
||||||
|
|
||||||
userArgs = (char**)(programArgs + 1);
|
userArgs = (char**)(programArgs + 1);
|
||||||
userEnv = userArgs + argCount + 1;
|
userEnv = userArgs + argCount + 1;
|
||||||
@@ -1104,8 +1114,10 @@ team_create_thread_start(void *args)
|
|||||||
runtimeLoaderPath.UnlockBuffer();
|
runtimeLoaderPath.UnlockBuffer();
|
||||||
err = runtimeLoaderPath.Append("runtime_loader");
|
err = runtimeLoaderPath.Append("runtime_loader");
|
||||||
|
|
||||||
if (err == B_OK)
|
if (err == B_OK) {
|
||||||
err = elf_load_user_image(runtimeLoaderPath.Path(), team, 0, &entry);
|
err = elf_load_user_image(runtimeLoaderPath.Path(), team, 0,
|
||||||
|
&entry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err < B_OK) {
|
if (err < B_OK) {
|
||||||
@@ -1121,7 +1133,7 @@ team_create_thread_start(void *args)
|
|||||||
team->state = TEAM_STATE_NORMAL;
|
team->state = TEAM_STATE_NORMAL;
|
||||||
|
|
||||||
// jump to the entry point in user space
|
// jump to the entry point in user space
|
||||||
return arch_thread_enter_userspace(t, entry, programArgs, NULL);
|
return arch_thread_enter_userspace(thread, entry, programArgs, NULL);
|
||||||
// only returns in case of error
|
// only returns in case of error
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1219,7 +1231,7 @@ load_image_internal(char**& _flatArgs, size_t flatArgsSize, int32 argCount,
|
|||||||
// create an address space for this team
|
// create an address space for this team
|
||||||
status = vm_create_address_space(team->id, USER_BASE, USER_SIZE, false,
|
status = vm_create_address_space(team->id, USER_BASE, USER_SIZE, false,
|
||||||
&team->address_space);
|
&team->address_space);
|
||||||
if (status < B_OK)
|
if (status != B_OK)
|
||||||
goto err3;
|
goto err3;
|
||||||
|
|
||||||
// cut the path from the main thread name
|
// cut the path from the main thread name
|
||||||
@@ -1247,7 +1259,7 @@ load_image_internal(char**& _flatArgs, size_t flatArgsSize, int32 argCount,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// wait for the loader of the new team to finish its work
|
// wait for the loader of the new team to finish its work
|
||||||
if (flags & B_WAIT_TILL_LOADED) {
|
if ((flags & B_WAIT_TILL_LOADED) != 0) {
|
||||||
struct thread* mainThread;
|
struct thread* mainThread;
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
@@ -1298,7 +1310,8 @@ err1:
|
|||||||
if (parentIOContext != NULL)
|
if (parentIOContext != NULL)
|
||||||
vfs_put_io_context(parentIOContext);
|
vfs_put_io_context(parentIOContext);
|
||||||
|
|
||||||
// remove the team structure from the team hash table and delete the team structure
|
// Remove the team structure from the team hash table and delete the team
|
||||||
|
// structure
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_TEAM_LOCK();
|
GRAB_TEAM_LOCK();
|
||||||
|
|
||||||
@@ -1491,7 +1504,8 @@ static thread_id
|
|||||||
fork_team(void)
|
fork_team(void)
|
||||||
{
|
{
|
||||||
struct thread* parentThread = thread_get_current_thread();
|
struct thread* parentThread = thread_get_current_thread();
|
||||||
struct team *parentTeam = parentThread->team, *team;
|
struct team* parentTeam = parentThread->team;
|
||||||
|
struct team* team;
|
||||||
struct fork_arg* forkArgs;
|
struct fork_arg* forkArgs;
|
||||||
struct area_info info;
|
struct area_info info;
|
||||||
thread_id threadID;
|
thread_id threadID;
|
||||||
@@ -1559,8 +1573,9 @@ fork_team(void)
|
|||||||
goto err3;
|
goto err3;
|
||||||
|
|
||||||
// copy all areas of the team
|
// copy all areas of the team
|
||||||
// ToDo: should be able to handle stack areas differently (ie. don't have them copy-on-write)
|
// TODO: should be able to handle stack areas differently (ie. don't have
|
||||||
// ToDo: all stacks of other threads than the current one could be left out
|
// them copy-on-write)
|
||||||
|
// TODO: all stacks of other threads than the current one could be left out
|
||||||
|
|
||||||
forkArgs->user_thread = NULL;
|
forkArgs->user_thread = NULL;
|
||||||
|
|
||||||
@@ -1652,7 +1667,8 @@ err25:
|
|||||||
err2:
|
err2:
|
||||||
free(forkArgs);
|
free(forkArgs);
|
||||||
err1:
|
err1:
|
||||||
// remove the team structure from the team hash table and delete the team structure
|
// remove the team structure from the team hash table and delete the team
|
||||||
|
// structure
|
||||||
teamLocker.Lock();
|
teamLocker.Lock();
|
||||||
|
|
||||||
remove_team_from_group(team);
|
remove_team_from_group(team);
|
||||||
@@ -2210,7 +2226,8 @@ team_delete_process_group(struct process_group *group)
|
|||||||
// remove_group_from_session() keeps this pointer around
|
// remove_group_from_session() keeps this pointer around
|
||||||
// only if the session can be freed as well
|
// only if the session can be freed as well
|
||||||
if (group->session) {
|
if (group->session) {
|
||||||
TRACE(("team_delete_process_group(): frees session %ld\n", group->session->id));
|
TRACE(("team_delete_process_group(): frees session %ld\n",
|
||||||
|
group->session->id));
|
||||||
free(group->session);
|
free(group->session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2374,14 +2391,16 @@ team_delete_team(struct team *team)
|
|||||||
// cycle through and signal kill on each of the threads
|
// cycle through and signal kill on each of the threads
|
||||||
// ToDo: this can be optimized. There's got to be a better solution.
|
// ToDo: this can be optimized. There's got to be a better solution.
|
||||||
struct thread* temp_thread;
|
struct thread* temp_thread;
|
||||||
char death_sem_name[B_OS_NAME_LENGTH];
|
char deathSemName[B_OS_NAME_LENGTH];
|
||||||
sem_id deathSem;
|
sem_id deathSem;
|
||||||
int32 threadCount;
|
int32 threadCount;
|
||||||
|
|
||||||
sprintf(death_sem_name, "team %ld death sem", teamID);
|
sprintf(deathSemName, "team %ld death sem", teamID);
|
||||||
deathSem = create_sem(0, death_sem_name);
|
deathSem = create_sem(0, deathSemName);
|
||||||
if (deathSem < 0)
|
if (deathSem < 0) {
|
||||||
panic("team_delete_team: cannot init death sem for team %ld\n", teamID);
|
panic("team_delete_team: cannot init death sem for team %ld\n",
|
||||||
|
teamID);
|
||||||
|
}
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_TEAM_LOCK();
|
GRAB_TEAM_LOCK();
|
||||||
@@ -2401,8 +2420,8 @@ team_delete_team(struct team *team)
|
|||||||
|
|
||||||
RELEASE_TEAM_DEBUG_INFO_LOCK(team->debug_info);
|
RELEASE_TEAM_DEBUG_INFO_LOCK(team->debug_info);
|
||||||
|
|
||||||
// we can safely walk the list because of the lock. no new threads can be created
|
// We can safely walk the list because of the lock. no new threads can
|
||||||
// because of the TEAM_STATE_DEATH flag on the team
|
// be created because of the TEAM_STATE_DEATH flag on the team
|
||||||
temp_thread = team->thread_list;
|
temp_thread = team->thread_list;
|
||||||
while (temp_thread) {
|
while (temp_thread) {
|
||||||
struct thread* next = temp_thread->team_next;
|
struct thread* next = temp_thread->team_next;
|
||||||
@@ -3132,7 +3151,8 @@ _user_fork(void)
|
|||||||
|
|
||||||
|
|
||||||
thread_id
|
thread_id
|
||||||
_user_wait_for_child(thread_id child, uint32 flags, int32 *_userReason, status_t *_userReturnCode)
|
_user_wait_for_child(thread_id child, uint32 flags, int32* _userReason,
|
||||||
|
status_t* _userReturnCode)
|
||||||
{
|
{
|
||||||
status_t returnCode;
|
status_t returnCode;
|
||||||
int32 reason;
|
int32 reason;
|
||||||
@@ -3386,7 +3406,8 @@ _user_wait_for_team(team_id id, status_t *_userReturnCode)
|
|||||||
|
|
||||||
status = wait_for_team(id, &returnCode);
|
status = wait_for_team(id, &returnCode);
|
||||||
if (status >= B_OK && _userReturnCode != NULL) {
|
if (status >= B_OK && _userReturnCode != NULL) {
|
||||||
if (user_memcpy(_userReturnCode, &returnCode, sizeof(returnCode)) < B_OK)
|
if (user_memcpy(_userReturnCode, &returnCode, sizeof(returnCode))
|
||||||
|
!= B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -3493,7 +3514,8 @@ _user_get_current_team(void)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_user_get_team_usage_info(team_id team, int32 who, team_usage_info *userInfo, size_t size)
|
_user_get_team_usage_info(team_id team, int32 who, team_usage_info* userInfo,
|
||||||
|
size_t size)
|
||||||
{
|
{
|
||||||
team_usage_info info;
|
team_usage_info info;
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|||||||
Reference in New Issue
Block a user