benaphore.h

Go to the documentation of this file.
00001 /*
00002     Copyright (c) 2002, Thomas Kurschel
00003 
00004 
00005     Part of Open SCSI bus manager
00006         
00007     Benaphore definition
00008 */
00009 
00010 #ifndef _BENAPHORE_H
00011 #define _BENAPHORE_H
00012 
00013 #include <KernelExport.h>
00014 
00015 typedef struct {
00016     int32   ben;
00017     sem_id  sem;
00018 } benaphore;
00019 
00020  
00021 #define INIT_BEN(x, prefix) ( (x)->ben = -1, (x)->sem = create_sem(0, #prefix " benaphore"), (x)->sem )
00022 #define DELETE_BEN(x)       delete_sem((x)->sem);
00023 
00024 #if __GNUC__ && _X86_ && !DEBUG
00025 
00026 #ifdef NO_PIC
00027 
00028 // don't use normal inline as this _does_ incur overhead;
00029 // also, we have to include the xxx_sem call in the assembler code
00030 // as this is the only way to use flags directly (else we had to create
00031 // a temporary variable); this function call leads to the following:
00032 // - it's not PIC safe, making it unusable in user mode!
00033 // - function calls clobber eax, ecx, edx and memory
00034 #define ACQUIRE_BEN( x ) \
00035 __asm__ __volatile__ ( \
00036     "lock incl %0;" \
00037     "jng 1f;" \
00038     "push %1;" \
00039     "call acquire_sem;" \
00040     "add  $4,%%esp;" \
00041     "1:;" \
00042     : "=m" ((x)->ben) \
00043     : "m" ((x)->sem), "0" ((x)->ben) \
00044     : "ax", "cx", "dx" \
00045 );
00046 
00047 #define RELEASE_BEN( x ) \
00048 __asm__ __volatile__ ( \
00049     "lock decl %0;" \
00050     "jl 1f;" \
00051     "push %1;" \
00052     "call release_sem;" \
00053     "add  $4,%%esp;" \
00054     "1:;" \
00055     : "=m" ((x)->ben) \
00056     : "m" ((x)->sem), "0" ((x)->ben) \
00057     : "ax", "cx", "dx" \
00058 );
00059 
00060 #else   // NO_PIC
00061 
00062 // larger, but PIC-safe version
00063 
00064 #define ACQUIRE_BEN( x ) \
00065 { \
00066     char not_idle; \
00067 \
00068     __asm__ __volatile__ ( \
00069         "lock incl %0;" \
00070         "setg %1" \
00071         : "=m" ((x)->ben), "=qm" (not_idle) \
00072         : "0" ((x)->ben) \
00073     ); \
00074 \
00075     if( not_idle ) \
00076         acquire_sem( (x)->sem ); \
00077 }
00078 
00079 #define RELEASE_BEN( x ) \
00080 { \
00081     char not_idle; \
00082 \
00083     __asm__ __volatile__ ( \
00084         "lock decl %0;" \
00085         "setge %1" \
00086         : "=m" ((x)->ben), "=qm" (not_idle) \
00087         : "0" ((x)->ben) \
00088     ); \
00089 \
00090     if( not_idle ) \
00091         release_sem( (x)->sem ); \
00092 }
00093 
00094 #endif
00095 
00096 #else   // __GNUC__ && _X86_
00097 
00098 #define ACQUIRE_BEN(x) \
00099     if((atomic_add(&((x)->ben), 1)) >= 0) \
00100         acquire_sem((x)->sem);
00101         
00102 #define RELEASE_BEN(x) \
00103     if((atomic_add(&((x)->ben), -1)) > 0) \
00104         release_sem((x)->sem);
00105 
00106 #endif
00107 
00108 
00109 #endif

Copyright 2005 by yellowTAB GmbH, Be Inc., Palm Source Inc. and their respective legal successors
All rights reserved.