1  /*
   2   * \brief  Basic locking primitive
   3   * \author Norman Feske
   4   * \date   2006-07-26
   5   */

   6  
   7  /*
   8   * Copyright (C) 2006-2013 Genode Labs GmbH
   9   *
  10   * This file is part of the Genode OS framework, which is distributed
  11   * under the terms of the GNU General Public License version 2.
  12   */

  13  
  14  #ifndef _INCLUDE__BASE__CANCELABLE_LOCK_H_
  15  #define _INCLUDE__BASE__CANCELABLE_LOCK_H_
  16  
  17  #include <base/lock_guard.h>
  18  #include <base/blocking.h>
  19  
  20  namespace Genode {
  21  
  22     class Thread_base;
  23     class Cancelable_lock;
  24  }

  25  
  26  
  27  class Genode::Cancelable_lock
  28  {
  29     private:
  30  
  31        class Applicant
  32        {
  33           private:
  34  
  35              Thread_base *_thread_base;
  36              Applicant   *_to_wake_up;

  37  
  38           public:
  39  
  40              explicit Applicant(Thread_base *thread_base)
  41              : _thread_base(thread_base), _to_wake_up(0) { }

  42  
  43              void applicant_to_wake_up(Applicant *to_wake_up) {
  44                 _to_wake_up = to_wake_up; }

  45  
  46              Applicant *applicant_to_wake_up() { return _to_wake_up; }
  47  
  48              Thread_base *thread_base() { return _thread_base; }
  49  
  50              /**
  51               * Called from previous lock owner
  52               */

  53              void wake_up();

  54  
  55              bool operator == (Applicant &a) { return _thread_base == a.thread_base(); }
  56              bool operator != (Applicant &a) { return _thread_base != a.thread_base(); }

  57        }
;

  58  
  59        /*
  60         * Note that modifications of the applicants queue must be performed
  61         * atomically. Hence, we use the additional spinlock here.
  62         */

  63  
  64        volatile int _spinlock_state;
  65        volatile int _state;
  66  
  67        Applicant* volatile _last_applicant;
  68        Applicant  _owner;

  69  
  70     public:
  71  
  72        enum State { LOCKED, UNLOCKED };
  73  
  74        /**
  75         * Constructor
  76         */

  77        explicit Cancelable_lock(State initial = UNLOCKED);

  78  
  79        /**
  80         * Try to aquire the lock and block while the lock is not free
  81         *
  82         * \throw  Genode::Blocking_canceled
  83         */

  84        void lock();

  85  
  86        /**
  87         * Release lock
  88         */

  89        void unlock();

  90  
  91        /**
  92         * Lock guard
  93         */

  94        typedef Genode::Lock_guard<Cancelable_lock> Guard;

  95  }
;

  96  
  97  #endif /* _INCLUDE__BASE__CANCELABLE_LOCK_H_ */