You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Allow strings to be directly copied between threads in some cases (#93)
closes#71
This works by allowing threads direct access to the original thread's string for as long as it is cached in the origin thread's ThreadedBase connection.
As long as the connection lives long enough for the reading thread(s) to dereference the string in question (which, thanks to 4ddf79e, will be the case in all common cases, including dead threads and completed worker tasks), the extra malloc and string copy is avoided on the writer thread, which significantly improves performance in synthetic benchmarks.
If the connection is destroyed, it will create persistent copies of any cached strings during free_obj, and the old double-copy method will be used to enable the string to be accessed. However, this is rarely needed.
The caveat to this is that pthreads_store_sync_local_properties() will do work more often when strings are used, but I don't think this is a big concern. For most cases, the property table should be small enough for this to not be a problem anyway, and for the large cases, we need to implement dedicated queue data structures anyway. Profiling anyway suggested that the overhead of zend_hash_internal_pointer_reset_ex() was several orders of magnitude bigger a problem anyway (see #42).
Test that string copying works correctly from live and dead threads
3
+
--DESCRIPTION--
4
+
We implement some optimisations to allow strings to be copied only 1 time, as long as they live on the child thread for long enough for the parent thread to dereference them.
5
+
This test verifies the basic functionality, with a string that will be single-copied (the "a" string) and another which will be copied the old way with just-in-time rescue when the object is destroyed.
6
+
--FILE--
7
+
<?php
8
+
9
+
$thread = newclassextends \Thread{
10
+
11
+
public\ThreadedArray$buffer;
12
+
13
+
publicfunction__construct(){
14
+
$this->buffer = new \ThreadedArray();
15
+
}
16
+
17
+
public ?string$str = null;
18
+
publicbool$shutdown = false;
19
+
20
+
21
+
publicfunctionrun() : void{
22
+
$this->synchronized(function() : void{
23
+
$this->buffer[] = str_repeat("a", 20);
24
+
$this->buffer[] = str_repeat("b", 20);
25
+
$this->notify();
26
+
});
27
+
$this->synchronized(function() : void{
28
+
while(!$this->shutdown){
29
+
$this->wait();
30
+
}
31
+
});
32
+
}
33
+
};
34
+
$thread->start();
35
+
36
+
$thread->synchronized(function() use ($thread) : void{
37
+
while($thread->buffer->count() === 0){
38
+
$thread->wait();
39
+
}
40
+
});
41
+
var_dump($thread->buffer->shift());
42
+
$thread->synchronized(function() use ($thread) : void{
0 commit comments