/*********************************************************************** * function is called at program start * you can put your own initialization jobs there ***********************************************************************/ static UInt16 StartApplication(void) { Err err = 0; // Initialize the random number seed; SysRandom( TimGetSeconds() ); // Load prefs PrefLoadPrefs(&gPrefs); // Initialize TNglue err = TNGlueColorInit(); // Initialize Cache CacheInit(); // Open Database if (err == errNone) err = OpenDatabase(); if (err == errNone) DatabaseSetCat(gPrefs.curCat); // Set Alarms if (err == errNone) AlarmReset(DatabaseGetRefN(DB_MAIN)); return (err); }
float GetNumVerticesLoadedTriList ( WORD *pwList, int iHowManyTris ) { // What's the top index? WORD wHighest = 0; int i; for ( i = 0; i < iHowManyTris * 3; i++ ) { if ( wHighest < pwList[i] ) { wHighest = pwList[i]; } } CacheInit ( wHighest + 1 ); // Let's find the current score of this list. float fScore = 0.0f; WORD *pwCurTri = pwList; for ( i = 0; i < iHowManyTris; i++ ) { fScore += CacheAddTri ( pwCurTri[0], pwCurTri[1], pwCurTri[2] ); pwCurTri += 3; } CacheBin(); return fScore; }
long Ext2InitPartition(CICell ih) { long cnt, gdPerBlock; if (ih == gCurrentIH) return 0; printf("Ext2InitPartition: %x\n", ih); gCurrentIH = 0; // Read for the Super Block. Seek(ih, SBOFF); Read(ih, (long)gFSBuf, SBSIZE); gFS = (struct m_ext2fs *)gFSBuf; e2fs_sb_bswap(&gFS->e2fs, &gFS->e2fs); if (gFS->e2fs.e2fs_magic != E2FS_MAGIC) return -1; // Calculate the block size and set up the block cache. gBlockSize = 1024 << gFS->e2fs.e2fs_log_bsize; if (gBlockSizeOld <= gBlockSize) { gTempBlock = AllocateBootXMemory(gBlockSize); } CacheInit(ih, gBlockSize); gBlockSizeOld = gBlockSize; gCurrentIH = ih; gdPerBlock = gBlockSize / sizeof(struct ext2_gd); // Fill in the in memory super block fields. gFS->e2fs_bsize = 1024 << gFS->e2fs.e2fs_log_bsize; gFS->e2fs_bshift = LOG_MINBSIZE + gFS->e2fs.e2fs_log_bsize; gFS->e2fs_qbmask = gFS->e2fs_bsize - 1; gFS->e2fs_bmask = ~gFS->e2fs_qbmask; gFS->e2fs_fsbtodb = gFS->e2fs.e2fs_log_bsize + 1; gFS->e2fs_ncg = HowMany(gFS->e2fs.e2fs_bcount - gFS->e2fs.e2fs_first_dblock, gFS->e2fs.e2fs_bpg); gFS->e2fs_ngdb = HowMany(gFS->e2fs_ncg, gdPerBlock); gFS->e2fs_ipb = gFS->e2fs_bsize / EXT2_DINODE_SIZE; gFS->e2fs_itpg = gFS->e2fs.e2fs_ipg / gFS->e2fs_ipb; gFS->e2fs_gd = AllocateBootXMemory(gFS->e2fs_ngdb * gFS->e2fs_bsize); // Read the summary information from disk. for (cnt = 0; cnt < gFS->e2fs_ngdb; cnt++) { ReadBlock(((gBlockSize > 1024) ? 0 : 1) + cnt + 1, 0, gBlockSize, (char *)&gFS->e2fs_gd[gdPerBlock * cnt], 0); e2fs_cg_bswap(&gFS->e2fs_gd[gdPerBlock * cnt], &gFS->e2fs_gd[gdPerBlock * cnt], gBlockSize); } // Read the Root Inode ReadInode(EXT2_ROOTINO, &gRootInode, 0, 0); return 0; }
long UFSInitPartition(CICell ih) { if (ih == gCurrentIH) return 0; printf("UFSInitPartition: %x\n", ih); gCurrentIH = 0; // Assume there is no Disk Label gPartitionBase = 0; // Look for the Super Block Seek(ih, gPartitionBase + SBOFF); Read(ih, (long)gFSBuf, SBSIZE); gFS = (struct fs *)gFSBuf; if (gFS->fs_magic != FS_MAGIC) { return -1; } // Calculate the block size and set up the block cache. gBlockSize = gFS->fs_bsize; gFragSize = gFS->fs_fsize; gFragsPerBlock = gBlockSize / gFragSize; if (gBlockSizeOld <= gBlockSize) { gTempBlock = AllocateBootXMemory(gBlockSize); } CacheInit(ih, gBlockSize); gBlockSizeOld = gBlockSize; gCurrentIH = ih; // Read the Root Inode ReadInode(ROOTINO, &gRootInode, 0, 0); return 0; }
long HFSInitPartition(CICell ih) { long extentSize, extentFile, nodeSize; void *extent; if (ih == gCurrentIH) { #ifdef __i386__ CacheInit(ih, gCacheBlockSize); #endif return 0; } #ifdef __i386__ if (!gTempStr) gTempStr = (char *)malloc(4096); if (!gLinkTemp) gLinkTemp = (char *)malloc(64); if (!gBTreeHeaderBuffer) gBTreeHeaderBuffer = (char *)malloc(512); if (!gHFSMdbVib) { gHFSMdbVib = (char *)malloc(kBlockSize); gHFSMDB = (HFSMasterDirectoryBlock *)gHFSMdbVib; } if (!gHFSPlusHeader) { gHFSPlusHeader = (char *)malloc(kBlockSize); gHFSPlus = (HFSPlusVolumeHeader *)gHFSPlusHeader; } if (!gTempStr || !gLinkTemp || !gBTreeHeaderBuffer || !gHFSMdbVib || !gHFSPlusHeader) return -1; #endif /* __i386__ */ gAllocationOffset = 0; gIsHFSPlus = 0; gCaseSensitive = 0; gBTHeaders[0] = 0; gBTHeaders[1] = 0; // Look for the HFS MDB Seek(ih, kMDBBaseOffset); Read(ih, (long)gHFSMdbVib, kBlockSize); if ( SWAP_BE16(gHFSMDB->drSigWord) == kHFSSigWord ) { gAllocationOffset = SWAP_BE16(gHFSMDB->drAlBlSt) * kBlockSize; // See if it is HFSPlus if (SWAP_BE16(gHFSMDB->drEmbedSigWord) != kHFSPlusSigWord) { // Normal HFS; gCacheBlockSize = gBlockSize = SWAP_BE32(gHFSMDB->drAlBlkSiz); CacheInit(ih, gCacheBlockSize); gCurrentIH = ih; // grab the 64 bit volume ID bcopy(&gHFSMDB->drFndrInfo[6], &gVolID, 8); // Get the Catalog BTree node size. extent = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec; extentSize = SWAP_BE32(gHFSMDB->drCTFlSize); extentFile = kHFSCatalogFileID; ReadExtent(extent, extentSize, extentFile, 0, 256, gBTreeHeaderBuffer + kBTreeCatalog * 256, 0); nodeSize = SWAP_BE16(((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 + sizeof(BTNodeDescriptor)))->nodeSize); // If the BTree node size is larger than the block size, reset the cache. if (nodeSize > gBlockSize) { gCacheBlockSize = nodeSize; CacheInit(ih, gCacheBlockSize); } return 0; } // Calculate the offset to the embeded HFSPlus volume. gAllocationOffset += (long long)SWAP_BE16(gHFSMDB->drEmbedExtent.startBlock) * SWAP_BE32(gHFSMDB->drAlBlkSiz); } // Look for the HFSPlus Header Seek(ih, gAllocationOffset + kMDBBaseOffset); Read(ih, (long)gHFSPlusHeader, kBlockSize); // Not a HFS+ or HFSX volume. if (SWAP_BE16(gHFSPlus->signature) != kHFSPlusSigWord && SWAP_BE16(gHFSPlus->signature) != kHFSXSigWord) { verbose("HFS signature was not present.\n"); gCurrentIH = 0; return -1; } gIsHFSPlus = 1; gCacheBlockSize = gBlockSize = SWAP_BE32(gHFSPlus->blockSize); CacheInit(ih, gCacheBlockSize); gCurrentIH = ih; // grab the 64 bit volume ID bcopy(&gHFSPlus->finderInfo[24], &gVolID, 8); // Get the Catalog BTree node size. extent = &gHFSPlus->catalogFile.extents; extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize); extentFile = kHFSCatalogFileID; ReadExtent(extent, extentSize, extentFile, 0, 256, gBTreeHeaderBuffer + kBTreeCatalog * 256, 0); nodeSize = SWAP_BE16(((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 + sizeof(BTNodeDescriptor)))->nodeSize); // If the BTree node size is larger than the block size, reset the cache. if (nodeSize > gBlockSize) { gCacheBlockSize = nodeSize; CacheInit(ih, gCacheBlockSize); } return 0; }
long UFSInitPartition( CICell ih ) { #if !BOOT1 long ret; #endif if (ih == gCurrentIH) { #ifdef __i386__ CacheInit(ih, gBlockSize); #endif return 0; } #if !BOOT1 verbose("UFSInitPartition: %x\n", ih); #endif gCurrentIH = 0; #ifdef __i386__ if (!gULBuf) gULBuf = (char *) malloc(UFS_LABEL_SIZE); if (!gFSBuf) gFSBuf = (char *) malloc(SBSIZE); if (!gTempName) gTempName = (char *) malloc(MAXNAMLEN + 1); if (!gTempName2) gTempName2 = (char *) malloc(MAXNAMLEN + 1); if (!gRootInodePtr) gRootInodePtr = (InodePtr) malloc(sizeof(Inode)); if (!gFileInodePtr) gFileInodePtr = (InodePtr) malloc(sizeof(Inode)); if (!gULBuf || !gFSBuf || !gTempName || !gTempName2 || !gRootInodePtr || !gFileInodePtr) return -1; #endif // Assume there is no Disk Label gPartitionBase = 0; #if !BOOT1 // read the disk label to get the UUID // (rumor has it that UFS headers can be either-endian on disk; hopefully // that isn't true for this UUID field). Seek(ih, gPartitionBase + UFS_LABEL_OFFSET); ret = Read(ih, (long)&gUFSLabel, UFS_LABEL_SIZE); if(ret != 0) bzero(&gUFSLabel, UFS_LABEL_SIZE); #endif /* !BOOT1 */ // Look for the Super Block Seek(ih, gPartitionBase + SBOFF); Read(ih, (long)gFSBuf, SBSIZE); gFS = (struct fs *)gFSBuf; byte_swap_superblock(gFS); if (gFS->fs_magic != FS_MAGIC) { return -1; } ih->modTime = gFS->fs_time; // Calculate the block size and set up the block cache. gBlockSize = gFS->fs_bsize; gFragSize = gFS->fs_fsize; gFragsPerBlock = gBlockSize / gFragSize; if (gTempBlock != 0) free(gTempBlock); gTempBlock = malloc(gBlockSize); CacheInit(ih, gBlockSize); gCurrentIH = ih; // Read the Root Inode ReadInode(ROOTINO, gRootInodePtr, 0, 0); return 0; }
// Call this to reorder the tris in this trilist to get good vertex-cache coherency. // *pwList is modified (but obviously not changed in size or memory location). void _OptimiseVertexCoherencyTriList ( WORD *pwList, int iHowManyTris, u32 optimize_mode) { if ( iHowManyTris <= 2 ) { // Silly. return; } switch (optimize_mode){ case 1: // Very cheap'n'cheerful. LOOKAHEAD = 1; iLookaheadCutoff = 4; break; case 2: // Expensive, but better. LOOKAHEAD = 5; iLookaheadCutoff = 16; break; } #ifdef _DEBUG // Find current score (probably rubbish). float fCurrentScore = GetNumVerticesLoadedTriList ( pwList, iHowManyTris ); #endif // First scan to find the biggest index. WORD *pwIndex = pwList; int iBiggestIndex = 0; int i; for ( i = 0; i < iHowManyTris * 3; i++ ) { if ( iBiggestIndex < *pwIndex ) { iBiggestIndex = *pwIndex; } pwIndex++; } #if 0 iValenceCounts.resize(iBiggestIndex+1); for ( i = 0; i <= iBiggestIndex; i++ ) { *(iValenceCounts.item(i)) = 0; } // And set up the valencies. pwIndex = pwList; for ( i = 0; i < iHowManyTris * 3; i++ ) { ++(*(iValenceCounts.item(*pwIndex))); pwIndex++; } #else svVertex.resize ( iBiggestIndex + 1 ); for ( i = 0; i <= iBiggestIndex; i++ ) { ScoreVertex *sv = svVertex.item(i); sv->iCurrentValence = 0; sv->stri.resize(0); } stTri.resize ( iHowManyTris ); pstTri.resize ( iHowManyTris ); WORD *pwCurTri = pwList; for ( i = 0; i < iHowManyTris; i++ ) { ScoreTri *pstCur = stTri.item(i); *(pstTri.item(i)) = pstCur; pstCur->bUsed = FALSE; pstCur->bAllowed = FALSE; for ( int j = 0; j < 3; j++ ) { pstCur->wIndex[j] = pwCurTri[j]; svVertex.item(pwCurTri[j])->iCurrentValence++; *(svVertex.item(pwCurTri[j])->stri.append()) = pstCur; } pwCurTri += 3; } #endif WORD *pwNewIndex = new WORD[iHowManyTris*3]; CacheInit ( iBiggestIndex + 1 ); #if 0 // If you try to optimise from the very first tri, it takes ages to find the "best" // first tri - almost none of the early-outs work, because there is no cache history, // and indeed the whole concept of a "best" first tri is madness - you have to start // somewhere. // So I just pick the first one, and let it carry on from there. Once the cache has // been "seeded" the early-outs come thick and fast and it's a decent speed. pwNewIndex[0] = pwList[0]; pwNewIndex[1] = pwList[1]; pwNewIndex[2] = pwList[2]; --(*(iValenceCounts.item(pwList[0]))); --(*(iValenceCounts.item(pwList[1]))); --(*(iValenceCounts.item(pwList[2]))); CacheAddTri ( pwList[0], pwList[1], pwList[2] ); // No need to actually increase the score - everything is relative anyway. float fTemp = FindBestScore ( iHowManyTris - 1, 0.0f, 1e10, pwList + 3, iHowManyTris - 1, pwNewIndex + 3 ); #else float fTemp = FindBestScore ( iHowManyTris, 0.0f, 1e10, (pstTri.item(0)), iHowManyTris, pwNewIndex ); #endif CacheBin(); #if 0 iValenceCounts.resize(0); #else svVertex.resize(0); stTri.resize(0); #endif #ifdef _DEBUG // Find new score (hopefully better). float fNewScore = GetNumVerticesLoadedTriList ( pwNewIndex, iHowManyTris ); fNewScore /= (float)iHowManyTris; // The verts per tri score. // And if you definately use indices 0 to iBiggestIndex (which all this code does), then this is the max possible: float fMaxPossible = iBiggestIndex / (float)iHowManyTris; #endif memcpy ( pwList, pwNewIndex, sizeof(WORD) * 3 * iHowManyTris ); delete[] pwNewIndex; }
int main(int argc, char *argv[]) { int i, oldumask; argcGlobal = argc; argvGlobal = argv; configfilename = DEFAULT_CONFIG_FILE; /* init stuff */ ProcessCmdLine(argc, argv); InitErrors(); /* * Do this first thing, to get any options that only take effect at * startup time. It is read again each time the server resets. */ if (ReadConfigFile(configfilename) != FSSuccess) { FatalError("couldn't read config file\n"); } /* make sure at least world write access is disabled */ if (((oldumask = umask(022)) & 002) == 002) (void)umask(oldumask); SetDaemonState(); SetUserId(); while (1) { serverGeneration++; OsInit(); if (serverGeneration == 1) { /* do first time init */ serverCache = CacheInit(SERVER_CACHE_SIZE); CreateSockets(OldListenCount, OldListen); InitProcVectors(); clients = (ClientPtr *) fsalloc(MAXCLIENTS * sizeof(ClientPtr)); if (!clients) FatalError("couldn't create client array\n"); for (i = MINCLIENT; i < MAXCLIENTS; i++) clients[i] = NullClient; /* make serverClient */ serverClient = (ClientPtr) fsalloc(sizeof(ClientRec)); if (!serverClient) FatalError("couldn't create server client\n"); } ResetSockets(); /* init per-cycle stuff */ InitClient(serverClient, SERVER_CLIENT, (pointer) 0); clients[SERVER_CLIENT] = serverClient; currentMaxClients = MINCLIENT; currentClient = serverClient; if (!InitClientResources(serverClient)) FatalError("couldn't init server resources\n"); InitExtensions(); InitAtoms(); InitFonts(); SetConfigValues(); if (!create_connection_block()) FatalError("couldn't create connection block\n"); #ifdef DEBUG fprintf(stderr, "Entering Dispatch loop\n"); #endif Dispatch(); #ifdef DEBUG fprintf(stderr, "Leaving Dispatch loop\n"); #endif /* clean up per-cycle stuff */ CacheReset(); CloseDownExtensions(); if ((dispatchException & DE_TERMINATE) || drone_server) break; fsfree(ConnectionInfo); /* note that we're parsing it again, for each time the server resets */ if (ReadConfigFile(configfilename) != FSSuccess) FatalError("couldn't read config file\n"); } CloseSockets(); CloseErrors(); exit(0); }
long HFSInitPartition(CICell ih) { long extentSize, extentFile, nodeSize; void *extent; if (ih == gCurrentIH) return 0; printf("HFSInitPartition: %x\n", ih); gAllocationOffset = 0; gIsHFSPlus = 0; gCaseSensitive = 0; gBTHeaders[0] = 0; gBTHeaders[1] = 0; // Look for the HFS MDB Seek(ih, kMDBBaseOffset); Read(ih, (long)gHFSMdbVib, kBlockSize); if (gHFSMDB->drSigWord == kHFSSigWord) { gAllocationOffset = gHFSMDB->drAlBlSt * kBlockSize; // See if it is HFSPlus if (gHFSMDB->drEmbedSigWord != kHFSPlusSigWord) { // Normal HFS; gBlockSize = gHFSMDB->drAlBlkSiz; CacheInit(ih, gBlockSize); gCurrentIH = ih; // Get the Catalog BTree node size. extent = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec; extentSize = gHFSMDB->drCTFlSize; extentFile = kHFSCatalogFileID; ReadExtent(extent, extentSize, extentFile, 0, 256, gBTreeHeaderBuffer + kBTreeCatalog * 256, 0); nodeSize = ((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 + sizeof(BTNodeDescriptor)))->nodeSize; // If the BTree node size is larger than the block size, reset the cache. if (nodeSize > gBlockSize) CacheInit(ih, nodeSize); return 0; } // Calculate the offset to the embeded HFSPlus volume. gAllocationOffset += (long long)gHFSMDB->drEmbedExtent.startBlock * gHFSMDB->drAlBlkSiz; } // Look for the HFSPlus Header Seek(ih, gAllocationOffset + kMDBBaseOffset); Read(ih, (long)gHFSPlusHeader, kBlockSize); // Not a HFS[+] volume. if ((gHFSPlus->signature != kHFSPlusSigWord) && (gHFSPlus->signature != kHFSXSigWord)) return -1; gIsHFSPlus = 1; gBlockSize = gHFSPlus->blockSize; CacheInit(ih, gBlockSize); gCurrentIH = ih; // Get the Catalog BTree node size. extent = &gHFSPlus->catalogFile.extents; extentSize = gHFSPlus->catalogFile.logicalSize; extentFile = kHFSCatalogFileID; ReadExtent(extent, extentSize, extentFile, 0, 256, gBTreeHeaderBuffer + kBTreeCatalog * 256, 0); nodeSize = ((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 + sizeof(BTNodeDescriptor)))->nodeSize; // If the BTree node size is larger than the block size, reset the cache. if (nodeSize > gBlockSize) CacheInit(ih, nodeSize); return 0; }