00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef _POSIX_MUTEX_H
00020 #define _POSIX_MUTEX_H
00021
00022 #include <posix/internal.h>
00023 #include <posix/thread.h>
00024
00025 typedef struct pse51_mutex {
00026 xnsynch_t synchbase;
00027 xnholder_t link;
00028
00029 #define link2mutex(laddr) \
00030 ((pse51_mutex_t *)(((char *)laddr) - offsetof(pse51_mutex_t, link)))
00031
00032 pthread_mutexattr_t attr;
00033 unsigned count;
00034 unsigned condvars;
00035
00036 pse51_kqueues_t *owningq;
00037 } pse51_mutex_t;
00038
00039 void pse51_mutexq_cleanup(pse51_kqueues_t *q);
00040
00041 void pse51_mutex_pkg_init(void);
00042
00043 void pse51_mutex_pkg_cleanup(void);
00044
00045
00046 int pse51_mutex_timedlock_break(struct __shadow_mutex *shadow,
00047 int timed, xnticks_t to);
00048
00049
00050 static inline int pse51_mutex_trylock_internal(xnthread_t *cur,
00051 struct __shadow_mutex *shadow,
00052 unsigned count)
00053 {
00054 pse51_mutex_t *mutex = shadow->mutex;
00055
00056 if (xnpod_unblockable_p())
00057 return EPERM;
00058
00059 if (!pse51_obj_active(shadow, PSE51_MUTEX_MAGIC, struct __shadow_mutex))
00060 return EINVAL;
00061
00062 #if XENO_DEBUG(POSIX)
00063 if (mutex->owningq != pse51_kqueues(mutex->attr.pshared))
00064 return EPERM;
00065 #endif
00066
00067 if (mutex->count)
00068 return EBUSY;
00069
00070 xnsynch_set_owner(&mutex->synchbase, cur);
00071 mutex->count = count;
00072 return 0;
00073 }
00074
00075
00076 static inline int pse51_mutex_timedlock_internal(xnthread_t *cur,
00077 struct __shadow_mutex *shadow,
00078 unsigned count,
00079 int timed,
00080 xnticks_t abs_to)
00081
00082 {
00083 pse51_mutex_t *mutex;
00084 int err;
00085
00086 err = pse51_mutex_trylock_internal(cur, shadow, count);
00087 if (err != EBUSY)
00088 return err;
00089
00090 mutex = shadow->mutex;
00091 if (xnsynch_owner(&mutex->synchbase) == cur)
00092 return EBUSY;
00093
00094 if (timed)
00095 xnsynch_sleep_on(&mutex->synchbase, abs_to, XN_REALTIME);
00096 else
00097 xnsynch_sleep_on(&mutex->synchbase, XN_INFINITE, XN_RELATIVE);
00098
00099 if (xnthread_test_info(cur, XNBREAK))
00100 return EINTR;
00101
00102 if (xnthread_test_info(cur, XNRMID))
00103 return EINVAL;
00104
00105 if (xnthread_test_info(cur, XNTIMEO))
00106 return ETIMEDOUT;
00107
00108 return 0;
00109 }
00110
00111 #endif