The R Project SVN R

Rev

Rev 11007 | Rev 11100 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 11007 Rev 11091
Line 993... Line 993...
993
{
993
{
994
    MEMORY_BASIC_INFORMATION info;
994
    MEMORY_BASIC_INFORMATION info;
995
    while ((unsigned long)start_address < TOP_MEMORY)
995
    while ((unsigned long)start_address < TOP_MEMORY)
996
    {
996
    {
997
	VirtualQuery (start_address, &info, sizeof (info));
997
	VirtualQuery (start_address, &info, sizeof (info));
998
	if (info.State != MEM_FREE)
-
 
999
	    start_address = (char*)info.BaseAddress + info.RegionSize;
-
 
1000
	else if (info.RegionSize >= size)
998
	if (info.State == MEM_FREE && info.RegionSize >= size)
1001
	    return start_address;
999
	    return start_address;
1002
	else {
1000
	else {
1003
/*	    Requested region is not available so see if the
1001
/*	    Requested region is not available or not big enough 
1004
	    next region is available.  Set 'start_address'
1002
	    so see if the next region is available.  Set 'start_address'
1005
	    to the next region and call 'VirtualQuery()' again. */
1003
	    to the next region and call 'VirtualQuery()' again. */
1006
 
1004
 
1007
	    start_address = (char*)info.BaseAddress + info.RegionSize;
1005
	    start_address = (char*)info.BaseAddress + info.RegionSize;
1008
	    
1006
	    
1009
/*	    Make sure we start looking for the next region
1007
/*	    Make sure we start looking for the next region
Line 1023... Line 1021...
1023
	}
1021
	}
1024
    }
1022
    }
1025
    return NULL;
1023
    return NULL;
1026
}
1024
}
1027
 
1025
 
1028
 
-
 
-
 
1026
/* BDR 2000-10-28: add loop count as this infinitely looped */
1029
void *wsbrk (long size)
1027
void *wsbrk (long size)
1030
{
1028
{
1031
    void *tmp;
1029
    void *tmp;
-
 
1030
    int count = 0;
1032
    if (PageSize == 0) PageSize = getpagesize();
1031
    if (PageSize == 0) PageSize = getpagesize();
1033
 
1032
 
1034
    if (size > 0) {
1033
    if (size > 0) {
1035
	/* will this take us over the limit? */
1034
	/* will this take us over the limit? */
1036
	if (totalAllocated + size > R_max_memory) 
1035
	if (totalAllocated + size > R_max_memory) 
1037
	    return (void*)-1;
1036
	    return (void*)-1;
1038
 
1037
 
1039
	/* first check if request fits in reserved space, and if not
1038
	/* first check if request fits in reserved space, and if not
1040
	   try to reserve the address space (never unreserved) */
1039
	   try to reserve the address space (never unreserved) */
1041
	if (gAddressBase == 0) {
1040
	if (gAddressBase == 0) {
1042
	    gReservedSize = max (RESERVED_SIZE, AlignPage (size));
1041
	    gReservedSize = max (RESERVED_SIZE, AlignPage64K(size));
1043
	    gNextAddress = gAddressBase =
1042
	    gNextAddress = gAddressBase =
1044
		(unsigned int)VirtualAlloc (NULL, gReservedSize,
1043
		(unsigned int)VirtualAlloc (NULL, gReservedSize,
1045
					    MEM_RESERVE, PAGE_NOACCESS);
1044
					    MEM_RESERVE, PAGE_NOACCESS);
1046
	    if(!gAddressBase)
1045
	    if(!gAddressBase)
1047
		R_Suicide("unable to reserve initial space in wsbrk");
1046
		R_Suicide("unable to reserve initial space in wsbrk");
1048
	} else if (AlignPage (gNextAddress + size) > (gAddressBase +
1047
	} else if (AlignPage (gNextAddress + size) > (gAddressBase +
1049
						      gReservedSize)) {
1048
						      gReservedSize)) {
1050
	    long new_size = max (NEXT_SIZE, AlignPage(size));
1049
	    long new_size = max (NEXT_SIZE, AlignPage64K(size));
1051
	    void *new_address = (void*)(gAddressBase+gReservedSize);
1050
	    void *new_address = (void*)(gAddressBase+gReservedSize);
1052
	    do {
1051
	    do {
-
 
1052
		/* if we failed twice, try somewhat desparately */
-
 
1053
		if (count >= 2) 
-
 
1054
		    new_address = (void *)((unsigned int) new_address + new_size + NEXT_SIZE);
1053
		new_address = findRegion (new_address, new_size);
1055
		new_address = findRegion (new_address, new_size);
1054
		if (new_address == 0) return (void *) -1;
1056
		if (new_address == 0) return (void *) -1;
1055
		gNextAddress =
1057
		gNextAddress =
1056
		    (unsigned int)VirtualAlloc (new_address, new_size,
1058
		    (unsigned int)VirtualAlloc (new_address, new_size,
1057
						MEM_RESERVE, PAGE_NOACCESS);
1059
						MEM_RESERVE, PAGE_NOACCESS);
1058
				/* repeat in case of race condition
1060
				/* repeat in case of race condition
1059
				  The region that we found has been grabbed
1061
				  The region that we found has been grabbed
1060
				  by another thread */
1062
				  by another thread */
1061
	    } while (gNextAddress == 0);
1063
	    } while (gNextAddress == 0 && count++ < 10);
-
 
1064
	    if (gNextAddress == 0) return (void *) -1;
1062
 
1065
 
1063
	    if (new_address != (void*)gNextAddress)
1066
	    if (new_address != (void*)gNextAddress)
1064
		R_Suicide("internal error in wsbrk");
1067
		R_Suicide("internal error in wsbrk");
1065
 
1068
 
1066
	    if (gNextAddress == gAddressBase +gReservedSize) {
1069
	    if (gNextAddress == gAddressBase + gReservedSize) {
1067
		/* allocated a contiguous block */
1070
		/* allocated a contiguous block */
1068
		gReservedSize += new_size;
1071
		gReservedSize += new_size;
1069
	    } else {
1072
	    } else {
1070
		gAddressBase = gNextAddress;
1073
		gAddressBase = gNextAddress;
1071
		gReservedSize = new_size;
1074
		gReservedSize = new_size;