// -*- C++ -*- (c) 2013 Milan Lenco // (c) 2014-2019 Vladimír Štill // (c) 2016 Henrich Lauko // (c) 2016 Jan Mrázek /* Includes */ #include #include using namespace __dios; /* Barrier */ /* pthread_barrier_t representation: { .__counter: 16 bits .__nthreads: the number of threads to synchronize, 16 bits } */ int pthread_barrier_destroy( pthread_barrier_t *barrier ) noexcept { __dios::FencedInterruptMask mask; if ( barrier == NULL ) return EINVAL; int r = _destroy_cond_or_barrier( barrier ); if ( r == 0 ) { int uninit; barrier->__nthreads = uninit; } return r; } int pthread_barrier_init( pthread_barrier_t *barrier, const pthread_barrierattr_t * /* TODO: barrier attributes */, unsigned count ) noexcept { __dios::FencedInterruptMask mask; if ( count == 0 || barrier == NULL ) return EINVAL; // Set the number of threads that must call pthread_barrier_wait() before // any of them successfully return from the call. barrier->__nthreads = count; barrier->__counter = 0; return 0; } int pthread_barrier_wait( pthread_barrier_t *barrier ) noexcept { __dios::FencedInterruptMask mask; if ( barrier == NULL ) return EINVAL; int ret = 0; int counter = barrier->__counter; int release_count = barrier->__nthreads; if ( ( counter + 1 ) == release_count ) { _cond_signal< true >( barrier ); return PTHREAD_BARRIER_SERIAL_THREAD; } // fall asleep _PThread &thread = getThread(); thread.setSleeping( barrier ); _cond_adjust_count( barrier, 1 ); // one more thread is blocked on this barrier // sleeping __lart_termsec_begin( __lart_termsec_kind_barrier_wait, barrier, &thread ); waitOrCancel( mask, [&] { return thread.sleeping == Barrier; } ); __lart_termsec_end( __lart_termsec_kind_barrier_wait, barrier, &thread ); return 0; } /* Barrier attributes */ int pthread_barrierattr_destroy( pthread_barrierattr_t * ) noexcept { /* TODO */ return 0; } int pthread_barrierattr_getpshared( const pthread_barrierattr_t *, int * ) noexcept { /* TODO */ return 0; } int pthread_barrierattr_init( pthread_barrierattr_t * ) noexcept { /* TODO */ return 0; } int pthread_barrierattr_setpshared( pthread_barrierattr_t *, int ) noexcept { /* TODO */ return 0; }