summaryrefslogtreecommitdiffstats
path: root/lib/libjove/object/untyped.c
blob: 281bb606e96ef8e3cf47c6691e9875094611ef82 (plain) (blame)
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
121
122
123
124
125
126
127
#include <jove.h>
#include <object.h>
#include <syscall.h>
#include <error.h>
#include <string.h>

void
_jove_alloc_untyped_inplace(
        KernelObjectUntyped *untyped,
        KernelObjectDirectory *parent,
        uint8_t membi
        )
{
    *untyped = (KernelObjectUntyped) {
        .typed = (KernelObjectTyped) {
            .type = KO_MEMORY_UNTYPED,
            .parent = parent,
            .membi = membi
        },
        .bytes = 0,
        .alignment = -1,
        .children_head = NULL,
        .sibling = NULL
    };

    parent->children[membi] = (KernelObjectTyped*)untyped;
    parent->lastmemb = 0;
}

KernelObjectUntyped*
_jove_alloc_untyped(KernelObjectDirectory *parent, uint8_t membi)
{
    if(_jove_alloc == NULL) {
        jove_errno = EJOVE_NOALLOC;
        return NULL;
    }
    if(parent->children[membi] != NULL) {
        jove_errno = EJOVE_FULL;
    }

    KernelObjectUntyped *untyped = _jove_alloc(sizeof(KernelObjectUntyped));

    _jove_alloc_untyped_inplace(untyped, parent, membi);
    return untyped;
}

KernelObjectUntyped*
jove_object_as_untyped(KernelObjectTyped *typed)
{
    if(typed->type == KO_MEMORY_UNTYPED) return (KernelObjectUntyped*)typed;
    jove_errno = EJOVE_BADOBJ;
    return NULL;
}

int
jove_untyped_size(KernelObjectUntyped *untyped)
{
    if(untyped->bytes != 0)
        return untyped->bytes;

    int e = _syscall_invoke_untyped_size(untyped, &untyped->bytes);
    if(e) return jove_error_from_kerror(e);

    return untyped->bytes;
}

int
jove_untyped_alignment(KernelObjectUntyped *untyped)
{
    if(untyped->alignment >= 0)
        return untyped->alignment;

    int e = _syscall_invoke_untyped_alignment(untyped, (size_t*)&untyped->alignment);
    if(e) return jove_error_from_kerror(e);

    return untyped->alignment;
}

KernelObjectUntyped*
jove_untyped_split(
        KernelObjectUntyped *untyped,
        size_t bytes,
        KernelObjectDirectory *dest,
        uint8_t destmemb
        )
{
    if(!_jove_alloc) {
        jove_errno = EJOVE_NOALLOC;
        return NULL;
    }

    KernelObjectUntyped temp;
    _jove_alloc_untyped_inplace(&temp, dest, destmemb);

    jove_errno = jove_untyped_split_inplace(untyped, bytes, &temp);
    if(jove_errno) return NULL;

    KernelObjectUntyped *newuntyped = _jove_alloc(sizeof(KernelObjectUntyped));
    memcpy(newuntyped, &temp, sizeof(KernelObjectUntyped));

    dest->children[destmemb] = JOVE_OBJECT_TYPED(newuntyped);
    return newuntyped;
}

JoveError jove_untyped_split_inplace(
        KernelObjectUntyped *untyped,
        size_t bytes,
        KernelObjectUntyped *dest)
{
    if(jove_untyped_size(untyped) - sizeof(size_t) <= bytes) {
        return EJOVE_BADSIZE;
    }
    if(bytes < sizeof(size_t)) {
        return EJOVE_BADSIZE;;
    }

    int e = _syscall_invoke_untyped_split(untyped, bytes, dest);
    if(e) {
        return jove_error_from_kerror(e);
    }

    dest->bytes = bytes;
    dest->alignment = -1;
    untyped->bytes -= bytes;

    return EJOVE_OK;
}