00001 #include <stdlib.h> 00002 #include <stdio.h> 00003 00004 #include <internal/imoc.h> 00005 #ifdef __SPU__ 00006 #include <internal/spu/imoc_core_spu.h> 00007 #else 00008 #include <internal/ppu/imoc_core_ppu.h> 00009 #endif 00010 00011 /** 00012 * \addtogroup internal_p2p_bmalloc 00013 **/ 00014 //@{ 00015 00016 00017 /** 00018 * Pointer to first entry of linked-list. 00019 **/ 00020 moc_internal_buffer_node_t* bmalloc_first_node = 0; 00021 00022 /* 00023 * Prints out the nodes of the linked list. 00024 * 00025 * Used for debugging 00026 */ 00027 /**void bmalloc_print_nodes() 00028 { 00029 if (!bmalloc_first_node) 00030 printf("No nodes in list\n"); 00031 else 00032 { 00033 int z = 0; 00034 moc_internal_buffer_node_t* t; 00035 for (t = bmalloc_first_node; t != 0; t = t->next_node) 00036 { 00037 printf( "Node %i: offset %u - size %u - valid %i - mid %u\n", z, 00038 node_handle.status_array_base[ t->mid ].buffer_offset, 00039 node_handle.status_array_base[ t->mid ].message_size, 00040 node_handle.status_array_base[ t->mid ].flags.bits.buffer_used, 00041 t->mid ); 00042 z++; 00043 } 00044 } 00045 }**/ 00046 00047 /** 00048 * Returns the next node holding valid buffer-information coming after node start. 00049 * 00050 * During the search all invalid nodes the function stumbles across are freed and 00051 * the links are corrected. 00052 * 00053 * @param start \b in start-node of search (NULL means beginning of list) 00054 * @return next valid node 00055 **/ 00056 moc_internal_buffer_node_t* __attribute__((always_inline)) bmalloc_nextValidNode( 00057 moc_internal_buffer_node_t* start) 00058 { 00059 moc_internal_buffer_node_t* currentNode = 0; 00060 uint8_t unusedNodes = 0; 00061 if (start) 00062 currentNode = start->next_node; 00063 else 00064 currentNode = bmalloc_first_node; 00065 /* skip and free unused nodes of linked list */ 00066 while (currentNode 00067 && !node_handle.status_array_base[currentNode->mid].flags.bits.buffer_used) 00068 { 00069 moc_internal_buffer_node_t* temp = currentNode; 00070 unusedNodes = 1; 00071 currentNode = currentNode->next_node; 00072 free(temp); 00073 } 00074 /* when nodes have been freed then correct links of linked-list */ 00075 if (unusedNodes) 00076 { 00077 if (start) 00078 start->next_node = currentNode; 00079 else 00080 bmalloc_first_node = currentNode; 00081 } 00082 return currentNode; 00083 } 00084 00085 uint64_t IMOC_bmalloc(uint32_t size, uint8_t mid) 00086 { 00087 int temp; 00088 moc_internal_buffer_node_t* lower_node = 0; 00089 moc_internal_buffer_node_t* upper_node = bmalloc_nextValidNode(0); 00090 uint64_t lower_bound = 0, upper_bound = 0; 00091 00092 if (upper_node) 00093 upper_bound 00094 = node_handle.status_array_base[upper_node->mid].buffer_offset; 00095 else 00096 upper_bound = node_handle.buffer_size; 00097 00098 while (1) 00099 { 00100 temp = 16 - (lower_bound % 16); 00101 if (temp < 16) 00102 lower_bound += temp; 00103 if (upper_bound > lower_bound && (upper_bound - lower_bound) >= size) 00104 { 00105 moc_internal_buffer_node_t* temp = malloc( 00106 sizeof(moc_internal_buffer_node_t)); 00107 node_handle.status_array_base[mid].flags.bits.buffer_used = 1; 00108 node_handle.status_array_base[mid].buffer_offset = lower_bound; 00109 node_handle.status_array_base[mid].message_size = size; 00110 temp->mid = mid; 00111 temp->next_node = upper_node; 00112 if (lower_node) 00113 lower_node->next_node = temp; 00114 else 00115 bmalloc_first_node = temp; 00116 while (upper_node) 00117 upper_node = bmalloc_nextValidNode(upper_node); 00118 return (uint64_t) node_handle.buffer_base + lower_bound; 00119 } 00120 else 00121 { 00122 if (!upper_node) 00123 return 0; 00124 lower_node = upper_node; 00125 upper_node = bmalloc_nextValidNode(upper_node); 00126 00127 lower_bound 00128 = upper_bound 00129 + node_handle.status_array_base[lower_node->mid].message_size; 00130 if (upper_node) 00131 upper_bound 00132 = node_handle.status_array_base[upper_node->mid].buffer_offset; 00133 else 00134 upper_bound = node_handle.buffer_size; 00135 } 00136 } 00137 } 00138 00139 //@}
1.5.6