Ignore:
Timestamp:
Mar 4, 2021, 7:40:25 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
77d601f
Parents:
342af53 (diff), a5040fe (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/locks.cfa

    r342af53 r8e4aa05  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2021 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// locks.hfa -- LIBCFATHREAD
     8// Runtime locks that used with the runtime thread system.
     9//
     10// Author           : Colby Alexander Parsons
     11// Created On       : Thu Jan 21 19:46:50 2021
     12// Last Modified By :
     13// Last Modified On :
     14// Update Count     :
     15//
     16
     17#define __cforall_thread__
     18
    119#include "locks.hfa"
    220#include "kernel_private.hfa"
     
    725//-----------------------------------------------------------------------------
    826// info_thread
    9 forall(dtype L | is_blocking_lock(L)) {
     27forall(L & | is_blocking_lock(L)) {
    1028        struct info_thread {
    1129                // used to put info_thread on a dl queue (aka sequence)
     
    5674
    5775void ^?{}( blocking_lock & this ) {}
    58 void  ?{}( single_acquisition_lock & this ) {((blocking_lock &)this){ false, false };}
    59 void ^?{}( single_acquisition_lock & this ) {}
    60 void  ?{}( owner_lock & this ) {((blocking_lock &)this){ true, true };}
    61 void ^?{}( owner_lock & this ) {}
    62 void  ?{}( multiple_acquisition_lock & this ) {((blocking_lock &)this){ true, false };}
    63 void ^?{}( multiple_acquisition_lock & this ) {}
     76
    6477
    6578void lock( blocking_lock & this ) with( this ) {
     
    170183
    171184//-----------------------------------------------------------------------------
    172 // Overloaded routines for traits
    173 // These routines are temporary until an inheritance bug is fixed
    174 void   lock      ( single_acquisition_lock & this ) { lock   ( (blocking_lock &)this ); }
    175 void   unlock    ( single_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); }
    176 void   on_wait   ( single_acquisition_lock & this ) { on_wait( (blocking_lock &)this ); }
    177 void   on_notify ( single_acquisition_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }
    178 void   set_recursion_count( single_acquisition_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); }
    179 size_t get_recursion_count( single_acquisition_lock & this ) { return get_recursion_count( (blocking_lock &)this ); }
    180 
    181 void   lock     ( owner_lock & this ) { lock   ( (blocking_lock &)this ); }
    182 void   unlock   ( owner_lock & this ) { unlock ( (blocking_lock &)this ); }
    183 void   on_wait  ( owner_lock & this ) { on_wait( (blocking_lock &)this ); }
    184 void   on_notify( owner_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }
    185 void   set_recursion_count( owner_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); }
    186 size_t get_recursion_count( owner_lock & this ) { return get_recursion_count( (blocking_lock &)this ); }
    187 
    188 void   lock     ( multiple_acquisition_lock & this ) { lock   ( (blocking_lock &)this ); }
    189 void   unlock   ( multiple_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); }
    190 void   on_wait  ( multiple_acquisition_lock & this ) { on_wait( (blocking_lock &)this ); }
    191 void   on_notify( multiple_acquisition_lock & this, struct $thread * t ){ on_notify( (blocking_lock &)this, t ); }
    192 void   set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
    193 size_t get_recursion_count( multiple_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }
    194 
    195 //-----------------------------------------------------------------------------
    196185// alarm node wrapper
    197 forall(dtype L | is_blocking_lock(L)) {
     186forall(L & | is_blocking_lock(L)) {
    198187        struct alarm_node_wrap {
    199188                alarm_node_t alarm_node;
     
    239228//-----------------------------------------------------------------------------
    240229// condition variable
    241 forall(dtype L | is_blocking_lock(L)) {
     230forall(L & | is_blocking_lock(L)) {
    242231
    243232        void ?{}( condition_variable(L) & this ){
     
    356345        bool wait( condition_variable(L) & this, L & l, uintptr_t info, Time time         ) with(this) { WAIT_TIME( info, &l , time ) }
    357346}
     347
     348//-----------------------------------------------------------------------------
     349// Semaphore
     350void  ?{}( semaphore & this, int count = 1 ) {
     351        (this.lock){};
     352        this.count = count;
     353        (this.waiting){};
     354}
     355void ^?{}(semaphore & this) {}
     356
     357bool P(semaphore & this) with( this ){
     358        lock( lock __cfaabi_dbg_ctx2 );
     359        count -= 1;
     360        if ( count < 0 ) {
     361                // queue current task
     362                append( waiting, active_thread() );
     363
     364                // atomically release spin lock and block
     365                unlock( lock );
     366                park();
     367                return true;
     368        }
     369        else {
     370            unlock( lock );
     371            return false;
     372        }
     373}
     374
     375bool V(semaphore & this) with( this ) {
     376        $thread * thrd = 0p;
     377        lock( lock __cfaabi_dbg_ctx2 );
     378        count += 1;
     379        if ( count <= 0 ) {
     380                // remove task at head of waiting list
     381                thrd = pop_head( waiting );
     382        }
     383
     384        unlock( lock );
     385
     386        // make new owner
     387        unpark( thrd );
     388
     389        return thrd != 0p;
     390}
     391
     392bool V(semaphore & this, unsigned diff) with( this ) {
     393        $thread * thrd = 0p;
     394        lock( lock __cfaabi_dbg_ctx2 );
     395        int release = max(-count, (int)diff);
     396        count += diff;
     397        for(release) {
     398                unpark( pop_head( waiting ) );
     399        }
     400
     401        unlock( lock );
     402
     403        return thrd != 0p;
     404}
Note: See TracChangeset for help on using the changeset viewer.