Sebastian Lackner : ntdll: Try to merge threadpool wait queue buckets if possible.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Jul 6 06:37:35 CDT 2015


Module: wine
Branch: master
Commit: 00215697780f16780c5229cade9dfaa585e86125
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=00215697780f16780c5229cade9dfaa585e86125

Author: Sebastian Lackner <sebastian at fds-team.de>
Date:   Sun Jul  5 02:25:32 2015 +0200

ntdll: Try to merge threadpool wait queue buckets if possible.

When the number of elements per bucket is too small, then try to reduce
the number of threads by merging buckets. This is to ensure that the
number of running wait queue threads doesn't get too big.

---

 dlls/ntdll/threadpool.c | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index 6aefce8..3f54208 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -1528,6 +1528,46 @@ static void CALLBACK waitqueue_thread_proc( void *param )
                 tp_object_release( wait );
             }
         }
+
+        /* Try to merge bucket with other threads. */
+        if (waitqueue.num_buckets > 1 && bucket->objcount &&
+            bucket->objcount <= MAXIMUM_WAITQUEUE_OBJECTS * 1 / 3)
+        {
+            struct waitqueue_bucket *other_bucket;
+            LIST_FOR_EACH_ENTRY( other_bucket, &waitqueue.buckets, struct waitqueue_bucket, bucket_entry )
+            {
+                if (other_bucket != bucket && other_bucket->objcount &&
+                    other_bucket->objcount + bucket->objcount <= MAXIMUM_WAITQUEUE_OBJECTS * 2 / 3)
+                {
+                    other_bucket->objcount += bucket->objcount;
+                    bucket->objcount = 0;
+
+                    /* Update reserved list. */
+                    LIST_FOR_EACH_ENTRY( wait, &bucket->reserved, struct threadpool_object, u.wait.wait_entry )
+                    {
+                        assert( wait->type == TP_OBJECT_TYPE_WAIT );
+                        wait->u.wait.bucket = other_bucket;
+                    }
+                    list_move_tail( &other_bucket->reserved, &bucket->reserved );
+
+                    /* Update waiting list. */
+                    LIST_FOR_EACH_ENTRY( wait, &bucket->waiting, struct threadpool_object, u.wait.wait_entry )
+                    {
+                        assert( wait->type == TP_OBJECT_TYPE_WAIT );
+                        wait->u.wait.bucket = other_bucket;
+                    }
+                    list_move_tail( &other_bucket->waiting, &bucket->waiting );
+
+                    /* Move bucket to the end, to keep the probability of
+                     * newly added wait objects as small as possible. */
+                    list_remove( &bucket->bucket_entry );
+                    list_add_tail( &waitqueue.buckets, &bucket->bucket_entry );
+
+                    NtSetEvent( other_bucket->update_event, NULL );
+                    break;
+                }
+            }
+        }
     }
 
     /* Remove this bucket from the list. */




More information about the wine-cvs mailing list