@@ -32,6 +32,7 @@ limitations under the License.
3232#include " ../../test/ci-tools.h"
3333#include " ../future.h"
3434
35+ #include < photon/common/lockfree_queue.h>
3536
3637using namespace std ;
3738using namespace photon ;
@@ -698,6 +699,40 @@ TEST(Semaphore, heavy) {
698699 wait_for_completion ();
699700}
700701
702+ using Ring = photon::common::RingChannel<
703+ LockfreeSPSCRingQueue<Delegate<void >, 16 >>;
704+
705+ void test_disposable_semaphore (Ring* ring, uint64_t count, uint64_t slat, uint64_t oplat) {
706+ while (count--) {
707+ disposable_semaphore sem;
708+ auto op = [oplat, &sem]() {
709+ if (oplat) ::usleep (oplat); // operation latency
710+ sem.signal (); // completion signal
711+ };
712+ ring->send (op);
713+ if (slat) ::usleep (slat); // submission latency
714+ int ret = sem.wait (1000 *1000 ); // wait for completion
715+ EXPECT_EQ (0 , ret);
716+ if (ret) return ;
717+ }
718+ }
719+
720+ TEST (disposable_semaphore, basic) {
721+ Ring ring;
722+ std::thread worker ([&]() {
723+ vcpu_init ();
724+ while (auto cb = ring.recv (0 , 0 )) cb ();
725+ vcpu_fini ();
726+ });
727+
728+ test_disposable_semaphore (&ring, 10000 , 0 , 100 );
729+ test_disposable_semaphore (&ring, 10000 , 100 , 0 );
730+ test_disposable_semaphore (&ring, 10000 , 00 , 00 );
731+
732+ ring.send ({});
733+ worker.join ();
734+ }
735+
701736TEST (Sleep, sleep_only_thread) { // Sleep_sleep_only_thread_Test::TestBody
702737 // If current thread is only thread and sleeping
703738 // it should be able to avoid crash during long time sleep
0 commit comments