[haiku-commits] r33771 - in haiku/trunk: headers/private/kernel src/system/kernel

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 26 Oct 2009 14:34:43 +0100 (CET)

Author: axeld
Date: 2009-10-26 14:34:43 +0100 (Mon, 26 Oct 2009)
New Revision: 33771
Changeset: http://dev.haiku-os.org/changeset/33771/haiku

Modified:
   haiku/trunk/headers/private/kernel/port.h
   haiku/trunk/headers/private/kernel/thread_types.h
   haiku/trunk/src/system/kernel/port.cpp
   haiku/trunk/src/system/kernel/team.cpp
Log:
* delete_owned_ports() no longer scans the whole port array for ports belonging
  to the owning team.
* Instead, the team now maintains a list containing the ports it owns.


Modified: haiku/trunk/headers/private/kernel/port.h
===================================================================
--- haiku/trunk/headers/private/kernel/port.h   2009-10-26 13:29:29 UTC (rev 
33770)
+++ haiku/trunk/headers/private/kernel/port.h   2009-10-26 13:34:43 UTC (rev 
33771)
@@ -32,7 +32,7 @@
 #endif
 
 status_t port_init(struct kernel_args *args);
-int delete_owned_ports(team_id owner);
+void delete_owned_ports(struct team* team);
 int32 port_max_ports(void);
 int32 port_used_ports(void);
 
@@ -41,12 +41,9 @@
 
 // currently private API
 status_t writev_port_etc(port_id id, int32 msgCode, const iovec *msgVecs,
-                       size_t vecCount, size_t bufferSize, uint32 flags,
-                       bigtime_t timeout);
+                               size_t vecCount, size_t bufferSize, uint32 
flags,
+                               bigtime_t timeout);
 
-// temp: test
-void port_test(void);
-
 // user syscalls
 port_id                _user_create_port(int32 queueLength, const char *name);
 status_t       _user_close_port(port_id id);

Modified: haiku/trunk/headers/private/kernel/thread_types.h
===================================================================
--- haiku/trunk/headers/private/kernel/thread_types.h   2009-10-26 13:29:29 UTC 
(rev 33770)
+++ haiku/trunk/headers/private/kernel/thread_types.h   2009-10-26 13:34:43 UTC 
(rev 33771)
@@ -194,6 +194,7 @@
        struct list             image_list;
        struct list             watcher_list;
        struct list             sem_list;
+       struct list             port_list;
        struct arch_team arch_info;
 
        addr_t                  user_data;

Modified: haiku/trunk/src/system/kernel/port.cpp
===================================================================
--- haiku/trunk/src/system/kernel/port.cpp      2009-10-26 13:29:29 UTC (rev 
33770)
+++ haiku/trunk/src/system/kernel/port.cpp      2009-10-26 13:34:43 UTC (rev 
33771)
@@ -52,6 +52,7 @@
 typedef DoublyLinkedList<port_message> MessageList;
 
 struct port_entry {
+       struct list_link        team_link;
        port_id                         id;
        team_id                         owner;
        int32                           capacity;
@@ -563,38 +564,52 @@
 }
 
 
-//     #pragma mark - private kernel API
+static void
+uninit_port_locked(struct port_entry& port)
+{
+       int32 id = port.id;
 
+       // mark port as invalid
+       port.id = -1;
+       free((char*)port.lock.name);
+       port.lock.name = NULL;
 
-/*! This function cycles through the ports table, deleting all
-       the ports that are owned by the passed team_id
-*/
-int
-delete_owned_ports(team_id owner)
-{
-       // TODO: investigate maintaining a list of ports in the team
-       //      to make this simpler and more efficient.
+       while (port_message* message = port.messages.RemoveHead()) {
+               put_port_message(message);
+       }
 
-       TRACE(("delete_owned_ports(owner = %ld)\n", owner));
+       notify_port_select_events(id % sMaxPorts, B_EVENT_INVALID);
+       port.select_infos = NULL;
 
-       MutexLocker locker(sPortsLock);
+       // Release the threads that were blocking on this port.
+       // read_port() will see the B_BAD_PORT_ID return value, and act 
accordingly
+       port.read_condition.NotifyAll(B_BAD_PORT_ID);
+       port.write_condition.NotifyAll(B_BAD_PORT_ID);
+       sNotificationService.Notify(PORT_REMOVED, id);
+}
 
-       int32 count = 0;
 
-       for (int32 i = 0; i < sMaxPorts; i++) {
-               if (sPorts[i].id != -1 && sPorts[i].owner == owner) {
-                       port_id id = sPorts[i].id;
+//     #pragma mark - private kernel API
 
-                       locker.Unlock();
 
-                       delete_port(id);
-                       count++;
+/*! This function delets all the ports that are owned by the passed team.
+*/
+void
+delete_owned_ports(struct team* team)
+{
+       TRACE(("delete_owned_ports(owner = %ld)\n", team->id));
 
-                       locker.Lock();
-               }
+       struct list queue;
+
+       {
+               InterruptsSpinLocker locker(gTeamSpinlock);
+               list_move_to_list(&team->port_list, &queue);
        }
 
-       return count;
+       while (port_entry* port = (port_entry*)list_remove_head_item(&queue)) {
+               MutexLocker locker(port->lock);
+               uninit_port_locked(*port);
+       }
 }
 
 
@@ -693,6 +708,10 @@
        if (queueLength < 1 || queueLength > MAX_QUEUE_LENGTH)
                return B_BAD_VALUE;
 
+       struct team* team = thread_get_current_thread()->team;
+       if (team == NULL)
+               return B_BAD_TEAM_ID;
+
        MutexLocker locker(sPortsLock);
 
        // check early on if there are any free port slots to use
@@ -730,6 +749,11 @@
                        sPorts[i].total_count = 0;
                        sPorts[i].select_infos = NULL;
 
+                       {
+                               InterruptsSpinLocker teamLocker(gTeamSpinlock);
+                               list_add_item(&team->port_list, 
&sPorts[i].team_link);
+                       }
+
                        port_id id = sPorts[i].id;
 
                        T(Create(sPorts[i]));
@@ -800,24 +824,13 @@
 
        T(Delete(sPorts[slot]));
 
-       // mark port as invalid
-       sPorts[slot].id = -1;
-       free((char*)sPorts[slot].lock.name);
-       sPorts[slot].lock.name = NULL;
-
-       while (port_message* message = sPorts[slot].messages.RemoveHead()) {
-               put_port_message(message);
+       {
+               InterruptsSpinLocker teamLocker(gTeamSpinlock);
+               list_remove_link(&sPorts[slot].team_link);
        }
 
-       notify_port_select_events(slot, B_EVENT_INVALID);
-       sPorts[slot].select_infos = NULL;
+       uninit_port_locked(sPorts[slot]);
 
-       // Release the threads that were blocking on this port.
-       // read_port() will see the B_BAD_PORT_ID return value, and act 
accordingly
-       sPorts[slot].read_condition.NotifyAll(B_BAD_PORT_ID);
-       sPorts[slot].write_condition.NotifyAll(B_BAD_PORT_ID);
-       sNotificationService.Notify(PORT_REMOVED, id);
-
        locker.Unlock();
 
        MutexLocker _(sPortsLock);

Modified: haiku/trunk/src/system/kernel/team.cpp
===================================================================
--- haiku/trunk/src/system/kernel/team.cpp      2009-10-26 13:29:29 UTC (rev 
33770)
+++ haiku/trunk/src/system/kernel/team.cpp      2009-10-26 13:34:43 UTC (rev 
33771)
@@ -7,8 +7,10 @@
  * Distributed under the terms of the NewOS License.
  */
 
+
 /*!    Team functions */
 
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -798,6 +800,7 @@
        team->job_control_entry->team = team;
 
        list_init(&team->sem_list);
+       list_init(&team->port_list);
        list_init(&team->image_list);
        list_init(&team->watcher_list);
 
@@ -1392,7 +1395,7 @@
        delete_team_user_data(team);
        vm_delete_areas(team->address_space);
        xsi_sem_undo(team);
-       delete_owned_ports(team->id);
+       delete_owned_ports(team);
        sem_delete_owned_sems(team);
        remove_images(team);
        vfs_exec_io_context(team->io_context);
@@ -2463,7 +2466,7 @@
        vfs_put_io_context(team->io_context);
        delete_realtime_sem_context(team->realtime_sem_context);
        xsi_sem_undo(team);
-       delete_owned_ports(teamID);
+       delete_owned_ports(team);
        sem_delete_owned_sems(team);
        remove_images(team);
        vm_delete_address_space(team->address_space);


Other related posts:

  • » [haiku-commits] r33771 - in haiku/trunk: headers/private/kernel src/system/kernel - axeld