1 
2 #ifdef HAVE_CONFIG_H
3 #include <config.h>
4 #endif
5 
6 #include <schroedinger/schroutils.h>
7 #include <schroedinger/schrodomain.h>
8 #include <schroedinger/schrodebug.h>
9 #include <stdlib.h>
10 
11 //#define MEM_DOMAIN_ALWAYS_FREE 1
12 
13 /* SchroMemoryDomain */
14 
15 SchroMemoryDomain *
schro_memory_domain_new(void)16 schro_memory_domain_new (void)
17 {
18   SchroMemoryDomain *domain;
19 
20   domain = schro_malloc0 (sizeof (SchroMemoryDomain));
21 
22   domain->mutex = schro_mutex_new ();
23 
24   return domain;
25 }
26 
27 SchroMemoryDomain *
schro_memory_domain_new_local(void)28 schro_memory_domain_new_local (void)
29 {
30   SchroMemoryDomain *domain;
31 
32   domain = schro_memory_domain_new ();
33 
34   domain->alloc = (void *) malloc;
35   domain->free = (void *) free;
36   domain->flags = SCHRO_MEMORY_DOMAIN_CPU;
37 
38   return domain;
39 }
40 
41 void
schro_memory_domain_free(SchroMemoryDomain * domain)42 schro_memory_domain_free (SchroMemoryDomain * domain)
43 {
44   int i;
45 
46   SCHRO_ASSERT (domain != NULL);
47 
48   for (i = 0; i < SCHRO_MEMORY_DOMAIN_SLOTS; i++) {
49     if (domain->slots[i].flags & SCHRO_MEMORY_DOMAIN_SLOT_ALLOCATED) {
50       domain->free (domain->slots[i].ptr, domain->slots[i].size);
51     }
52   }
53 
54   schro_mutex_free (domain->mutex);
55 
56   schro_free (domain);
57 }
58 
59 void *
schro_memory_domain_alloc(SchroMemoryDomain * domain,int size)60 schro_memory_domain_alloc (SchroMemoryDomain * domain, int size)
61 {
62   int i;
63   void *ptr;
64 
65   SCHRO_ASSERT (domain != NULL);
66 
67   SCHRO_DEBUG ("alloc %d", size);
68 
69   schro_mutex_lock (domain->mutex);
70   for (i = 0; i < SCHRO_MEMORY_DOMAIN_SLOTS; i++) {
71     if (!(domain->slots[i].flags & SCHRO_MEMORY_DOMAIN_SLOT_ALLOCATED)) {
72       continue;
73     }
74     if (domain->slots[i].flags & SCHRO_MEMORY_DOMAIN_SLOT_IN_USE) {
75       continue;
76     }
77     if (domain->slots[i].size == size) {
78       domain->slots[i].flags |= SCHRO_MEMORY_DOMAIN_SLOT_IN_USE;
79       SCHRO_DEBUG ("got %p", domain->slots[i].ptr);
80       ptr = domain->slots[i].ptr;
81       goto done;
82     }
83   }
84 
85   for (i = 0; i < SCHRO_MEMORY_DOMAIN_SLOTS; i++) {
86     if (domain->slots[i].flags & SCHRO_MEMORY_DOMAIN_SLOT_ALLOCATED) {
87       continue;
88     }
89 
90     domain->slots[i].flags |= SCHRO_MEMORY_DOMAIN_SLOT_ALLOCATED;
91     domain->slots[i].flags |= SCHRO_MEMORY_DOMAIN_SLOT_IN_USE;
92     domain->slots[i].size = size;
93     domain->slots[i].ptr = domain->alloc (size);
94 
95     SCHRO_DEBUG ("created %p", domain->slots[i].ptr);
96     ptr = domain->slots[i].ptr;
97     goto done;
98   }
99 
100   SCHRO_ASSERT (0);
101 done:
102   schro_mutex_unlock (domain->mutex);
103   return ptr;
104 }
105 
106 void
schro_memory_domain_memfree(SchroMemoryDomain * domain,void * ptr)107 schro_memory_domain_memfree (SchroMemoryDomain * domain, void *ptr)
108 {
109   int i;
110 
111   SCHRO_ASSERT (domain != NULL);
112 
113   SCHRO_DEBUG ("free %p", ptr);
114 
115   schro_mutex_lock (domain->mutex);
116   for (i = 0; i < SCHRO_MEMORY_DOMAIN_SLOTS; i++) {
117     if (!(domain->slots[i].flags & SCHRO_MEMORY_DOMAIN_SLOT_ALLOCATED)) {
118       continue;
119     }
120     if (!(domain->slots[i].flags & SCHRO_MEMORY_DOMAIN_SLOT_IN_USE)) {
121       continue;
122     }
123     if (domain->slots[i].ptr == ptr) {
124 #ifdef MEM_DOMAIN_ALWAYS_FREE
125       domain->free (domain->slots[i].ptr, domain->slots[i].size);
126       domain->slots[i].flags = 0;
127 #else
128       domain->slots[i].flags &= (~SCHRO_MEMORY_DOMAIN_SLOT_IN_USE);
129 #endif
130       schro_mutex_unlock (domain->mutex);
131       return;
132     }
133   }
134   schro_mutex_unlock (domain->mutex);
135 
136   SCHRO_ASSERT (0);
137 }
138