forked from KolibriOS/kolibrios
ddk: 3.19-rc1
git-svn-id: svn://kolibrios.org@5270 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
@@ -40,23 +40,103 @@
|
||||
#define _LINUX_RESERVATION_H
|
||||
|
||||
#include <linux/ww_mutex.h>
|
||||
#include <linux/fence.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/seqlock.h>
|
||||
#include <linux/rcupdate.h>
|
||||
|
||||
extern struct ww_class reservation_ww_class;
|
||||
extern struct lock_class_key reservation_seqcount_class;
|
||||
extern const char reservation_seqcount_string[];
|
||||
|
||||
struct reservation_object_list {
|
||||
struct rcu_head rcu;
|
||||
u32 shared_count, shared_max;
|
||||
struct fence __rcu *shared[];
|
||||
};
|
||||
|
||||
struct reservation_object {
|
||||
struct ww_mutex lock;
|
||||
seqcount_t seq;
|
||||
|
||||
struct fence __rcu *fence_excl;
|
||||
struct reservation_object_list __rcu *fence;
|
||||
struct reservation_object_list *staged;
|
||||
};
|
||||
|
||||
#define reservation_object_held(obj) lockdep_is_held(&(obj)->lock.base)
|
||||
#define reservation_object_assert_held(obj) \
|
||||
lockdep_assert_held(&(obj)->lock.base)
|
||||
|
||||
static inline void
|
||||
reservation_object_init(struct reservation_object *obj)
|
||||
{
|
||||
ww_mutex_init(&obj->lock, &reservation_ww_class);
|
||||
|
||||
__seqcount_init(&obj->seq, reservation_seqcount_string, &reservation_seqcount_class);
|
||||
RCU_INIT_POINTER(obj->fence, NULL);
|
||||
RCU_INIT_POINTER(obj->fence_excl, NULL);
|
||||
obj->staged = NULL;
|
||||
}
|
||||
|
||||
static inline void
|
||||
reservation_object_fini(struct reservation_object *obj)
|
||||
{
|
||||
int i;
|
||||
struct reservation_object_list *fobj;
|
||||
struct fence *excl;
|
||||
|
||||
/*
|
||||
* This object should be dead and all references must have
|
||||
* been released to it, so no need to be protected with rcu.
|
||||
*/
|
||||
excl = rcu_dereference_protected(obj->fence_excl, 1);
|
||||
if (excl)
|
||||
fence_put(excl);
|
||||
|
||||
fobj = rcu_dereference_protected(obj->fence, 1);
|
||||
if (fobj) {
|
||||
for (i = 0; i < fobj->shared_count; ++i)
|
||||
fence_put(rcu_dereference_protected(fobj->shared[i], 1));
|
||||
|
||||
kfree(fobj);
|
||||
}
|
||||
kfree(obj->staged);
|
||||
|
||||
ww_mutex_destroy(&obj->lock);
|
||||
}
|
||||
|
||||
static inline struct reservation_object_list *
|
||||
reservation_object_get_list(struct reservation_object *obj)
|
||||
{
|
||||
return rcu_dereference_protected(obj->fence,
|
||||
reservation_object_held(obj));
|
||||
}
|
||||
|
||||
static inline struct fence *
|
||||
reservation_object_get_excl(struct reservation_object *obj)
|
||||
{
|
||||
return rcu_dereference_protected(obj->fence_excl,
|
||||
reservation_object_held(obj));
|
||||
}
|
||||
|
||||
int reservation_object_reserve_shared(struct reservation_object *obj);
|
||||
void reservation_object_add_shared_fence(struct reservation_object *obj,
|
||||
struct fence *fence);
|
||||
|
||||
void reservation_object_add_excl_fence(struct reservation_object *obj,
|
||||
struct fence *fence);
|
||||
|
||||
int reservation_object_get_fences_rcu(struct reservation_object *obj,
|
||||
struct fence **pfence_excl,
|
||||
unsigned *pshared_count,
|
||||
struct fence ***pshared);
|
||||
|
||||
long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
|
||||
bool wait_all, bool intr,
|
||||
unsigned long timeout);
|
||||
|
||||
bool reservation_object_test_signaled_rcu(struct reservation_object *obj,
|
||||
bool test_all);
|
||||
|
||||
#endif /* _LINUX_RESERVATION_H */
|
||||
|
Reference in New Issue
Block a user