Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4973 right-hear 1
#include 
2
#include 
3
#include 
4
 
5
static void * ___brk_addr = 0;
6
extern char end[];
7
static unsigned long min_brk,max_brk,cur_brk;
8
extern unsigned long __menuet__memsize;
9
static void* cur_dynamic_area;
10
static unsigned cur_total_size;
11
 
12
static inline void heap_init(void)
13
{
14
	__asm__("int $0x40" :: "a"(68),"b"(11));
15
}
16
 
17
static inline void* heap_alloc(unsigned size)
18
{
19
	void* res;
20
	__asm__("int $0x40" : "=a"(res) : "a"(68),"b"(12),"c"(size));
21
	return res;
22
}
23
 
24
static inline void heap_free(void* ptr)
25
{
26
	__asm__("int $0x40" :: "a"(68),"b"(13),"c"(ptr));
27
}
28
 
29
void init_brk(void)
30
{
31
 cur_brk=min_brk=(((unsigned long)&end)+0xfff)&~0xfff;
32
 max_brk=(__menuet__memsize-32768)&~0xfff;
33
 ___brk_addr=(void *)min_brk;
34
 cur_dynamic_area = NULL;
35
 cur_total_size = max_brk;
36
 heap_init();
37
}
38
 
39
/*static int sys_brk(unsigned long end_data_seg)
40
{
41
 if(!end_data_seg) return cur_brk;
42
 if (end_data_seg >= min_brk &&
43
     end_data_seg < max_brk)
44
  cur_brk = end_data_seg;
45
 return cur_brk;
46
}*/
47
 
48
/*int brk(void *_heaptop)
49
{
50
 return sys_brk((unsigned long)_heaptop);
51
}
52
 
53
static int __init_brk (void)
54
{
55
 if (___brk_addr == 0)
56
 {
57
  ___brk_addr=(void *)sys_brk(0);
58
  if (___brk_addr == 0)
59
  {
60
   errno = ENOMEM;
61
   return -1;
62
  }
63
 }
64
 return 0;
65
}*/
66
 
67
void * sbrk(int increment)
68
{
69
/* if (__init_brk () == 0)
70
 {
71
  void * tmp = ___brk_addr+increment;
72
  ___brk_addr=(void *)sys_brk((unsigned long)tmp);
73
  if (___brk_addr == tmp) return tmp-increment;
74
  errno = ENOMEM;
75
  return ((void *) -1);
76
 }
77
 return ((void *) -1);*/
78
	void* res;
79
	unsigned long tmp;
80
	if (increment <= 0)
81
	{
82
		/* release memory */
83
		while (cur_dynamic_area && increment)
84
		{
85
			tmp = cur_brk - (unsigned long)cur_dynamic_area -
86
				3*sizeof(void*);
87
			if (tmp > increment)
88
				tmp = increment;
89
			cur_brk -= tmp;
90
			increment -= tmp;
91
			if (cur_brk == (unsigned long)cur_dynamic_area + 3*sizeof(void*))
92
			{
93
				cur_brk = (unsigned long)((void**)cur_dynamic_area)[1];
94
				max_brk = (unsigned long)((void**)cur_dynamic_area)[2];
95
				res = cur_dynamic_area;
96
				cur_dynamic_area = ((void**)cur_dynamic_area)[0];
97
				heap_free(res);
98
			}
99
		}
100
		if (!cur_dynamic_area)
101
		{
102
			cur_brk += increment;
103
			if (cur_brk < min_brk)
104
				cur_brk = min_brk;
105
		}
106
		return (void*)cur_brk;
107
	}
108
	/* allocate memory */
109
	if (cur_brk + increment <= max_brk)
110
	{
111
		/* We have memory in current block, so use it */
112
		res = (void*)cur_brk;
113
		cur_brk += increment;
114
		return res;
115
	}
116
	tmp = 65536;
117
	/* We do not have memory in current block, so allocate new one */
118
	if (increment > 65536 - 3*sizeof(void*))
119
		tmp = (increment + 3*sizeof(void*) + 0xFFF) & ~0xFFF;
120
	res = heap_alloc(tmp);
121
	if (!res)
122
	{
123
		errno = ENOMEM;
124
		return (void*)-1;
125
	}
126
	((void**)res)[0] = cur_dynamic_area;
127
	((void**)res)[1] = (void*)cur_brk;
128
	((void**)res)[2] = (void*)max_brk;
129
	cur_dynamic_area = res;
130
	cur_brk = (unsigned long)res + 3*sizeof(void*);
131
	max_brk = (unsigned long)res + tmp;
132
	res = (void*)cur_brk;
133
	cur_brk += increment;
134
	return (void*)res;
135
}