[haiku-commits] r41310 - in haiku/branches/developer/bonefish/signals: headers/private/kernel src/system/kernel

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 4 May 2011 00:07:04 +0200 (CEST)

Author: bonefish
Date: 2011-05-04 00:07:03 +0200 (Wed, 04 May 2011)
New Revision: 41310
Changeset: https://dev.haiku-os.org/changeset/41310

Modified:
   haiku/branches/developer/bonefish/signals/headers/private/kernel/team.h
   
haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h
   haiku/branches/developer/bonefish/signals/src/system/kernel/signal.cpp
   haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp
Log:
* Renamed process_group and process_session to ProcessGroup and ProcessSession
  respectively and C++-ified the structs a bit. Also added locking, though it
  is not used yet.
* Changed sGroupHash from hash_table to BOpenHashTable.


Modified: 
haiku/branches/developer/bonefish/signals/headers/private/kernel/team.h
===================================================================
--- haiku/branches/developer/bonefish/signals/headers/private/kernel/team.h     
2011-05-03 22:01:09 UTC (rev 41309)
+++ haiku/branches/developer/bonefish/signals/headers/private/kernel/team.h     
2011-05-03 22:07:03 UTC (rev 41310)
@@ -25,9 +25,8 @@
 void team_remove_team(Team *team);
 port_id team_shutdown_team(Team *team, cpu_status& state);
 void team_delete_team(Team *team, port_id debuggerPort);
-struct process_group *team_get_process_group_locked(
-                       struct process_session *session, pid_t id);
-void team_delete_process_group(struct process_group *group);
+struct ProcessGroup *team_get_process_group_locked(ProcessSession* session,
+                       pid_t id);
 Team *team_get_kernel_team(void);
 team_id team_get_kernel_team_id(void);
 team_id team_get_current_team_id(void);

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-03 22:01:09 UTC (rev 41309)
+++ 
haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h 
    2011-05-03 22:07:03 UTC (rev 41310)
@@ -14,6 +14,7 @@
 
 #include <arch/thread_types.h>
 #include <condition_variable.h>
+#include <heap.h>
 #include <lock.h>
 #include <signal.h>
 #include <smp.h>
@@ -83,23 +84,6 @@
        uint16                          signal;
 };
 
-struct process_session {
-       pid_t                           id;
-       int32                           group_count;
-       int32                           controlling_tty;        // index of the 
controlling tty,
-                                                                               
        // -1 if none
-       pid_t                           foreground_group;
-};
-
-struct process_group {
-       struct process_group *next;             // next in hash
-       struct process_session *session;
-       pid_t                           id;
-       int32                           refs;
-       BKernel::Team           *teams;
-       bool                            orphaned;
-};
-
 struct team_loading_info {
        Thread*                         thread; // the waiting thread
        status_t                        result;         // the result of the 
loading
@@ -243,7 +227,7 @@
        Team                    *group_next;
        pid_t                   group_id;
        pid_t                   session_id;
-       struct process_group *group;
+       struct ProcessGroup *group;
        int                             num_threads;    // number of threads in 
this team
        int                             state;                  // current team 
state, see above
        int32                   flags;
@@ -427,12 +411,57 @@
        struct arch_thread arch_info;
 };
 
+
+struct ProcessSession {
+       pid_t                           id;
+       int32                           group_count;
+       int32                           controlling_tty;        // index of the 
controlling tty,
+                                                                               
        // -1 if none
+       pid_t                           foreground_group;
+
+public:
+                                                               
ProcessSession(pid_t id);
+                                                               
~ProcessSession();
+
+                       bool                            Lock()
+                                                                       { 
mutex_lock(&fLock); return true; }
+                       void                            Unlock()
+                                                                       { 
mutex_unlock(&fLock); }
+
+private:
+                       mutex                           fLock;
+};
+
+
+struct ProcessGroup : DeferredDeletable {
+       struct ProcessGroup *next;              // next in hash
+       struct ProcessSession *session;
+       pid_t                           id;
+       int32                           refs;
+       BKernel::Team           *teams;
+       bool                            orphaned;
+
+public:
+                                                               
ProcessGroup(pid_t id);
+                                                               ~ProcessGroup();
+
+                       bool                            Lock()
+                                                                       { 
mutex_lock(&fLock); return true; }
+                       void                            Unlock()
+                                                                       { 
mutex_unlock(&fLock); }
+
+private:
+                       mutex                           fLock;
+};
+
 }      // namespace BKernel
 
 using BKernel::Team;
 using BKernel::TeamListEntry;
 using BKernel::TeamListIterator;
 using BKernel::Thread;
+using BKernel::ProcessSession;
+using BKernel::ProcessGroup;
 
 
 struct thread_queue {

Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/signal.cpp
===================================================================
--- haiku/branches/developer/bonefish/signals/src/system/kernel/signal.cpp      
2011-05-03 22:01:09 UTC (rev 41309)
+++ haiku/branches/developer/bonefish/signals/src/system/kernel/signal.cpp      
2011-05-03 22:07:03 UTC (rev 41310)
@@ -633,7 +633,7 @@
                // send a signal to the specified process group
                // (the absolute value of the id)
 
-               struct process_group *group;
+               ProcessGroup *group;
 
                // TODO: handle -1 correctly
                if (id == 0 || id == -1) {

Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp
===================================================================
--- haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp        
2011-05-03 22:01:09 UTC (rev 41309)
+++ haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp        
2011-05-03 22:07:03 UTC (rev 41310)
@@ -52,7 +52,6 @@
 #include <vm/vm.h>
 #include <vm/VMAddressSpace.h>
 #include <util/AutoLock.h>
-#include <util/khash.h>
 
 //#define TRACE_TEAM
 #ifdef TRACE_TEAM
@@ -258,6 +257,37 @@
        TeamList                fList;
 };
 
+
+// #pragma mark - ProcessGroupHashDefinition
+
+
+struct ProcessGroupHashDefinition {
+       typedef pid_t                   KeyType;
+       typedef ProcessGroup    ValueType;
+
+       size_t HashKey(pid_t key) const
+       {
+               return key;
+       }
+
+       size_t Hash(ProcessGroup* value) const
+       {
+               return HashKey(value->id);
+       }
+
+       bool Compare(pid_t key, ProcessGroup* value) const
+       {
+               return value->id == key;
+       }
+
+       ProcessGroup*& GetLink(ProcessGroup* value) const
+       {
+               return value->next;
+       }
+};
+
+typedef BOpenHashTable<ProcessGroupHashDefinition> ProcessGroupHashTable;
+
 }      // unnamed namespace
 
 
@@ -265,7 +295,7 @@
 
 
 static TeamTable sTeamHash;
-static hash_table* sGroupHash = NULL;
+static ProcessGroupHashTable sGroupHash;
 static Team* sKernelTeam = NULL;
 
 // some arbitrarily chosen limits -- should probably depend on the available
@@ -704,6 +734,61 @@
 }
 
 
+//     #pragma mark - ProcessGroup
+
+
+ProcessGroup::ProcessGroup(pid_t id)
+       :
+       session(NULL),
+       id(id),
+       refs(0),
+       teams(NULL),
+       orphaned(true)
+{
+       char lockName[32];
+       snprintf(lockName, sizeof(lockName), "Group:%" B_PRId32, id);
+       mutex_init_etc(&fLock, lockName, MUTEX_FLAG_CLONE_NAME);
+}
+
+
+ProcessGroup::~ProcessGroup()
+{
+       TRACE(("ProcessGroup::~ProcessGroup(): id = %ld\n", group->id));
+
+       // remove_group_from_session() keeps this pointer around
+       // only if the session can be freed as well
+       if (session != NULL) {
+               TRACE(("ProcessGroup::~ProcessGroup(): frees session %ld\n",
+                       session->id));
+               delete session;
+       }
+
+       mutex_destroy(&fLock);
+}
+
+
+//     #pragma mark - ProcessSession
+
+
+ProcessSession::ProcessSession(pid_t id)
+       :
+       id(id),
+       group_count(0),
+       controlling_tty(-1),
+       foreground_group(-1)
+{
+       char lockName[32];
+       snprintf(lockName, sizeof(lockName), "Session:%" B_PRId32, id);
+       mutex_init_etc(&fLock, lockName, MUTEX_FLAG_CLONE_NAME);
+}
+
+
+ProcessSession::~ProcessSession()
+{
+       mutex_destroy(&fLock);
+}
+
+
 //     #pragma mark - Private functions
 
 
@@ -791,32 +876,6 @@
 }
 
 
-static int
-process_group_compare(void* _group, const void* _key)
-{
-       struct process_group* group = (struct process_group*)_group;
-       const struct team_key* key = (const struct team_key*)_key;
-
-       if (group->id == key->id)
-               return 0;
-
-       return 1;
-}
-
-
-static uint32
-process_group_hash(void* _group, const void* _key, uint32 range)
-{
-       struct process_group* group = (struct process_group*)_group;
-       const struct team_key* key = (const struct team_key*)_key;
-
-       if (group != NULL)
-               return group->id % range;
-
-       return (uint32)key->id % range;
-}
-
-
 static void
 insert_team_into_parent(Team* parent, Team* team)
 {
@@ -890,38 +949,20 @@
 }
 
 
-static void
-deferred_delete_process_group(struct process_group* group)
-{
-       if (group == NULL)
-               return;
-
-       // remove_group_from_session() keeps this pointer around
-       // only if the session can be freed as well
-       if (group->session) {
-               TRACE(("deferred_delete_process_group(): frees session %ld\n",
-                       group->session->id));
-               deferred_free(group->session);
-       }
-
-       deferred_free(group);
-}
-
-
 /*!    Removes a group from a session, and puts the session object
        back into the session cache, if it's not used anymore.
        You must hold the team lock when calling this function.
 */
 static void
-remove_group_from_session(struct process_group* group)
+remove_group_from_session(ProcessGroup* group)
 {
-       struct process_session* session = group->session;
+       ProcessSession* session = group->session;
 
        // the group must be in any session to let this function have any effect
        if (session == NULL)
                return;
 
-       hash_remove(sGroupHash, group);
+       sGroupHash.RemoveUnchecked(group);
 
        // we cannot free the resource here, so we're keeping the group link
        // around - this way it'll be freed by free_process_group()
@@ -935,7 +976,7 @@
 static void
 acquire_process_group_ref(pid_t groupID)
 {
-       process_group* group = team_get_process_group_locked(NULL, groupID);
+       ProcessGroup* group = team_get_process_group_locked(NULL, groupID);
        if (group == NULL) {
                panic("acquire_process_group_ref(): unknown group ID: %ld", 
groupID);
                return;
@@ -950,7 +991,7 @@
 static void
 release_process_group_ref(pid_t groupID)
 {
-       process_group* group = team_get_process_group_locked(NULL, groupID);
+       ProcessGroup* group = team_get_process_group_locked(NULL, groupID);
        if (group == NULL) {
                panic("release_process_group_ref(): unknown group ID: %ld", 
groupID);
                return;
@@ -967,27 +1008,26 @@
        // group is no longer used
 
        remove_group_from_session(group);
-       deferred_delete_process_group(group);
+       deferred_delete(group);
 }
 
 
 /*!    You must hold the team lock when calling this function. */
 static void
-insert_group_into_session(struct process_session* session,
-       struct process_group* group)
+insert_group_into_session(ProcessSession* session, ProcessGroup* group)
 {
        if (group == NULL)
                return;
 
        group->session = session;
-       hash_insert(sGroupHash, group);
+       sGroupHash.InsertUnchecked(group);
        session->group_count++;
 }
 
 
 /*!    You must hold the team lock when calling this function. */
 static void
-insert_team_into_group(struct process_group* group, Team* team)
+insert_team_into_group(ProcessGroup* group, Team* team)
 {
        team->group = group;
        team->group_id = group->id;
@@ -1006,7 +1046,7 @@
 static void
 remove_team_from_group(Team* team)
 {
-       struct process_group* group = team->group;
+       ProcessGroup* group = team->group;
        Team* current;
        Team* last = NULL;
 
@@ -1035,40 +1075,6 @@
 }
 
 
-static struct process_group*
-create_process_group(pid_t id)
-{
-       struct process_group* group
-               = (struct process_group*)malloc(sizeof(struct process_group));
-       if (group == NULL)
-               return NULL;
-
-       group->id = id;
-       group->refs = 0;
-       group->session = NULL;
-       group->teams = NULL;
-       group->orphaned = true;
-       return group;
-}
-
-
-static struct process_session*
-create_process_session(pid_t id)
-{
-       struct process_session* session
-               = (struct process_session*)malloc(sizeof(struct 
process_session));
-       if (session == NULL)
-               return NULL;
-
-       session->id = id;
-       session->group_count = 0;
-       session->controlling_tty = -1;
-       session->foreground_group = -1;
-
-       return session;
-}
-
-
 static status_t
 create_team_user_data(Team* team)
 {
@@ -1913,7 +1919,7 @@
 {
        Team* team;
 
-       struct process_group* group = team_get_process_group_locked(
+       ProcessGroup* group = team_get_process_group_locked(
                parent->group->session, groupID);
        if (group == NULL)
                return false;
@@ -2209,11 +2215,11 @@
 }
 
 
-/*!    Updates the \c orphaned field of a process_group and returns its new 
value.
+/*!    Updates the \c orphaned field of a ProcessGroup and returns its new 
value.
        Interrupts must be disabled and team lock be held.
 */
 static bool
-update_orphaned_process_group(process_group* group, pid_t dyingProcess)
+update_orphaned_process_group(ProcessGroup* group, pid_t dyingProcess)
 {
        // Orphaned Process Group: "A process group in which the parent of every
        // member is either itself a member of the group or is not a member of 
the
@@ -2245,7 +2251,7 @@
        Interrupts must be disabled and team lock be held.
 */
 static bool
-process_group_has_stopped_processes(process_group* group)
+process_group_has_stopped_processes(ProcessGroup* group)
 {
        SpinLocker _(gThreadSpinlock);
 
@@ -2267,24 +2273,25 @@
 status_t
 team_init(kernel_args* args)
 {
-       struct process_session* session;
-       struct process_group* group;
+       ProcessSession* session;
+       ProcessGroup* group;
 
        // create the team hash table
        new(&sTeamHash) TeamTable;
        if (sTeamHash.Init() != B_OK)
                panic("Failed to init team hash table!");
 
-       sGroupHash = hash_init(16, offsetof(struct process_group, next),
-               &process_group_compare, &process_group_hash);
+       new(&sGroupHash) ProcessGroupHashTable;
+       if (sGroupHash.Init() != B_OK)
+               panic("Failed to init process group hash table!");
 
        // create initial session and process groups
 
-       session = create_process_session(1);
+       session = new(std::nothrow) ProcessSession(1);
        if (session == NULL)
                panic("Could not create initial session.\n");
 
-       group = create_process_group(1);
+       group = new(std::nothrow) ProcessGroup(1);
        if (group == NULL)
                panic("Could not create initial process group.\n");
 
@@ -2422,14 +2429,10 @@
 /*! This searches the session of the team for the specified group ID.
        You must hold the team lock when you call this function.
 */
-struct process_group*
-team_get_process_group_locked(struct process_session* session, pid_t id)
+ProcessGroup*
+team_get_process_group_locked(ProcessSession* session, pid_t id)
 {
-       struct process_group* group;
-       struct team_key key;
-       key.id = id;
-
-       group = (struct process_group*)hash_lookup(sGroupHash, &key);
+       ProcessGroup* group = sGroupHash.Lookup(id);
        if (group != NULL && (session == NULL || session == group->session))
                return group;
 
@@ -2438,26 +2441,6 @@
 
 
 void
-team_delete_process_group(struct process_group* group)
-{
-       if (group == NULL)
-               return;
-
-       TRACE(("team_delete_process_group(id = %ld)\n", group->id));
-
-       // remove_group_from_session() keeps this pointer around
-       // only if the session can be freed as well
-       if (group->session) {
-               TRACE(("team_delete_process_group(): frees session %ld\n",
-                       group->session->id));
-               free(group->session);
-       }
-
-       free(group);
-}
-
-
-void
 team_set_controlling_tty(int32 ttyIndex)
 {
        Team* team = thread_get_current_thread()->team;
@@ -2488,14 +2471,14 @@
 
        InterruptsSpinLocker locker(gTeamSpinlock);
 
-       process_session* session = team->group->session;
+       ProcessSession* session = team->group->session;
 
        // must be the controlling tty of the calling process
        if (session->controlling_tty != ttyIndex)
                return ENOTTY;
 
        // check process group -- must belong to our session
-       process_group* group = team_get_process_group_locked(session,
+       ProcessGroup* group = team_get_process_group_locked(session,
                processGroupID);
        if (group == NULL)
                return B_BAD_VALUE;
@@ -2549,7 +2532,7 @@
        // terminal), there's a bit of signalling we have to do.
        if (team->session_id == team->id
                && team->group->session->controlling_tty >= 0) {
-               process_session* session = team->group->session;
+               ProcessSession* session = team->group->session;
 
                session->controlling_tty = -1;
 
@@ -2563,7 +2546,7 @@
                // stopped processes
                Team* child = team->children;
                while (child != NULL) {
-                       process_group* childGroup = child->group;
+                       ProcessGroup* childGroup = child->group;
                        if (!childGroup->orphaned
                                && update_orphaned_process_group(childGroup, 
team->id)
                                && 
process_group_has_stopped_processes(childGroup)) {
@@ -2579,7 +2562,7 @@
                // update "orphaned" flags of all children's process groups
                Team* child = team->children;
                while (child != NULL) {
-                       process_group* childGroup = child->group;
+                       ProcessGroup* childGroup = child->group;
                        if (!childGroup->orphaned)
                                update_orphaned_process_group(childGroup, 
team->id);
 
@@ -3613,10 +3596,10 @@
                        return EACCES;
        }
 
-       struct process_group* group = NULL;
+       ProcessGroup* group = NULL;
        if (groupID == processID) {
                // A new process group might be needed.
-               group = create_process_group(groupID);
+               group = new(std::nothrow) ProcessGroup(groupID);
                if (group == NULL)
                        return B_NO_MEMORY;
 
@@ -3626,7 +3609,7 @@
        }
 
        status_t status = B_OK;
-       struct process_group* freeGroup = NULL;
+       ProcessGroup* freeGroup = NULL;
 
        InterruptsSpinLocker locker(gTeamSpinlock);
 
@@ -3644,7 +3627,7 @@
                        freeGroup = group;
                } else {
                        // Check if a process group with the requested ID 
already exists.
-                       struct process_group* targetGroup
+                       ProcessGroup* targetGroup
                                = 
team_get_process_group_locked(team->group->session, groupID);
                        if (targetGroup != NULL) {
                                // In case of processID == groupID we have to 
free the
@@ -3659,7 +3642,7 @@
 
                        if (targetGroup != NULL) {
                                // we got a group, let's move the team there
-                               process_group* oldGroup = team->group;
+                               ProcessGroup* oldGroup = team->group;
 
                                remove_team_from_group(team);
                                insert_team_into_group(targetGroup, team);
@@ -3702,10 +3685,10 @@
 
        if (status != B_OK) {
                // in case of error, the group hasn't been added into the hash
-               team_delete_process_group(group);
+               delete group;
        }
 
-       team_delete_process_group(freeGroup);
+       delete freeGroup;
 
        return status == B_OK ? groupID : status;
 }
@@ -3715,8 +3698,8 @@
 _user_setsid(void)
 {
        Team* team = thread_get_current_thread()->team;
-       struct process_session* session;
-       struct process_group* group;
+       ProcessSession* session;
+       ProcessGroup* group;
        cpu_status state;
        bool failed = false;
 
@@ -3724,13 +3707,13 @@
        if (is_process_group_leader(team))
                return B_NOT_ALLOWED;
 
-       group = create_process_group(team->id);
+       group = new(std::nothrow) ProcessGroup(team->id);
        if (group == NULL)
                return B_NO_MEMORY;
 
-       session = create_process_session(group->id);
+       session = new(std::nothrow) ProcessSession(group->id);
        if (session == NULL) {
-               team_delete_process_group(group);
+               delete group;
                return B_NO_MEMORY;
        }
 
@@ -3750,8 +3733,8 @@
        restore_interrupts(state);
 
        if (failed) {
-               team_delete_process_group(group);
-               free(session);
+               delete group;
+               delete session;
                return B_NOT_ALLOWED;
        }
 


Other related posts:

  • » [haiku-commits] r41310 - in haiku/branches/developer/bonefish/signals: headers/private/kernel src/system/kernel - ingo_weinhold