// // Cforall Version 1.0.0 Copyright (C) 2022 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // comp_basic.cfa -- Test that simple completions work correctly // even when mixing io_uring and regular calls // // Author : Thierry Delisle // Created On : Thu Sep 01 11:27:08 2022 // Last Modified By : // Last Modified On : // Update Count : // #include #include #include #include #include #include #include #include static struct { barrier & bar; int pipe[2]; } globals; Duration default_preemption() { return 0; } enum { TIMES = 1000 }; volatile unsigned counter = 0; // ----- Reader ----- // Reader from the pipe to test completion doesn't starve thread Reader {}; void main(Reader & this) { char thrash[1]; bool do_read = has_user_level_blocking( (fptr_t)async_read ); for(TIMES) { io_future_t f; if ( do_read ) { async_read(f, globals.pipe[0], thrash, 1, 0); } else { fulfil(f, 0); // If we don't have user-level blocking just play along } block( globals.bar ); yield( prng( this, 15 ) ); unsigned i = __atomic_add_fetch( &counter, 1, __ATOMIC_SEQ_CST ); if(0 == (i % 100)) sout | i; wait( f ); if(f.result < 0) abort | "Read error" | -f.result | ":" | strerror(-f.result); block( globals.bar ); } } // ----- Writer ----- // Writes to the pipe so the Reader can unblock // takes its sweet time so the Reader has to block thread Writer {}; void main(Writer & this) { for(TIMES) { block( globals.bar ); sleep( 1`us ); char buf[1] = { '+' }; int ret = write( globals.pipe[1], buf, 1 ); if(ret < 0) abort | "Write error" | errno | ":" | strerror(errno); block( globals.bar ); } } int main() { barrier bar = { 2 }; &globals.bar = &bar; int ret = pipe(globals.pipe); if(ret != 0) abort | "Pipe error" | errno | ":" | strerror(errno); sout | "starting"; { Reader ior; Writer iow; } sout | "done"; }