]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/plr/include/pthread_rep.h
update
[l4.git] / l4 / pkg / plr / include / pthread_rep.h
1 #pragma once
2
3 #include <l4/util/atomic.h>
4
5 enum {
6         mutex_init_id   = 0,
7         mutex_lock_id   = 1,
8         mutex_unlock_id = 2,
9         pt_lock_id      = 3,
10         pt_unlock_id    = 4,
11         pt_max_wrappers = 5,
12
13         lock_entry_free = 0,
14         lock_unlocking  = 0xAAAAAAAA,
15         lock_unowned    = 0xFFFFFFFF,
16
17         NUM_TRAMPOLINES = 32,
18         TRAMPOLINE_SIZE = 32,
19         NUM_LOCKS       = 64,
20         LOCK_INFO_ADDR  = 0xA000,
21 };
22
23 typedef struct {
24   unsigned char trampolines[NUM_TRAMPOLINES * TRAMPOLINE_SIZE];
25   struct {
26           volatile l4_addr_t lockdesc;            // corresponding pthread_mutex_t ptr
27           volatile l4_addr_t owner;               // lock owner
28           volatile l4_addr_t owner_epoch;         // lock holder's epoch
29           volatile l4_addr_t wait_count; // count how many threads wait to acquire this lock
30           volatile l4_addr_t acq_count;           // count how many threads acquired this lock
31           volatile l4_addr_t wake_count;          // count how many threads should be unlocked
32           volatile l4_uint32_t lock;     // internal: lock for this row
33   } locks[NUM_LOCKS];
34   volatile l4_umword_t replica_count; // number of replicas running a.t.m.
35 } lock_info;
36
37 /* Compile-time assertion: lock_info must fit into a page) */
38 char __lock_info_size_valid[!!(sizeof(lock_info) <= L4_PAGESIZE)-1];
39
40 lock_info* get_lock_info(void);
41 lock_info* get_lock_info(void) {
42         return (lock_info*)LOCK_INFO_ADDR;
43 }
44
45
46 static inline void lock_li(volatile lock_info *li, unsigned idx)
47 {
48         asm volatile ("" : : : "memory");
49         while (!l4util_cmpxchg32(&li->locks[idx].lock, 0, 1)) {
50                 asm volatile ("ud2" : : : "eax", "memory");
51         }
52 }
53
54 static inline void unlock_li(volatile lock_info* li, unsigned idx)
55 {
56         asm volatile ("" : : : "eax", "memory");
57         li->locks[idx].lock = 0;
58         asm volatile ("" ::: "memory");
59 }
60
61
62 static char const *
63 __attribute__((used))
64 lockID_to_str(unsigned id)
65 {
66         switch(id) {
67                 case mutex_init_id:   return "mutex_init";
68                 case mutex_lock_id:   return "mutex_lock";
69                 case mutex_unlock_id: return "mutex_unlock";
70                 case pt_lock_id:      return "__pthread_lock";
71                 case pt_unlock_id:    return "__pthread_unlock";
72                 default: return "???";
73         }
74 }