mt_realloc.c
3.29 KB
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
/*
=============================================================================
Copyright (C) 1997-1999 NINTENDO Co.,Ltd.
$RCSfile: mt_realloc.c,v $
$Revision: 1.1.1.1 $
$Date: 2002/10/30 02:07:09 $
=============================================================================
関数名:mt_realloc
-----------------------------------------------------------------------------
書式: #include <malloc.h>
void *mt_realloc(void *ptr, int size);
説明: マルチスレッド対応の realloc()。
引数や戻り値、その他の説明については、realloc() と同じなので、
そちらの説明を参照すること。
-----------------------------------------------------------------------------
*/
#include <ultra64.h>
#include "string.h"
#include "malloc.h"
#include "_malloc.h"
void *mt_realloc(void *ptr, int size)
{
unsigned int *next2;
unsigned int size2;
unsigned char *p2;
struct mallocST *malloc_st_ptr ;
OSIntMask svintmask ;
void *ret ;
if( (int)malloc_ptr == -1 ){
return NULL;
}
svintmask = osSetIntMask( OS_IM_NONE ) ; /* 全ての割り込みを不許可 */
if( !ptr ){
ret = _malloc( malloc_ptr, size ); /* 新規にメモリ確保 */
osSetIntMask( svintmask ) ; /* 割り込みマスクを復帰 */
return ret ;
}
if( !size ){ /* 現在のメモリを開放 */
_free(malloc_ptr, ptr);
osSetIntMask( svintmask ) ; /* 割り込みマスクを復帰 */
return NULL;
}
size += 15;
size &= (~15);
p2 = (unsigned char *)ptr - MALLOC_HEADSIZE;
malloc_st_ptr = (struct mallocST *)p2;
if( !malloc_st_ptr->flag ){
osSetIntMask( svintmask ) ; /* 割り込みマスクを復帰 */
return NULL;
}
next2 = malloc_st_ptr->next;
size2 = malloc_st_ptr->size;
malloc_st_ptr = (struct mallocST *)next2;
if (next2 && !malloc_st_ptr->flag) {
size2 += malloc_st_ptr->size + MALLOC_HEADSIZE;
next2 = (unsigned int *)malloc_st_ptr->next;
}
malloc_st_ptr = (struct mallocST *)p2;
if( size > size2 ){
/* 現在のポインタの位置からでは指定サイズ確保が出来ない。 */
p2 = (unsigned char *)_malloc(malloc_ptr, size);
if( p2 == NULL ){
osSetIntMask( svintmask ) ; /* 割り込みマスクを復帰 */
return NULL;
}
_nmemcpy(p2, ptr, size);
_free(malloc_ptr, ptr);
osSetIntMask( svintmask ) ; /* 割り込みマスクを復帰 */
return p2;
}else{
/* 今のポインタを継承したままサイズを変更する。*/
if( (size + MALLOC_HEADSIZE + 16) < size2 ){
/* ブロックを再分割する必要がある場合 */
/*
malloc_st_ptr->next
= (unsigned int *)((unsigned int)ptr + size + MALLOC_HEADSIZE);
*/
malloc_st_ptr->next
= (unsigned int *)((unsigned int)ptr + size) ;
malloc_st_ptr->size = size;
malloc_st_ptr = (struct mallocST *)malloc_st_ptr->next;
malloc_st_ptr->next = next2;
malloc_st_ptr->size = size2 - size - MALLOC_HEADSIZE;
malloc_st_ptr->flag = 0;
}else{
/* ブロックを再分割する必要がない場合 (ブロックのサイズが
確保しようとしているサイズと同じ大きさだった場合) */
malloc_st_ptr->next = next2;
malloc_st_ptr->size = size2;
}
osSetIntMask( svintmask ) ; /* 割り込みマスクを復帰 */
return ptr;
}
}