sv.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * This file is subject to the terms and conditions of the GNU General Public
  3.  * License.  See the file "COPYING" in the main directory of this archive
  4.  * for more details.
  5.  *
  6.  * Copyright (C) 2000 Silicon Graphics, Inc.  All rights reserved
  7.  *
  8.  * This implemenation of synchronization variables is heavily based on
  9.  * one done by Steve Lord <lord@sgi.com>
  10.  *
  11.  * Paul Cassella <pwc@sgi.com>
  12.  */
  13. #ifndef SV_H
  14. #define SV_H
  15. #include <linux/spinlock.h>
  16. #include <asm/semaphore.h>
  17. #ifndef ASSERT
  18. #define ASSERT(x) do {   
  19.                     if(!(x)) {   
  20.       printk(KERN_ERR "%sn", "Assertion failed: " # x);  
  21.       BUG();   
  22.     }   
  23.                   } while(0)
  24. #define _SV_ASSERT
  25. #endif
  26. typedef void sv_mon_lock_t;
  27. typedef void (*sv_mon_unlock_func_t)(sv_mon_lock_t *lock);
  28. /* sv_flags values: */
  29. #define SV_ORDER_FIFO        0x001
  30. #define SV_ORDER_FILO        0x002
  31. #define SV_ORDER_LIFO        SV_ORDER_FILO
  32. /* If at some point one order becomes preferable to others, we can
  33.    switch to it if the caller of sv_init doesn't specify. */
  34. #define SV_ORDER_DEFAULT     SV_ORDER_FIFO
  35. #define SV_ORDER_MASK        0x00f
  36. #define SV_MON_SEMA          0x010
  37. #define SV_MON_SPIN          0x020
  38. #define SV_MON_MASK          0x0f0
  39. /*
  40.    If the monitor lock can be aquired from interrupts.  Note that this
  41.    is a superset of the cases in which the sv can be touched from
  42.    interrupts.
  43.    This is currently only valid when the monitor lock is a spinlock.
  44.    If this is used, sv_wait, sv_signal, and sv_broadcast must all be
  45.    called with interrupts disabled, which has to happen anyway to have
  46.    acquired the monitor spinlock. 
  47.  */
  48. #define SV_INTS              0x100
  49. /* ditto for bottom halves */
  50. #define SV_BHS               0x200
  51. /* sv_wait_flag values: */
  52. #define SV_WAIT_SIG          0x001 /* Allow sv_wait to be interrupted by a signal */
  53. typedef struct sv_s {
  54. wait_queue_head_t sv_waiters;
  55. sv_mon_lock_t *sv_mon_lock;   /* Lock held for exclusive access to monitor. */
  56. sv_mon_unlock_func_t sv_mon_unlock_func;
  57. spinlock_t sv_lock;  /* Spinlock protecting the sv itself. */
  58. int sv_flags;
  59. } sv_t;
  60. #define DECLARE_SYNC_VARIABLE(sv, l, f) sv_t sv = sv_init(&sv, l, f)
  61. /* 
  62.  * @sv the sync variable to initialize
  63.  * @monitor_lock the lock enforcing exclusive running in the monitor
  64.  * @flags one of
  65.  *   SV_MON_SEMA monitor_lock is a semaphore
  66.  *   SV_MON_SPIN monitor_lock is a spinlock
  67.  * and a bitwise or of some subset of
  68.  *   SV_INTS - the monitor lock can be acquired from interrupts (and
  69.  *             hence, whenever we hold it, interrupts are disabled or
  70.  *             we're in an interrupt.)  This is only valid when
  71.  *             SV_MON_SPIN is set.
  72.  */
  73. void sv_init(sv_t *sv, sv_mon_lock_t *monitor_lock, int flags);
  74. /*
  75.  * Set SV_WAIT_SIG in sv_wait_flags to let the sv_wait be interrupted by signals.
  76.  *
  77.  * timeout is how long to wait before giving up, or 0 to wait
  78.  * indefinately.  It is given in jiffies, and is relative.
  79.  *
  80.  * The associated lock must be locked on entry.  It is unlocked on return.
  81.  *
  82.  * Return values:
  83.  *
  84.  * n < 0 : interrupted,  -n jiffies remaining on timeout, or -1 if timeout == 0
  85.  * n = 0 : timeout expired
  86.  * n > 0 : sv_signal()'d, n jiffies remaining on timeout, or 1 if timeout == 0
  87.  */
  88. extern signed long sv_wait(sv_t *sv, int sv_wait_flags,
  89.    unsigned long timeout /* relative jiffies */);
  90. static inline int sv_wait_compat(sv_t *sv, sv_mon_lock_t *lock, int sv_wait_flags,
  91.  unsigned long timeout, int sv_mon_type)
  92. {
  93. ASSERT(sv_mon_type == (sv->sv_flags & SV_MON_MASK));
  94. if(sv->sv_mon_lock)
  95. ASSERT(lock == sv->sv_mon_lock);
  96. else
  97. sv->sv_mon_lock = lock;
  98. return sv_wait(sv, sv_wait_flags, timeout);
  99. }
  100. /* These work like Irix's sv_wait() and sv_wait_sig(), except the
  101.    caller must call the one correpsonding to the type of the monitor
  102.    lock. */
  103. #define sv_spin_wait(sv, lock)                              
  104.         sv_wait_compat(sv, lock, 0, 0, SV_MON_SPIN)
  105. #define sv_spin_wait_sig(sv, lock)                          
  106.         sv_wait_compat(sv, lock, SV_WAIT_SIG, 0, SV_MON_SPIN)
  107. #define sv_sema_wait(sv, lock)                              
  108.         sv_wait_compat(sv, lock, 0, 0, SV_MON_SEMA)
  109. #define sv_sema_wait_sig(sv, lock)                          
  110.         sv_wait_compat(sv, lock, SV_WAIT_SIG, 0, SV_MON_SEMA)
  111. /* These work as in Irix. */
  112. void sv_signal(sv_t *sv);
  113. void sv_broadcast(sv_t *sv);
  114. /* This works as in Irix. */
  115. void sv_destroy(sv_t *sv);
  116. #ifdef _SV_ASSERT
  117. #undef ASSERT
  118. #undef _SV_ASSERT
  119. #endif
  120. #endif