Author: bonefish Date: 2011-05-29 01:47:47 +0200 (Sun, 29 May 2011) New Revision: 41800 Changeset: https://dev.haiku-os.org/changeset/41800 Modified: haiku/branches/developer/bonefish/signals/headers/private/kernel/thread.h haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h haiku/branches/developer/bonefish/signals/src/system/kernel/debug/user_debugger.cpp haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp Log: * Added a Thread::Create() to create and init the object. * Changed ThreadCreationAttributes::thread field from thread_id to Thread*. If non-NULL, thread_create_thread() uses the given Thread object, otherwise it creates a new one. * load_image_internal() and fork_team() create a Thread object for the main thread before the Team object, now. Therefore we already have the ID for the main thread and can pass it to Team::Create() and the Team constructor no longer needs to allocate a thread ID. * spawn_kernel_thread_etc(): Removed no longer needed "threadID" parameter. Modified: haiku/branches/developer/bonefish/signals/headers/private/kernel/thread.h =================================================================== --- haiku/branches/developer/bonefish/signals/headers/private/kernel/thread.h 2011-05-28 22:46:12 UTC (rev 41799) +++ haiku/branches/developer/bonefish/signals/headers/private/kernel/thread.h 2011-05-28 23:47:47 UTC (rev 41800) @@ -37,7 +37,7 @@ struct ThreadCreationAttributes : thread_creation_attributes { // when calling from kernel only team_id team; - thread_id thread; + Thread* thread; sigset_t signal_mask; public: @@ -46,7 +46,7 @@ ThreadCreationAttributes( thread_func function, const char* name, int32 priority, void* arg, - team_id team = -1, thread_id threadID = -1); + team_id team = -1, Thread* thread = NULL); status_t InitFromUserAttributes( thread_creation_attributes* userAttributes, @@ -110,7 +110,7 @@ bool kernel); thread_id spawn_kernel_thread_etc(thread_func, const char *name, int32 priority, - void *args, team_id team, thread_id threadID); + void *args, team_id team); status_t wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout, status_t *_returnCode); Modified: haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h =================================================================== --- haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h 2011-05-28 22:46:12 UTC (rev 41799) +++ haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h 2011-05-28 23:47:47 UTC (rev 41800) @@ -293,7 +293,8 @@ public: ~Team(); - static Team* Create(const char* name, bool kernel); + static Team* Create(team_id id, const char* name, + bool kernel); static Team* Get(team_id id); static Team* GetAndLock(team_id id); @@ -362,7 +363,7 @@ void UserDefinedTimersRemoved(int32 count); private: - Team(bool kernel); + Team(team_id id, bool kernel); private: mutex fLock; @@ -504,6 +505,8 @@ struct cpu_ent *cpu); ~Thread(); + static status_t Create(const char* name, Thread*& _thread); + static Thread* Get(thread_id id); static Thread* GetAndLock(thread_id id); static Thread* GetDebug(thread_id id); Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/debug/user_debugger.cpp =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/kernel/debug/user_debugger.cpp 2011-05-28 22:46:12 UTC (rev 41799) +++ haiku/branches/developer/bonefish/signals/src/system/kernel/debug/user_debugger.cpp 2011-05-28 23:47:47 UTC (rev 41800) @@ -2672,7 +2672,7 @@ if (error == B_OK) { snprintf(nameBuffer, sizeof(nameBuffer), "team %ld debug task", teamID); nubThread = spawn_kernel_thread_etc(debug_nub_thread, nameBuffer, - B_NORMAL_PRIORITY, NULL, teamID, -1); + B_NORMAL_PRIORITY, NULL, teamID); if (nubThread < 0) error = nubThread; } Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp 2011-05-28 22:46:12 UTC (rev 41799) +++ haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp 2011-05-28 23:47:47 UTC (rev 41800) @@ -426,10 +426,10 @@ // #pragma mark - Team -Team::Team(bool kernel) +Team::Team(team_id id, bool kernel) { // allocate an ID - id = kernel ? 1 : allocate_thread_id(); + this->id = id; visible = true; serial_number = -1; @@ -543,10 +543,10 @@ /*static*/ Team* -Team::Create(const char* name, bool kernel) +Team::Create(team_id id, const char* name, bool kernel) { // create the team object - Team* team = new(std::nothrow) Team(kernel); + Team* team = new(std::nothrow) Team(id, kernel); if (team == NULL) return NULL; ObjectDeleter<Team> teamDeleter(team); @@ -1567,7 +1567,6 @@ port_id errorPort, uint32 errorToken) { char** flatArgs = _flatArgs; - const char* threadName; thread_id thread; status_t status; struct team_arg* teamArgs; @@ -1583,7 +1582,22 @@ TRACE(("load_image_internal: name '%s', args = %p, argCount = %ld\n", path, flatArgs, argCount)); - Team* team = Team::Create(path, false); + // cut the path from the main thread name + const char* threadName = strrchr(path, '/'); + if (threadName != NULL) + threadName++; + else + threadName = path; + + // create the main thread object + Thread* mainThread; + status = Thread::Create(threadName, mainThread); + if (status != B_OK) + return status; + BReference<Thread> mainThreadReference(mainThread); + + // create team object + Team* team = Team::Create(mainThread->id, path, false); if (team == NULL) return B_NO_MEMORY; BReference<Team> teamReference(team, true); @@ -1658,13 +1672,6 @@ if (status != B_OK) goto err3; - // cut the path from the main thread name - threadName = strrchr(path, '/'); - if (threadName != NULL) - threadName++; - else - threadName = path; - // create the user data area status = create_team_user_data(team); if (status != B_OK) @@ -1675,9 +1682,11 @@ teamID = team->id; // Create a kernel thread, but under the context of the new team - // The new thread will take over ownership of teamArgs - thread = spawn_kernel_thread_etc(team_create_thread_start, threadName, - B_NORMAL_PRIORITY, teamArgs, teamID, teamID); + // The new thread will take over ownership of teamArgs. + thread = thread_create_thread( + ThreadCreationAttributes(team_create_thread_start, threadName, + B_NORMAL_PRIORITY, teamArgs, teamID, mainThread), + true); if (thread < 0) { status = thread; goto err5; @@ -1689,9 +1698,6 @@ // wait for the loader of the new team to finish its work if ((flags & B_WAIT_TILL_LOADED) != 0) { - Thread* mainThread = Thread::Get(thread); - BReference<Thread> mainThreadReference(mainThread, true); - InterruptsSpinLocker schedulerLocker(gSchedulerLock); // resume the team's main thread @@ -1943,7 +1949,15 @@ // TODO: this is very similar to load_image_internal() - maybe we can do // something about it :) - team = Team::Create(NULL, false); + // create the main thread object + Thread* mainThread; + status = Thread::Create(parentThread->name, mainThread); + if (status != B_OK) + return status; + BReference<Thread> mainThreadReference(mainThread); + + // create the team object + team = Team::Create(mainThread->id, NULL, false); if (team == NULL) return B_NO_MEMORY; @@ -2070,9 +2084,10 @@ } // create a kernel thread under the context of the new team - threadID = spawn_kernel_thread_etc(fork_team_thread_start, - parentThread->name, parentThread->priority, forkArgs, - team->id, team->id); + threadID = thread_create_thread( + ThreadCreationAttributes(fork_team_thread_start, parentThread->name, + parentThread->priority, forkArgs, team->id, mainThread), + true); if (threadID < 0) { status = threadID; goto err5; @@ -2584,7 +2599,7 @@ group->Publish(session); // create the kernel team - sKernelTeam = Team::Create("kernel_team", true); + sKernelTeam = Team::Create(1, "kernel_team", true); if (sKernelTeam == NULL) panic("could not create kernel team!\n"); sKernelTeam->SetArgs(sKernelTeam->Name()); Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp 2011-05-28 22:46:12 UTC (rev 41799) +++ haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp 2011-05-28 23:47:47 UTC (rev 41800) @@ -249,6 +249,24 @@ } +/*static*/ status_t +Thread::Create(const char* name, Thread*& _thread) +{ + Thread* thread = new Thread(name, -1, NULL); + if (thread == NULL) + return B_NO_MEMORY; + + status_t error = thread->Init(false); + if (error != B_OK) { + delete thread; + return error; + } + + _thread = thread; + return B_OK; +} + + /*static*/ Thread* Thread::Get(thread_id id) { @@ -473,7 +491,7 @@ ThreadCreationAttributes::ThreadCreationAttributes(thread_func function, const char* name, int32 priority, void* arg, team_id team, - thread_id threadID) + Thread* thread) { this->entry = (thread_entry_func)function; this->name = name; @@ -484,7 +502,7 @@ this->stack_size = 0; this->pthread = NULL; this->team = team >= 0 ? team : team_get_kernel_team()->id; - this->thread = threadID; + this->thread = thread; this->signal_mask = 0; } @@ -526,7 +544,7 @@ // kernel only attributes (not in thread_creation_attributes): Thread* currentThread = thread_get_current_thread(); team = currentThread->team->id; - thread = -1; + thread = NULL; signal_mask = currentThread->sig_block_mask; // inherit the current thread's signal mask @@ -658,22 +676,23 @@ failure. */ thread_id -thread_create_thread(const ThreadCreationAttributes& attributes, - bool kernel) +thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel) { + status_t status = B_OK; char stack_name[B_OS_NAME_LENGTH]; - status_t status; - TRACE(("create_thread(%s, id = %ld, %s)\n", attributes.name, + TRACE(("thread_create_thread(%s, id = %ld, %s)\n", attributes.name, attributes.thread, kernel ? "kernel" : "user")); - Thread* thread = new Thread(attributes.name, attributes.thread, NULL); - if (thread == NULL) - return B_NO_MEMORY; - status = thread->Init(false); - if (status != B_OK) { - delete thread; - return status; + // If a thread object is given, acquire a reference to it, otherwise create + // a new thread object with the given attributes. + Thread* thread = attributes.thread; + if (thread != NULL) { + thread->AcquireReference(); + } else { + status = Thread::Create(attributes.name, thread); + if (status != B_OK) + return status; } thread->priority = attributes.priority == -1 @@ -2188,16 +2207,13 @@ /*! Kernel private thread creation function. - - \param threadID The ID to be assigned to the new thread. If - \code < 0 \endcode a fresh one is allocated. */ thread_id spawn_kernel_thread_etc(thread_func function, const char *name, int32 priority, - void *arg, team_id team, thread_id threadID) + void *arg, team_id team) { return thread_create_thread( - ThreadCreationAttributes(function, name, priority, arg, team, threadID), + ThreadCreationAttributes(function, name, priority, arg, team), true); }