File: postgres_auth.c

package info (click to toggle)
chibicc 1.0.23.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,832 kB
  • sloc: ansic: 62,911; sh: 275; makefile: 92
file content (120 lines) | stat: -rw-r--r-- 2,872 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <assert.h>


typedef uint32_t uint32;

typedef struct {
    volatile uint32 value;
} pg_atomic_uint32;

#define AssertPointerAlignment(ptr, align) assert(((uintptr_t)(ptr) % (align)) == 0)

#define LW_EXCLUSIVE 1
#define LW_SHARED 2
#define LW_LOCK_MASK 0xF
#define LW_VAL_EXCLUSIVE 0x10
#define LW_VAL_SHARED 0x20

typedef struct {
    pg_atomic_uint32 state;
#ifdef LOCK_DEBUG
    void* owner;
#endif
} LWLock;

/* Atomic compare-and-exchange function */
static inline bool
pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr,
                                    uint32 *expected, uint32 newval)
{
    unsigned char ret;  // Use unsigned char for setz result

    __asm__ __volatile__(
        "lock\n\t"
        "cmpxchgl %3, %2\n\t"
        "setz %1"
    : "=a" (*expected), "=q" (ret), "+m" (ptr->value)
    : "r" (newval), "a" (*expected)
    : "memory", "cc");
    assert(1 == ret);
    return (bool) ret;
}

static inline bool
pg_atomic_compare_exchange_u32(volatile pg_atomic_uint32 *ptr,
                               uint32 *expected, uint32 newval)
{
    AssertPointerAlignment(ptr, 4);
    AssertPointerAlignment(expected, 4);

    return pg_atomic_compare_exchange_u32_impl(ptr, expected, newval);
}

/* Attempt to lock function */
static bool
LWLockAttemptLock(LWLock *lock, uint32 mode)
{
    uint32 old_state;

    //Assert(mode == LW_EXCLUSIVE || mode == LW_SHARED);

    old_state = lock->state.value;

    while (true)
    {
        uint32 desired_state;
        bool lock_free;

        desired_state = old_state;

        if (mode == LW_EXCLUSIVE)
        {
            lock_free = (old_state & LW_LOCK_MASK) == 0;
            if (lock_free)
                desired_state += LW_VAL_EXCLUSIVE;
        }
        else
        {
            lock_free = (old_state & LW_VAL_EXCLUSIVE) == 0;
            if (lock_free)
                desired_state += LW_VAL_SHARED;
        }

        if (pg_atomic_compare_exchange_u32(&lock->state, &old_state, desired_state))
        {
            if (lock_free)
            {
#ifdef LOCK_DEBUG
                if (mode == LW_EXCLUSIVE)
                    lock->owner = (void*)1;  // Simulating a lock owner for debug
#endif
                return false;
            }
            else
                return true;
        }
    }
}

int main() {
    LWLock lock = {{0}};  // Initialize the lock

    // Attempt to acquire an exclusive lock
    if (!LWLockAttemptLock(&lock, LW_EXCLUSIVE)) {
        printf("Acquired exclusive lock.\n");
    } else {
        printf("Failed to acquire exclusive lock.\n");
    }

    // Attempt to acquire a shared lock
    if (!LWLockAttemptLock(&lock, LW_SHARED)) {
        printf("Acquired shared lock.\n");
    } else {
        printf("Failed to acquire shared lock.\n");
    }

    return 0;
}