Complete.Org:
Mailing Lists:
Archives:
freeciv-dev:
July 1999: Re: [Freeciv-Dev] Server hangs on an Alpha |
Re: [Freeciv-Dev] Server hangs on an Alpha[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Nicolas Brunel [brunel@xxxxxxxxxxxxxxxxxxxx] said: > > I changed the myrand(int size) to myrand(RANDOM_TYPE size) and > > recompiled. The problem was still present. I then changed the > > RANDOM_TYPE typedef from "unsigned int" to "unsigned long int" and the > > now the server doesn't hang anymore. > > It fixs this problem. But, it creates a cast from long int to int in lots > of place. And casts can create problems... Okay I decided against that fix for the reasons you state above. So I did the following instead: 1) Changed line 55 of shared.h and line 314 of shared.c from: RANDOM_TYPE myrand(int size) to RANDOM_TYPE myrand(RANDOM_TYPE size) By the way RANDOM_TYPE is typedef'ed to "unsigned int". 2) On lines 1141 to 1145 of mapgen.c I changed: riverbuck = -myrand(totalmass); mountbuck = -myrand(totalmass); desertbuck = -myrand(totalmass); forestbuck = -myrand(totalmass); swampbuck = -myrand(totalmass); to riverbuck = -(long int)myrand(totalmass); mountbuck = -(long int)myrand(totalmass); desertbuck = -(long int)myrand(totalmass); forestbuck = -(long int)myrand(totalmass); swampbuck = -(long int)myrand(totalmass); It seems to me that the above cast shouldn't be required, but w/o the cast it seems like compiler just skips those lines of code b/c they never get executed. With the cast everything seems to work okay. However I was not able to reproduce the behavior with a small example :/ In another email you mentioned that placing an "assert(size > 0);" in myrand() caused everything to break (ie for generators 1 to 4). The reason is quite simple. In the current source tree myrand() takes an int, but on line 687 of mapgen.c we see the following code: map.seed = (myrand(MAX_UINT32) ^ time(NULL)) & (MAX_UINT32 >> 1); MAX_UINT32 is typecast to a signed int and thus becomes -1. That is why the assert fails. I poked around for a while, but that seemed to be the only time I could get to trigger the assert(size > 0). However that should no longer be a problem b/c I changed myrand() as I said above. I have attached 3 patches, they are all against FreeCiv 1.8.1. They are all pretty small and do exactly what I stated above. (I realize I should have made these against CVS and probably made them into one patch, but it is all pretty simple). > > I haven't had a chance to make > > sure it is "working" correctly, but it no longer hangs. > > That's already a good point. I played around and stepped through the source, played w/ the game and it seems that everything is working okay. > > (BTW both of my changes together should have counteracted the two > > problems you noted above). > > To be really sure, we have to parse mapgen.c. In all places a cast is done > from long int to int, we have to check the long int is no greater or > lesser to an int. If we can wipe out those long int it will be safer. There seems to be a lot of long ints used. Sometimes I wonder why. I don't know the source well enough to know if it is required in some locations. But there is a comment at line 1121 of mapgen.c that says this: static long int tilefactor, balance, lastplaced;/* int may be only 2 byte ! */ So that makes me wonder. Are longs just used b/c you want FreeCiv to run on machines that have 2 byte ints? > No time to do it tonigh, I'd be happy to do it if you would like.
shared.h.patch
shared.c.patch
mapgen.c.patch
|