struct Blocks *InsertBlock( NInt blockpos, NInt num_tracks, int num_lines, const char *name ) { R_ASSERT(is_playing()==false); struct Tracker_Windows *window=root->song->tracker_windows; struct WBlocks *wblock; struct Blocks *block; InsertBlock_IncBlockNums(blockpos); block=talloc(sizeof(struct Blocks)); block->l.num=blockpos; NewBlock(block,num_tracks,num_lines,name); while(window!=NULL){ wblock=talloc(sizeof(struct WBlocks)); wblock->l.num=blockpos; NewWBlock(window,wblock,block); window=NextWindow(window); } return block; }
// Send a SSTP packet void SstpSendPacket(SSTP_SERVER *s, SSTP_PACKET *p) { BUF *b; BLOCK *block; // Validate arguments if (s == NULL || p == NULL) { return; } if (p->IsControl) { Debug("SSTP Control Packet Send: Msg = %u, Num = %u\n", p->MessageType, LIST_NUM(p->AttibuteList)); } else { //Debug("SSTP Data Packet Send: Size=%u\n", p->DataSize); } b = SstpBuildPacket(p); if (b == NULL) { return; } block = NewBlock(b->Buf, b->Size, 0); block->PriorityQoS = p->IsControl; Free(b); InsertQueue(s->SendQueue, block); }
// Packet generation thread void NullPacketGenerateThread(THREAD *t, void *param) { NULL_LAN *n = (NULL_LAN *)param; // Validate arguments if (t == NULL || param == NULL) { return; } while (true) { Wait(n->Event, Rand32() % NULL_PACKET_GENERATE_INTERVAL); if (n->Halt) { break; } LockQueue(n->PacketQueue); { UCHAR *data; BLOCK *b; UINT size = Rand32() % 1500 + 14; data = Malloc(size); Copy(data, null_lan_broadcast_address, 6); Copy(data + 6, n->MacAddr, 6); b = NewBlock(data, size, 0); InsertQueue(n->PacketQueue, b); } UnlockQueue(n->PacketQueue); Cancel(n->Cancel); } }
void World::Drop(Block * const block_from, const ushort x_to, const ushort y_to, const ushort z_to, const ushort src, const ushort dest, const ushort num) { Block * block_to=GetBlock(x_to, y_to, z_to); if ( AIR==block_to->Sub() ) { SetBlock((block_to=NewBlock(PILE, DIFFERENT)), x_to, y_to, z_to); } else if ( WATER==block_to->Sub() ) { Block * const pile = NewBlock(PILE, DIFFERENT); SetBlock(pile, x_to, y_to, z_to); pile->HasInventory()->Get(block_to); block_to = pile; } Exchange(block_from, block_to, src, dest, num); emit Updated(x_to, y_to, z_to); }
void World::Damage(const ushort x, const ushort y, const ushort z, const ushort dmg, const int dmg_kind) { Block * temp = GetBlock(x, y, z); if ( temp==Normal(temp->Sub()) && AIR!=temp->Sub() ) { SetBlock((temp=NewBlock(temp->Kind(), temp->Sub())), x, y, z); } if ( temp->Damage(dmg, dmg_kind) > 0 ) { temp->ReceiveSignal(SOUND_STRINGS[1]); // "Ouch!" if ( block_manager.MakeId(BLOCK, STONE)==temp->GetId() && temp->Durability()!=MAX_DURABILITY ) { // convert stone into ladder DeleteBlock(temp); SetBlock(NewBlock(LADDER, STONE), x, y, z); emit ReEnlighten(x, y, z); } else { SetBlock(ReplaceWithNormal(temp), x, y, z); } } }
void* MemoryArenaAllocator::Alloc(size_t size) { size_t rounded = Round(size); // If there isn't enough space on this block, we need to // allocate a new one. if (m_current_block_pos + rounded > m_block_size) { NewBlock(rounded); m_current_block_pos = 0; } void* r = m_current_block + m_current_block_pos; m_current_block_pos += rounded; return r; }
// Packet generation thread void NullPacketGenerateThread(THREAD *t, void *param) { NULL_LAN *n = (NULL_LAN *)param; UINT64 end_tick = Tick64() + (UINT64)(60 * 1000); UINT seq = 0; // Validate arguments if (t == NULL || param == NULL) { return; } while (true) { /*if (Tick64() >= end_tick) { break; }*/ Wait(n->Event, Rand32() % 1500); if (n->Halt) { break; } LockQueue(n->PacketQueue); { UCHAR *data; BLOCK *b; UINT size = Rand32() % 1500 + 14; UCHAR dst_mac[6]; NullGenerateMacAddress(n->MacAddr, n->Id, seq); //NullGenerateMacAddress(dst_mac, n->Id + 1, 0); //StrToMac(dst_mac, "00-1B-21-A9-47-E6"); StrToMac(dst_mac, "00-AC-7A-EF-83-FD"); data = Malloc(size); Copy(data, null_lan_broadcast_address, 6); //Copy(data, dst_mac, 6); Copy(data + 6, n->MacAddr, 6); b = NewBlock(data, size, 0); InsertQueue(n->PacketQueue, b); } UnlockQueue(n->PacketQueue); Cancel(n->Cancel); //seq++; } }
bool World::Inscribe(const ushort x, const ushort y, const ushort z) { Block * block=GetBlock(x, y, z); if ( LIQUID==block->Kind() || AIR==block->Sub() ) { return false; } if ( block==Normal(block->Sub()) ) { SetBlock(block=NewBlock(block->Kind(), block->Sub()), x, y, z); } QString str=tr("No note received."); emit GetString(str); if ( block->Inscribe(str) ) { return true; } else { SetBlock(ReplaceWithNormal(block), x, y, z); return false; } }
T * CTMemory<T>::Allocate(void) { m_IrlMutex.StartReading(); // find a block of the right size with at least one free element // _L_DEBUG(1, cout << "CTMemory :: looking up a block of " << sizeof(T) << endl); bool bNewBlock = true; int nAcquiredBit = -1; CIterator Iterator; CABlock<T> * CurrentBlock = (CABlock<T> *) m_vBlocks.GetLast(Iterator); while (CurrentBlock) { nAcquiredBit = CurrentBlock->AcquireFree(); if (nAcquiredBit != -1) { bNewBlock = false; break; } CurrentBlock = (CABlock<T> *) m_vBlocks.GetPrev(Iterator); } m_IrlMutex.StopReading(); if (bNewBlock) { // add a new clean one // _L_DEBUG(1, cout << "CTMemory :: adding a block of " << sizeof(T) << endl); CABlock<T> NewBlock(sizeof(T)); m_IrlMutex.StartWriting(); m_vBlocks += NewBlock; CurrentBlock = (CABlock<T> *) m_vBlocks.GetLast(Iterator); CurrentBlock->Initialize(m_PageSize); nAcquiredBit = CurrentBlock->AcquireFree(); // assert(nAcquiredBit != -1); m_IrlMutex.StopWriting(); // printf("CTMemory :: new file size: %ld bytes.\n", m_TailOffset); } // add a new element to the block T * pMem = CurrentBlock->Allocate(nAcquiredBit); // assert(pMem); // _L_DEBUG(1, cout << "CTMemory :: allocated pointer: " << (long) pMem << endl); // printf("[+%d]", CurrentBlock->m_nElSize); return pMem; }
// 受信したパケットを書き込み bool LinkPaPutPacket(SESSION *s, void *data, UINT size) { LINK *k; BLOCK *block; SESSION *server_session; CONNECTION *server_connection; // 引数チェック if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL) { return false; } server_session = k->ServerSession; server_connection = server_session->Connection; // ここにはリンク接続先の HUB から届いたパケットが来るので // サーバーセッションの ReceivedBlocks に届けてあげる if (data != NULL) { block = NewBlock(data, size, 0); LockQueue(server_connection->ReceivedBlocks); { InsertQueue(server_connection->ReceivedBlocks, block); } UnlockQueue(server_connection->ReceivedBlocks); } else { // data == NULL のとき、すべてのパケットを格納し終わったので // Cancel を発行する Cancel(server_session->Cancel1); if (k->Hub != NULL && k->Hub->Option != NULL && k->Hub->Option->YieldAfterStorePacket) { YieldCpu(); } } return true; }
// Write the received packet bool LinkPaPutPacket(SESSION *s, void *data, UINT size) { LINK *k; BLOCK *block; SESSION *server_session; CONNECTION *server_connection; // Validate arguments if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL) { return false; } server_session = k->ServerSession; server_connection = server_session->Connection; // Since the packet arrives from the HUB of the link destination, // deliver it to the ReceivedBlocks of the server session if (data != NULL) { block = NewBlock(data, size, 0); LockQueue(server_connection->ReceivedBlocks); { InsertQueue(server_connection->ReceivedBlocks, block); } UnlockQueue(server_connection->ReceivedBlocks); } else { // Issue the Cancel, since finished store all packets when the data == NULL Cancel(server_session->Cancel1); if (k->Hub != NULL && k->Hub->Option != NULL && k->Hub->Option->YieldAfterStorePacket) { YieldCpu(); } } return true; }
void Interpreter::Interpret(ILineReader & reader, bool showResult) { Ref<Expr> expr = Parse(reader); // Bail if we failed to parse. if (expr.IsNull()) return; // Create a starting fiber for the expression. Ref<Block> block = Compiler::CompileTopLevel(*this, *expr); Value blockObj = NewBlock(block, mNil); Value fiber = NewFiber(blockObj); // Run the interpreter. Value result = fiber.AsFiber()->GetFiber().Execute(); if (showResult) { std::stringstream text; text << result << std::endl; mHost.Output(String(text.str().c_str())); } }
void World::DestroyAndReplace(const ushort x, const ushort y, const ushort z) { Block * const temp = GetBlock(x, y, z); if ( temp->Durability() > 0 ) { return; } Block * const dropped = temp->DropAfterDamage(); Shred * const shred = GetShred(x, y); const ushort x_in_shred = Shred::CoordInShred(x); const ushort y_in_shred = Shred::CoordInShred(y); if ( PILE!=temp->Kind() && (temp->HasInventory() || dropped) ) { Block * const new_pile=( ( dropped && PILE==dropped->Kind() ) ? dropped : NewBlock(PILE, DIFFERENT) ); shred->SetBlock(new_pile, x_in_shred, y_in_shred, z); Inventory * const inv = temp->HasInventory(); Inventory * const new_pile_inv = new_pile->HasInventory(); if ( inv ) { new_pile_inv->GetAll(inv); } if ( dropped && PILE!=dropped->Kind() && !new_pile_inv->Get(dropped) ) { DeleteBlock(dropped); } shred->AddFalling(x_in_shred, y_in_shred, z); } else { PutBlock(Normal(AIR), x, y, z); } const int old_transparency = temp->Transparent(); const uchar old_light = temp->LightRadius(); DeleteBlock(temp); shred->AddFalling(x_in_shred, y_in_shred, z+1); if ( old_transparency != INVISIBLE ) { ReEnlightenBlockRemove(x, y, z); } if ( old_light ) { RemoveFireLight(x, y, z); } } // void World::DestroyAndReplace(ushort x, y, z)
// Write the received packet bool LinkPaPutPacket(SESSION *s, void *data, UINT size) { LINK *k; BLOCK *block = NULL; SESSION *server_session; CONNECTION *server_connection; bool ret = true; bool halting = false; // Validate arguments if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL) { return false; } halting = (k->Halting || (*k->StopAllLinkFlag)); server_session = k->ServerSession; server_connection = server_session->Connection; k->Flag1++; if ((k->Flag1 % 32) == 0) { // Ommit for performance UINT current_num; int diff; current_num = GetQueueNum(server_connection->ReceivedBlocks); diff = (int)current_num - (int)k->LastServerConnectionReceivedBlocksNum; k->LastServerConnectionReceivedBlocksNum = current_num; CedarAddQueueBudget(k->Cedar, diff); } // Since the packet arrives from the HUB of the link destination, // deliver it to the ReceivedBlocks of the server session if (data != NULL) { if (halting == false) { block = NewBlock(data, size, 0); } if (k->LockFlag == false) { UINT current_num; int diff; k->LockFlag = true; LockQueue(server_connection->ReceivedBlocks); current_num = GetQueueNum(server_connection->ReceivedBlocks); diff = (int)current_num - (int)k->LastServerConnectionReceivedBlocksNum; k->LastServerConnectionReceivedBlocksNum = current_num; CedarAddQueueBudget(k->Cedar, diff); } if (halting == false) { if (CedarGetFifoBudgetBalance(k->Cedar) == 0) { FreeBlock(block); } else { InsertReveicedBlockToQueue(server_connection, block, true); } } } else { UINT current_num; int diff; current_num = GetQueueNum(server_connection->ReceivedBlocks); diff = (int)current_num - (int)k->LastServerConnectionReceivedBlocksNum; k->LastServerConnectionReceivedBlocksNum = current_num; CedarAddQueueBudget(k->Cedar, diff); if (k->LockFlag) { k->LockFlag = false; UnlockQueue(server_connection->ReceivedBlocks); } // Issue the Cancel, since finished store all packets when the data == NULL Cancel(server_session->Cancel1); if (k->Hub != NULL && k->Hub->Option != NULL && k->Hub->Option->YieldAfterStorePacket) { YieldCpu(); } } if (halting) { ret = false; } return ret; }
// Read next packet UINT EthGetPacket(ETH *e, void **data) { BLOCK *b; bool flag = false; // Validate arguments if (e == NULL || data == NULL) { return INFINITE; } if (e->HasFatalError) { return INFINITE; } if (e->SuAdapter != NULL) { // Read packet with SeLow UINT size; if (SuGetNextPacket(e->SuAdapter, data, &size) == false) { // Error occurred e->HasFatalError = true; return INFINITE; } return size; } RETRY: // Check the presence of the packet in queue b = GetNext(e->PacketQueue); if (b != NULL) { UINT size; size = b->Size; *data = b->Buf; Free(b); if (e->PacketQueue->num_item == 0) { e->Empty = true; } return size; } if (e->Empty) { e->Empty = false; return 0; } if (flag == false) { // Try to get next packet PROBE_STR("EthGetPacket: PacketInitPacket"); wp->PacketInitPacket(e->Packet, e->Buffer, e->BufferSize); PROBE_STR("EthGetPacket: PacketReceivePacket"); if (wp->PacketReceivePacket(e->Adapter, e->Packet, false) == false) { // Failed return INFINITE; } else { UCHAR *buf; UINT total; UINT offset; buf = (UCHAR *)e->Packet->Buffer; total = e->Packet->ulBytesReceived; offset = 0; while (offset < total) { struct bpf_hdr *header; UINT packet_size; UCHAR *packet_data; header = (struct bpf_hdr *)(buf + offset); packet_size = header->bh_caplen; offset += header->bh_hdrlen; packet_data = buf + offset; offset = Packet_WORDALIGN(offset + packet_size); if (packet_size >= 14) { UCHAR *tmp; BLOCK *b; PROBE_DATA2("EthGetPacket: NewBlock", packet_data, packet_size); tmp = MallocFast(packet_size); Copy(tmp, packet_data, packet_size); b = NewBlock(tmp, packet_size, 0); InsertQueue(e->PacketQueue, b); } } flag = true; goto RETRY; } } // No more packet return 0; }
void * CVMemory::VAllocate(size_t DesiredBytes) { // make Bytes a multiple of 32 nomatter what in order not to have too much fragmentation size_t Bytes = 8; while (Bytes < DesiredBytes) Bytes <<= 1; m_IrlMutex.StartReading(); // find a block of the right size with at least one free element // _L_DEBUG(1, cout << "CVMemory :: looking up a block of " << Bytes << endl); bool bNewBlock = true; int nAcquiredBit = -1; // look inside the pool of cached blocks for each multiple of 32 bytes short int nCachedIndex = (Bytes / 32) % V_MAX_CACHE; CIterator Iterator; CABlock<char> * CurrentBlock = m_CacheBlocks[nCachedIndex]; if ((CurrentBlock) && (((CTBlock<char> *) CurrentBlock)->GetElSize() == Bytes) && ((nAcquiredBit = ((CTBlock<char> *) CurrentBlock)->AcquireFree()) != -1)) { bNewBlock = false; } else if (Bytes <= (unsigned long) m_LastMultiple) { CurrentBlock = (CABlock<char> *) m_vBlocks.GetLast(Iterator); while (CurrentBlock) { if (((CTBlock<char> *) CurrentBlock)->GetElSize() == Bytes) { nAcquiredBit = ((CTBlock<char> *) CurrentBlock)->AcquireFree(); if (nAcquiredBit != -1) { bNewBlock = false; break; } } CurrentBlock = (CABlock<char> *) m_vBlocks.GetPrev(Iterator); } } else { m_LastMultiple = Bytes; } m_IrlMutex.StopReading(); // find a multiple of page size - this is the block that we will in fact allocate size_t MappedRegionSize = m_PageSize; while ((Bytes > MappedRegionSize) || (MappedRegionSize < 64 * KBYTE)) MappedRegionSize <<= 1; if (bNewBlock) { // add a new clean one // _L_DEBUG(1, cout << "CVMemory :: adding a block of " << Bytes << endl); CABlock<char> NewBlock(Bytes); m_IrlMutex.StartWriting(); m_vBlocks += NewBlock; CurrentBlock = (CABlock<char> *) m_vBlocks.GetLast(Iterator); ((CABlock<char> *) CurrentBlock)->Initialize(MappedRegionSize); nAcquiredBit = ((CTBlock<char> *) CurrentBlock)->AcquireFree(); // assert(nAcquiredBit != -1); m_IrlMutex.StopWriting(); // printf("CVMemory :: new file size: %ld bytes.\n", m_TailOffset); } m_IrlMutex.StartWriting(); m_CacheBlocks[nCachedIndex] = CurrentBlock; m_IrlMutex.StopWriting(); // add a new element to the block void * pMem = (void *) ((CTBlock<char> *) CurrentBlock)->Allocate(nAcquiredBit); // assert(pMem); // _L_DEBUG(1, cout << "CVMemory :: allocated pointer: " << (long) pMem << endl); // printf("[+%d]", CurrentBlock->m_nElSize); return pMem; }
// Handle the communication of SSTP protocol bool ProcessSstpHttps(CEDAR *cedar, SOCK *s, SOCK_EVENT *se) { UINT tmp_size = 65536; UCHAR *tmp_buf; FIFO *recv_fifo; FIFO *send_fifo; SSTP_SERVER *sstp; bool ret = false; // Validate arguments if (cedar == NULL || s == NULL || se == NULL) { return false; } tmp_buf = Malloc(tmp_size); recv_fifo = NewFifo(); send_fifo = NewFifo(); sstp = NewSstpServer(cedar, &s->RemoteIP, s->RemotePort, &s->LocalIP, s->LocalPort, se, s->RemoteHostname, s->CipherName); while (true) { UINT r; bool is_disconnected = false; bool state_changed = false; // Receive data over SSL while (true) { r = Recv(s, tmp_buf, tmp_size, true); if (r == 0) { // SSL is disconnected is_disconnected = true; break; } else if (r == SOCK_LATER) { // Data is not received any more break; } else { // Queue the received data WriteFifo(recv_fifo, tmp_buf, r); state_changed = true; } } while (recv_fifo->size >= 4) { UCHAR *first4; UINT read_size = 0; bool ok = false; // Read 4 bytes from the beginning of the receive queue first4 = ((UCHAR *)recv_fifo->p) + recv_fifo->pos; if (first4[0] == SSTP_VERSION_1) { USHORT len = READ_USHORT(first4 + 2) & 0xFFF; if (len >= 4) { ok = true; if (recv_fifo->size >= len) { UCHAR *data; BLOCK *b; read_size = len; data = Malloc(read_size); ReadFifo(recv_fifo, data, read_size); b = NewBlock(data, read_size, 0); InsertQueue(sstp->RecvQueue, b); } } } if (read_size == 0) { break; } if (ok == false) { // Disconnect the connection since a bad packet received is_disconnected = true; break; } } // Process the timer interrupt SstpProcessInterrupt(sstp); if (sstp->Disconnected) { is_disconnected = true; } // Put the transmission data that SSTP module has generated into the transmission queue while (true) { BLOCK *b = GetNext(sstp->SendQueue); if (b == NULL) { break; } // When transmit a data packet, If there are packets of more than about // 2.5 MB in the transmission queue of the TCP, discard without transmission if (b->PriorityQoS || (send_fifo->size <= MAX_BUFFERING_PACKET_SIZE)) { WriteFifo(send_fifo, b->Buf, b->Size); } FreeBlock(b); } // Data is transmitted over SSL while (send_fifo->size != 0) { r = Send(s, ((UCHAR *)send_fifo->p) + send_fifo->pos, send_fifo->size, true); if (r == 0) { // SSL is disconnected is_disconnected = true; break; } else if (r == SOCK_LATER) { // Can not send any more break; } else { // Advance the transmission queue by the amount of the transmitted ReadFifo(send_fifo, NULL, r); state_changed = true; } } if (is_disconnected) { // Disconnected break; } // Wait for the next state change if (state_changed == false) { UINT select_time = SELECT_TIME; UINT r = GetNextIntervalForInterrupt(sstp->Interrupt); WaitSockEvent(se, MIN(r, select_time)); } } if (sstp != NULL && sstp->EstablishedCount >= 1) { ret = true; } FreeSstpServer(sstp); ReleaseFifo(recv_fifo); ReleaseFifo(send_fifo); Free(tmp_buf); YieldCpu(); Disconnect(s); return ret; }
extern bool CreateBreak( void ) /*****************************************/ { block *blk; block *break_blk; block *back_break_blk; block *exit_blk; block_edge *edge; block_edge *next_edge; block_num targets; int pending; edge_list *exit_edge; if( HeadBlock == NULL ) { return( false ); } if( _IsntModel( FORTRAN_ALIASING ) ) { return( false ); } if( !FixReturns() ) { return( false ); } FixEdges(); /* Run through the blocks and find a place (break_blk) where no previous blocks are branched to from later blocks. IE: there are no backward branches around break_blk. */ _MarkBlkAllUnVisited(); break_blk = NULL; back_break_blk = NULL; pending = 0; BranchOuts = NULL; for( blk = HeadBlock; blk != NULL; blk = blk->next_block ) { if( AskIfReachedLabel( blk->label ) && blk != HeadBlock ) break; if( (blk->edge[0].flags & BLOCK_LABEL_DIES) == 0 && blk != HeadBlock ) { _MarkBlkVisited( blk ); ++pending; } else if( pending == 0 ) { break_blk = blk; } edge = &blk->edge[0]; for( targets = blk->targets; targets > 0; --targets ) { if( edge->flags & DEST_IS_BLOCK ) { if( edge->flags & DEST_LABEL_DIES ) { if( _IsBlkVisited( edge->destination.u.blk ) ) { _MarkBlkUnVisited( edge->destination.u.blk ); if( --pending == 0 ) { back_break_blk = blk->next_block; } } } } ++edge; } } /* clean up the BLOCK_VISITED flags */ _MarkBlkAllUnVisited(); if( back_break_blk != NULL ) { break_blk = back_break_blk; /* always better to break on a back edge */ } if( break_blk == NULL ) { break_blk = HeadBlock; } if( break_blk == HeadBlock ) { break_blk = break_blk->next_block; } if( break_blk == NULL ) { UnFixEdges(); return( false ); } /* create a new block and link it after break_blk. Point Break to the rest of the blocks and unhook them from the block list. */ Break = break_blk; Curr = CurrBlock; Tail = BlockList; exit_blk = NewBlock( NULL, false ); exit_blk->gen_id = BlockList->gen_id + 1; exit_blk->id = BlockList->id + 1; exit_blk->ins.hd.line_num = 0; BlockList = exit_blk; exit_blk->prev_block = break_blk->prev_block; exit_blk->next_block = NULL; _SetBlkAttr( exit_blk, BLK_UNKNOWN_DESTINATION ); break_blk->prev_block->next_block = exit_blk; break_blk->prev_block = NULL; /* run throuch all the blocks before break_blk, and create a 'BranchOut' for and edge that goes to a block after break_blk */ for( blk = HeadBlock; blk != NULL; blk = blk->next_block ) { edge = &blk->edge[0]; for( targets = blk->targets; targets > 0; --targets ) { if( (edge->flags & DEST_IS_BLOCK) == 0 || edge->destination.u.blk->gen_id >= break_blk->gen_id ) { exit_edge = CGAlloc( sizeof( edge_list ) ); exit_edge->edge = edge; exit_edge->next = BranchOuts; exit_edge->gen_id = blk->gen_id; BranchOuts = exit_edge; } ++edge; } } /* now, point all 'BranchOuts' at the new 'exit' block, saving their original labels in the 'lbl' field of the exit_list */ for( exit_edge = BranchOuts; exit_edge != NULL; exit_edge = exit_edge->next ) { edge = exit_edge->edge; if( edge->flags & DEST_IS_BLOCK ) { exit_edge->lbl = edge->destination.u.blk->label; RemoveInputEdge( edge ); } else { exit_edge->lbl = edge->destination.u.lbl; } edge->destination.u.blk = exit_blk; edge->flags |= DEST_IS_BLOCK; edge->next_source = exit_blk->input_edges; exit_blk->input_edges = edge; exit_blk->inputs++; } if( exit_blk->inputs == 0 ) { BlockList = exit_blk->prev_block; BlockList->next_block = NULL; exit_blk->prev_block = NULL; FreeABlock( exit_blk ); } _MarkBlkAttr( HeadBlock, BLK_BIG_LABEL ); HaveBreak = true; /* change any branches to HeadBlock from a block after break_blk into a label (~DEST_IS_BLOCK) branch. */ for( edge = HeadBlock->input_edges; edge != NULL; edge = next_edge ) { next_edge = edge->next_source; if( edge->source->gen_id >= break_blk->gen_id ) { RemoveInputEdge( edge ); edge->destination.u.lbl = edge->destination.u.blk->label; edge->flags &= ~DEST_IS_BLOCK; } } /* Now, set up a new HeadBlock, and redirect all unknowns branches to it. Known branches may still go to the old HeadBlock. This is so that HeadBlock will not be a loop header. The loop optimizer will screw up if it is. */ blk = NewBlock( NULL, false ); blk->input_edges = NULL; blk->inputs = 0; blk->label = HeadBlock->label; blk->ins.hd.line_num = HeadBlock->ins.hd.line_num; HeadBlock->ins.hd.line_num = 0; blk->gen_id = 0; blk->id = 0; HeadBlock->label = AskForNewLabel(); blk->targets = 1; _SetBlkAttr( blk, BLK_BIG_LABEL | BLK_JUMP ); _MarkBlkAttrNot( HeadBlock, BLK_BIG_LABEL ); edge = &blk->edge[0]; edge->flags = DEST_IS_BLOCK; edge->destination.u.blk = HeadBlock; edge->source = blk; edge->next_source = HeadBlock->input_edges; HeadBlock->input_edges = edge; HeadBlock->inputs++; HeadBlock->prev_block = blk; blk->prev_block = NULL; blk->next_block = HeadBlock; HeadBlock = blk; return( true ); }
// Process the received packet BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip, UINT src_port) { UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE]; UCHAR *iv; CRYPT *c; UINT64 my_tick, your_tick; UINT inner_size; UCHAR *inner_data = NULL; UINT pad_size; UCHAR *verify; bool compress_flag; BLOCK *b = NULL; UINT cookie; // Validate arguments if (a == NULL || buf == NULL || size == 0 || src_ip == NULL) { return NULL; } if (a->PlainTextMode == false) { // IV if (size < UDP_ACCELERATION_PACKET_IV_SIZE) { return NULL; } iv = buf; buf += UDP_ACCELERATION_PACKET_IV_SIZE; size -= UDP_ACCELERATION_PACKET_IV_SIZE; // Calculate the key UdpAccelCalcKey(key, a->YourKey, iv); if (false) { char tmp1[256]; char tmp2[256]; char tmp3[256]; BinToStr(tmp1, sizeof(tmp1), a->YourKey, sizeof(a->YourKey)); BinToStr(tmp2, sizeof(tmp2), iv, UDP_ACCELERATION_PACKET_IV_SIZE); BinToStr(tmp3, sizeof(tmp3), key, sizeof(key)); Debug("Your Key: %s\n" "IV : %s\n" "Comm Key: %s\n", tmp1, tmp2, tmp3); } // Decryption c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE); Encrypt(c, buf, buf, size); FreeCrypt(c); } // Cookie if (size < sizeof(UINT)) { return NULL; } cookie = READ_UINT(buf); buf += sizeof(UINT); size -= sizeof(UINT); if (cookie != a->MyCookie) { return NULL; } // My Tick if (size < sizeof(UINT64)) { return NULL; } my_tick = READ_UINT64(buf); buf += sizeof(UINT64); size -= sizeof(UINT64); // Your Tick if (size < sizeof(UINT64)) { return NULL; } your_tick = READ_UINT64(buf); buf += sizeof(UINT64); size -= sizeof(UINT64); // inner_size if (size < sizeof(USHORT)) { return NULL; } inner_size = READ_USHORT(buf); buf += sizeof(USHORT); size -= sizeof(USHORT); // compress_flag if (size < sizeof(UCHAR)) { return NULL; } compress_flag = *((UCHAR *)buf); buf += sizeof(UCHAR); size -= sizeof(UCHAR); if (size < inner_size) { return NULL; } // inner_data if (inner_size >= 1) { inner_data = buf; buf += inner_size; size -= inner_size; } if (a->PlainTextMode == false) { // padding if (size < UDP_ACCELERATION_PACKET_IV_SIZE) { return false; } pad_size = size - UDP_ACCELERATION_PACKET_IV_SIZE; buf += pad_size; size -= pad_size; // verify if (size != UDP_ACCELERATION_PACKET_IV_SIZE) { return NULL; } verify = buf; if (IsZero(verify, UDP_ACCELERATION_PACKET_IV_SIZE) == false) { return NULL; } } if (my_tick < a->LastRecvYourTick) { if ((a->LastRecvYourTick - my_tick) >= ((UINT64)UDP_ACCELERATION_WINDOW_SIZE_MSEC)) { return NULL; } } a->LastRecvMyTick = MAX(a->LastRecvMyTick, your_tick); a->LastRecvYourTick = MAX(a->LastRecvYourTick, my_tick); if (inner_size >= 1) { b = NewBlock(Clone(inner_data, inner_size), inner_size, compress_flag ? -1 : 0); } if (a->LastSetSrcIpAndPortTick < a->LastRecvYourTick) { a->LastSetSrcIpAndPortTick = a->LastRecvYourTick; Copy(&a->YourIp, src_ip, sizeof(IP)); a->YourPort = src_port; } if (a->LastRecvMyTick != 0) { if ((a->LastRecvMyTick + (UINT64)(UDP_ACCELERATION_WINDOW_SIZE_MSEC)) >= a->Now) { a->LastRecvTick = a->Now; a->IsReachedOnce = true; if (a->FirstStableReceiveTick == 0) { a->FirstStableReceiveTick = a->Now; } } } return b; }
// Processing of the interrupt void EtherIPProcInterrupts(ETHERIP_SERVER *s) { // Validate arguments if (s == NULL) { return; } // If EtherIP settings have been changed, and the change may effect to this connection, disconnect if (s->Ipc != NULL) { if (s->Ike->IPsec->EtherIPIdListSettingVerNo != s->LastEtherIPSettingVerNo) { ETHERIP_ID id; bool ok = true; s->LastEtherIPSettingVerNo = s->Ike->IPsec->EtherIPIdListSettingVerNo; if (SearchEtherIPId(s->IPsec, &id, s->ClientId) == false && SearchEtherIPId(s->IPsec, &id, "*") == false) { ok = false; } else { if (StrCmpi(s->CurrentEtherIPIdSetting.HubName, id.HubName) != 0 || StrCmpi(s->CurrentEtherIPIdSetting.UserName, id.UserName) != 0 || StrCmp(s->CurrentEtherIPIdSetting.Password, id.Password) != 0) { ok = false; } } if (ok == false) { // Disconnect immediately since setting of EtherIP seems to have been changed FreeIPC(s->Ipc); s->Ipc = NULL; EtherIPLog(s, "LE_RECONNECT"); } } } // Connect if IPC connection is not completed Lock(s->Lock); { if (s->Ipc == NULL) { if (s->IpcConnectThread == NULL) { if ((s->LastConnectFailedTick == 0) || ((s->LastConnectFailedTick + (UINT64)ETHERIP_VPN_CONNECT_RETRY_INTERVAL) <= s->Now)) { Lock(s->IPsec->LockSettings); { Copy(&s->CurrentIPSecServiceSetting, &s->IPsec->Services, sizeof(IPSEC_SERVICES)); } Unlock(s->IPsec->LockSettings); s->IpcConnectThread = NewThread(EtherIPIpcConnectThread, s); AddThreadToThreadList(s->Ike->ThreadList, s->IpcConnectThread); AddRef(s->Ref); } } } } Unlock(s->Lock); if (s->Ipc != NULL) { // Set to get hit the SockEvent when a packet arrives via the IPC IPCSetSockEventWhenRecvL2Packet(s->Ipc, s->SockEvent); // IPC interrupt processing IPCProcessInterrupts(s->Ipc); // Receive the MAC frame which arrived via the IPC while (true) { BLOCK *b = IPCRecvL2(s->Ipc); UCHAR *dst; UINT dst_size; if (b == NULL) { break; } if (b->Size >= 14) { BLOCK *block; // Store the arrived MAC frame by adding an EtherIP header to the reception packet queue if (s->L2TPv3 == false) { dst_size = b->Size + 2; dst = Malloc(dst_size); dst[0] = 0x30; dst[1] = 0x00; Copy(dst + 2, b->Buf, b->Size); } else { dst = Clone(b->Buf, b->Size); dst_size = b->Size; } block = NewBlock(dst, dst_size, 0); Add(s->SendPacketList, block); } FreeBlock(b); } if (IsIPCConnected(s->Ipc) == false) { // IPC connection is disconnected FreeIPC(s->Ipc); s->Ipc = NULL; } } }
CTextRenderer::CGlyph* CTextRenderer::CGlyphCache::NewGlyph(CGlyphId GlyphId, int Width, int Height) { ivec2 Granularity; Granularity.x = (Width%m_PPG == 0 ? (Width / m_PPG) : (Width / m_PPG) + 1); Granularity.y = (Height%m_PPG == 0 ? (Height / m_PPG) : (Height / m_PPG) + 1); if(Granularity.x < 1) Granularity.x = 1; if(Granularity.y < 1) Granularity.y = 1; //First pass: find a free slot in blocks //We use backward iteration because non-full blockes are at the end for(int i=m_Blocks.size()-1; i>=0; i--) { if(m_Blocks[i].m_Granularity == Granularity) { if(!m_Blocks[i].IsFull()) { CGlyph* pGlyph = &m_Glyphs[m_Glyphs.add(CGlyph(GlyphId))]; pGlyph->m_Width = Width; pGlyph->m_Height = Height; pGlyph->m_Granularity = Granularity; pGlyph->m_Block = i; pGlyph->m_BlockPos = m_Blocks[i].m_Size; UpdateGlyph(pGlyph); m_Blocks[pGlyph->m_Block].m_Size++; return pGlyph; } else break; //Only the last block of this granularity can be non-full } } //Second pass: find the oldest glyph with the same granularity int OldestTick = m_RenderTick; int OldestGlyph = -1; for(int i=0; i<m_Glyphs.size(); i++) { if(m_Glyphs[i].m_Granularity == Granularity && m_Glyphs[i].m_RenderTick < OldestTick) { OldestTick = m_Glyphs[i].m_RenderTick; OldestGlyph = i; } } if(OldestGlyph >= 0) //Replace the glyph { CGlyph Glyph = CGlyph(GlyphId); Glyph.m_Block = m_Glyphs[OldestGlyph].m_Block; Glyph.m_BlockPos = m_Glyphs[OldestGlyph].m_BlockPos; m_Glyphs.remove_index(OldestGlyph); int GlyphId = m_Glyphs.add(Glyph); CGlyph* pGlyph = &m_Glyphs[GlyphId]; pGlyph->m_Width = Width; pGlyph->m_Height = Height; pGlyph->m_Granularity = Granularity; UpdateGlyph(pGlyph); UpdateVersion(); return pGlyph; } else //Add a new block { int BlockId = NewBlock(Granularity); CGlyph* pGlyph = &m_Glyphs[m_Glyphs.add(CGlyph(GlyphId))]; pGlyph->m_Width = Width; pGlyph->m_Height = Height; pGlyph->m_Granularity = Granularity; pGlyph->m_Block = BlockId; pGlyph->m_BlockPos = 0; UpdateGlyph(pGlyph); m_Blocks[pGlyph->m_Block].m_Size++; return pGlyph; } }