Coverage Report

Created: 2018-06-21 18:56

/home/travis/build/MoarVM/MoarVM/src/6model/reprs/Semaphore.c
Line
Count
Source (jump to first uncovered line)
1
#include "moar.h"
2
3
/* This representation's function pointer table. */
4
static const MVMREPROps Semaphore_this_repr;
5
6
/* Creates a new type object of this representation, and associates it with
7
 * the given HOW. */
8
1
static MVMObject * type_object_for(MVMThreadContext *tc, MVMObject *HOW) {
9
1
    MVMSTable *st  = MVM_gc_allocate_stable(tc, &Semaphore_this_repr, HOW);
10
1
11
1
    MVMROOT(tc, st, {
12
1
        MVMObject *obj = MVM_gc_allocate_type_object(tc, st);
13
1
        MVM_ASSIGN_REF(tc, &(st->header), st->WHAT, obj);
14
1
        st->size = sizeof(MVMSemaphore);
15
1
    });
16
1
17
1
    return st->WHAT;
18
1
}
19
20
/* Copies the body of one object to another. */
21
0
static void copy_to(MVMThreadContext *tc, MVMSTable *st, void *src, MVMObject *dest_root, void *dest) {
22
0
    MVM_exception_throw_adhoc(tc, "Cannot copy object with representation Semaphore");
23
0
}
24
25
/* Set up the Semaphore with its initial value. */
26
2
static void set_int(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMint64 value) {
27
2
    MVMSemaphoreBody *body = (MVMSemaphoreBody *)data;
28
2
    int r;
29
2
    body->sem = MVM_malloc(sizeof(uv_sem_t));
30
2
    if ((r = uv_sem_init(body->sem, (MVMuint32) value)) < 0) {
31
0
        MVM_free(body->sem);
32
0
        body->sem = NULL;
33
0
        MVM_exception_throw_adhoc(tc, "Failed to initialize Semaphore: %s",
34
0
            uv_strerror(r));
35
0
    }
36
2
}
37
38
/* Called by the VM in order to free memory associated with this object. */
39
0
static void gc_free(MVMThreadContext *tc, MVMObject *obj) {
40
0
    MVMSemaphore *sem = (MVMSemaphore *)obj;
41
0
    if (sem->body.sem) {
42
0
        uv_sem_destroy(sem->body.sem);
43
0
        MVM_free(sem->body.sem);
44
0
    }
45
0
}
46
47
static const MVMStorageSpec storage_spec = {
48
    MVM_STORAGE_SPEC_REFERENCE, /* inlineable */
49
    0,                          /* bits */
50
    0,                          /* align */
51
    MVM_STORAGE_SPEC_BP_NONE,   /* boxed_primitive */
52
    0,                          /* can_box */
53
    0,                          /* is_unsigned */
54
};
55
56
57
/* Gets the storage specification for this representation. */
58
0
static const MVMStorageSpec * get_storage_spec(MVMThreadContext *tc, MVMSTable *st) {
59
0
    return &storage_spec;
60
0
}
61
62
/* Compose the representation. */
63
1
static void compose(MVMThreadContext *tc, MVMSTable *st, MVMObject *info) {
64
1
    /* Nothing to do for this REPR. */
65
1
}
66
67
/* Set the size of the STable. */
68
0
static void deserialize_stable_size(MVMThreadContext *tc, MVMSTable *st, MVMSerializationReader *reader) {
69
0
    st->size = sizeof(MVMSemaphore);
70
0
}
71
72
/* Initializes the representation. */
73
144
const MVMREPROps * MVMSemaphore_initialize(MVMThreadContext *tc) {
74
144
    return &Semaphore_this_repr;
75
144
}
76
77
static const MVMREPROps Semaphore_this_repr = {
78
    type_object_for,
79
    MVM_gc_allocate_object,
80
    NULL, /* initialize */
81
    copy_to,
82
    MVM_REPR_DEFAULT_ATTR_FUNCS,
83
    {
84
        set_int,
85
        MVM_REPR_DEFAULT_GET_INT,
86
        MVM_REPR_DEFAULT_SET_NUM,
87
        MVM_REPR_DEFAULT_GET_NUM,
88
        MVM_REPR_DEFAULT_SET_STR,
89
        MVM_REPR_DEFAULT_GET_STR,
90
        MVM_REPR_DEFAULT_SET_UINT,
91
        MVM_REPR_DEFAULT_GET_UINT,
92
        MVM_REPR_DEFAULT_GET_BOXED_REF
93
    },    /* box_funcs */
94
    MVM_REPR_DEFAULT_POS_FUNCS,
95
    MVM_REPR_DEFAULT_ASS_FUNCS,
96
    MVM_REPR_DEFAULT_ELEMS,
97
    get_storage_spec,
98
    NULL, /* change_type */
99
    NULL, /* serialize */
100
    NULL, /* deserialize */
101
    NULL, /* serialize_repr_data */
102
    NULL, /* deserialize_repr_data */
103
    deserialize_stable_size,
104
    NULL, /* gc_mark */
105
    gc_free,
106
    NULL, /* gc_cleanup */
107
    NULL, /* gc_mark_repr_data */
108
    NULL, /* gc_free_repr_data */
109
    compose,
110
    NULL, /* spesh */
111
    "Semaphore", /* name */
112
    MVM_REPR_ID_Semaphore,
113
    NULL, /* unmanaged_size */
114
    NULL, /* describe_refs */
115
};
116
117
6
MVMint64 MVM_semaphore_tryacquire(MVMThreadContext *tc, MVMSemaphore *sem) {
118
6
    int r;
119
6
    MVM_telemetry_timestamp(tc, "Semaphore.tryAcquire");
120
6
    r = uv_sem_trywait(sem->body.sem);
121
6
    return !r;
122
6
}
123
124
9
void MVM_semaphore_acquire(MVMThreadContext *tc, MVMSemaphore *sem) {
125
9
    unsigned int interval_id;
126
9
    interval_id = MVM_telemetry_interval_start(tc, "Semaphore.acquire");
127
9
    MVMROOT(tc, sem, {
128
9
        MVM_gc_mark_thread_blocked(tc);
129
9
        uv_sem_wait(sem->body.sem);
130
9
        MVM_gc_mark_thread_unblocked(tc);
131
9
    });
132
9
    MVM_telemetry_interval_stop(tc, interval_id, "Semaphore.acquire");
133
9
}
134
135
6
void MVM_semaphore_release(MVMThreadContext *tc, MVMSemaphore *sem) {
136
6
    MVM_telemetry_timestamp(tc, "Semaphore.release");
137
6
    uv_sem_post(sem->body.sem);
138
6
}