forked from skaphan/stmmap
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstmalloc.c
80 lines (58 loc) · 2.41 KB
/
stmalloc.c
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
/*
stmalloc.c
This is the implementation of an optional memory allocator for shared memory segments that
works under stmmap, a Software Transactional Memory system. It need not be used, but if you don't
want to write your own allocator, it might help.
Copyright 2009 Shel Kaphan
This file is part of stmmap.
stmmap is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
stmmap is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with stmmap. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include "stm.h"
#include "segalloc.h"
#include "stmalloc.h"
void stm_alloc_init(struct shared_segment *seg, int mode) {
stm_start_transaction("alloc.init");
stm_set_free_list_addr(seg, seg_alloc_init(stm_segment_base(seg), stm_segment_size(seg), mode));
stm_commit_transaction("alloc.init");
}
void stm_free(void *va) {
struct shared_segment *seg;
size_t size;
stm_start_transaction("alloc.free");
seg = stm_find_shared_segment(va);
if (seg) {
size = *(((size_t*)va)-1);
seg_free(va - sizeof(size_t), size, stm_segment_base(seg), stm_free_list_addr(seg));
}
stm_commit_transaction("alloc.free");
}
void *stm_alloc(struct shared_segment *seg, size_t size) {
void *result;
size_t real_size = seg_block_size_for(size + sizeof(size_t));
stm_start_transaction("alloc.new");
result = seg_alloc(real_size, stm_free_list_addr(seg));
if (result) {
*(size_t*)result = real_size;
}
stm_commit_transaction("alloc.new");
if (result == NULL) {
fprintf(stderr, "Failed to allocate size %ld\n", size);
return NULL;
}
return result + sizeof(size_t);
}
// This apparently trivial function causes the offset_ptr which is the free list
// to be converted into a regular pointer for regular programs to work with.
struct segalloc_node *stm_free_list(struct shared_segment *seg) {
return seg_free_list_from_free_list_addr(stm_free_list_addr(seg));
}