Guest User

Untitled

a guest
Aug 16th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.68 KB | None | 0 0
  1. //////////////////////////////////////////////////////////////////////
  2. //mm.h////////////////////////////////////////////////////////////////
  3. //////////////////////////////////////////////////////////////////////
  4. #ifndef _MM_H_
  5. #define _MM_H_
  6.  
  7. #define HNODE_USED 1
  8. #define HNODE_UNUSED 0
  9.  
  10. typedef struct _hnode
  11. {
  12. u64 address;
  13. u32 used;
  14. u32 size;
  15. struct _hnode *prev;
  16. struct _hnode *next;
  17. } __attribute__((packed)) hnode_t;
  18.  
  19. typedef struct _heap
  20. {
  21. u64 start;
  22. u64 size;
  23. u32 usedmem;
  24. hnode_t *first;
  25. } __attribute__((packed)) heap_t;
  26.  
  27. //Initialize rsx heap.
  28. s32 rsxHeapInit();
  29. //Allocate from rsx heap.
  30. void *rsxAlloc(u32 size);
  31. //Free allocated rsx memory.
  32. void rsxFree(void *ptr)
  33.  
  34. #endif
  35.  
  36. //////////////////////////////////////////////////////////////////////
  37. //mm.c////////////////////////////////////////////////////////////////
  38. //////////////////////////////////////////////////////////////////////
  39. #include <malloc.h>
  40.  
  41. #include "rsx/reality.h"
  42. #include "mm.h"
  43.  
  44. static u32 initialized = 0;
  45. static gcmConfiguration config;
  46. static u64 rsx_heap_ptr;
  47. static heap_t *rsx_heap;
  48.  
  49. //Collect unused nodes and merge them to bigger ones.
  50. static void _rsxHeapCollect()
  51. {
  52. hnode_t *node = rsx_heap->first;
  53.  
  54. //Iterate over all nodes.
  55. while(node != NULL)
  56. {
  57. //If we find an unused node ...
  58. if(node->used == HNODE_UNUSED)
  59. //... and if the previous node is also unused ...
  60. if(node->prev != NULL && node->prev->used == HNODE_UNUSED)
  61. {
  62. //... merge them.
  63. node->prev->size += node->size;
  64. node->prev->next = node->next;
  65. if(node->next != NULL)
  66. node->next->prev = node->prev;
  67. //Free node.
  68. free(node);
  69. }
  70. node = node->next;
  71. }
  72. }
  73.  
  74. s32 rsxHeapInit()
  75. {
  76. if(initialized == 0)
  77. {
  78. //Get config.
  79. gcmGetConfiguration(&config);
  80. //Setup heap.
  81. rsx_heap_ptr = (u64)config.localAddress;
  82. //Allocate base heap.
  83. if((rsx_heap = (heap_t *)malloc(sizeof(heap_t))) == NULL)
  84. return 0;
  85. //Start address and size.
  86. rsx_heap->start = rsx_heap_ptr;
  87. rsx_heap->size = config.localSize;
  88. //No memory used.
  89. rsx_heap->usedmem = 0;
  90. rsx_heap->first = NULL;
  91. //And done.
  92. initialized = 1;
  93. }
  94.  
  95. return 1;
  96. }
  97.  
  98. void *rsxAlloc(u32 size, u32 align)
  99. {
  100. hnode_t *node, *new;
  101. u32 search = 1;
  102.  
  103. if(initialized == 0)
  104. return NULL;
  105.  
  106. //First node?
  107. if(rsx_heap->first == NULL)
  108. {
  109. if(size > heap->size)
  110. return NULL;
  111. //Allocate new node.
  112. if((node = (hnode_t *)malloc(sizeof(hnode_t))) == NULL)
  113. return NULL;
  114.  
  115. node->address = rsx_heap->start;
  116. node->used = HNODE_USED;
  117. node->size = size;
  118. node->prev = NULL;
  119. node->next = NULL;
  120. rsx_heap->first = node;
  121. rsx_heap->usedmem = size;
  122.  
  123. return (void *)node->address;
  124. }
  125.  
  126. node = rsx_heap->first;
  127. while(search == 1)
  128. {
  129. //unused node?
  130. if(node->used == HNODE_UNUSED)
  131. {
  132. //20% bigger is acceptable.
  133. if(size <= node->size && node->size <= (size + node->size / 5))
  134. {
  135. node->used = HNODE_USED;
  136. rsx_heap->usedmem += node->size;
  137. return (void *)node->address;
  138. }
  139. else if(size < node->size) //Insert new node.
  140. {
  141. //Allocate new node.
  142. if((new = (hnode_t *)malloc(sizeof(hnode_t))) == NULL)
  143. return NULL;
  144.  
  145. //The new node follwes the ucrrent one.
  146. new->size = node->size - size;
  147. new->used = HNODE_UNUSED;
  148. new->address = node->address + size;
  149. //Insert into list.
  150. new->next = node->next;
  151. new->priv = node;
  152. node->size = size;
  153. node->used = HNODE_UNSED;
  154. //The next one is the new node.
  155. node->next = new;
  156.  
  157. rsx_heap->usemem += size;
  158. return (void *)node->address;
  159. }
  160. }
  161. if(node->next != NULL)
  162. node = node->next;
  163. else
  164. search = 0;
  165. }
  166.  
  167. //Add new node at the end.
  168. //Enough memory available to create a new node?
  169. if(heap->usedmem + size > heap->size)
  170. return NULL;
  171. //Allocate new node.
  172. if((new = (hnode_t *)malloc(sizeof(hnode_t))) == NULL)
  173. return NULL;
  174.  
  175. new->used = HNODE_USED;
  176. new->size = size;
  177. new->address = node->address + node->size;
  178. new->prev = node;
  179. new->next = NULL;
  180. node->next = new;
  181.  
  182. rsx_heap->usedmem += size;
  183. return (void *)new->address;
  184. }
  185.  
  186. void rsxFree(void *ptr)
  187. {
  188. u64 addr = (u64)ptr;
  189.  
  190. //Some basic error checking.
  191. if(initialized == 0)
  192. return;
  193. if(addr == 0 ||
  194. addr < (heap->start) ||
  195. addr > (heap->start + heap->size)
  196. )
  197. return;
  198.  
  199. hnode_t *node = rsx_heap->first;
  200.  
  201. //Find the correspondending node.
  202. while(node != NULL)
  203. {
  204. if(node->address == addr)
  205. {
  206. //Set it to unused.
  207. node->used = HNODE_UNUSED;
  208. //Update allocated size.
  209. rsx_heap->size -= node->size;
  210. return;
  211. }
  212. node = node->next;
  213. }
  214.  
  215. //Collect nodes.
  216. _rsxHeapCollect();
  217. }
Add Comment
Please, Sign In to add comment