-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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).
- Loading branch information
Showing
5 changed files
with
156 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
--TEST-- | ||
Test that string copying works correctly from live and dead threads | ||
--DESCRIPTION-- | ||
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. | ||
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. | ||
--FILE-- | ||
<?php | ||
|
||
$thread = new class extends \Thread{ | ||
|
||
public \ThreadedArray $buffer; | ||
|
||
public function __construct(){ | ||
$this->buffer = new \ThreadedArray(); | ||
} | ||
|
||
public ?string $str = null; | ||
public bool $shutdown = false; | ||
|
||
|
||
public function run() : void{ | ||
$this->synchronized(function() : void{ | ||
$this->buffer[] = str_repeat("a", 20); | ||
$this->buffer[] = str_repeat("b", 20); | ||
$this->notify(); | ||
}); | ||
$this->synchronized(function() : void{ | ||
while(!$this->shutdown){ | ||
$this->wait(); | ||
} | ||
}); | ||
} | ||
}; | ||
$thread->start(); | ||
|
||
$thread->synchronized(function() use ($thread) : void{ | ||
while($thread->buffer->count() === 0){ | ||
$thread->wait(); | ||
} | ||
}); | ||
var_dump($thread->buffer->shift()); | ||
$thread->synchronized(function() use ($thread) : void{ | ||
$thread->shutdown = true; | ||
$thread->notify(); | ||
}); | ||
|
||
$thread->join(); | ||
var_dump($thread->buffer->shift()); | ||
|
||
echo "OK\n"; | ||
?> | ||
--EXPECT-- | ||
string(20) "aaaaaaaaaaaaaaaaaaaa" | ||
string(20) "bbbbbbbbbbbbbbbbbbbb" | ||
OK | ||
|