private static void HandleClientThread() { try { while (!cancellation.Token.IsCancellationRequested) { Context context; while (ContextQueue.Count == 0) { Thread.Sleep(10); if (cancellation.Token.IsCancellationRequested) { return; } } if (!ContextQueue.TryDequeue(out context)) { continue; } context.Server.SetupContext(context); lock (CurrentConnections){ CurrentConnections.Add(context); } } } catch (Exception ex) { Console.WriteLine(ex); } }
// Accepts new connection contexts private void AcceptContext() { // Create a wait handle array so we can cancel this thread if need be WaitHandle[] Wait = new[] { ReadyEvent, StopEvent }; while (0 == WaitHandle.WaitAny(Wait)) { // Lock our context queue to prevent race conditions lock (ContextQueue) { // Context queue has entries, accept one if (ContextQueue.Count > 0) { // Dequeue next context in line var Context = ContextQueue.Dequeue(); // Handle this context HandleRequest(Context); } // There are no entries in the connection queue else { // No context in line, reset ready event ReadyEvent.Reset(); continue; } } } }
/// <summary> /// Fires when a client connects. /// </summary> /// <param name="data">The TCP Connection.</param> protected override void OnRunClient(object data) { try { var connection = (TcpClient)data; var context = new Context(this, connection); context.UserContext.ClientAddress = context.Connection.Client.RemoteEndPoint; context.UserContext.SetOnConnect(OnConnect); context.UserContext.SetOnConnected(OnConnected); context.UserContext.SetOnDisconnect(OnDisconnect); context.UserContext.SetOnSend(OnSend); context.UserContext.SetOnReceive(OnReceive); context.BufferSize = BufferSize; context.UserContext.OnConnect(); if (context.Connected) { ContextQueue.Enqueue(context); } } catch (Exception) { } }
private static void HandleClientThread() { while (!Handler.Shutdown.Token.IsCancellationRequested) { Context context; while (ContextQueue.Count == 0) { Thread.Sleep(10); if (Handler.Shutdown.IsCancellationRequested) { return; } } if (!ContextQueue.TryDequeue(out context)) { continue; } lock (ContextMapping) { WebSocketServer server = ContextMapping[context]; server.SetupContext(context); } lock (CurrentConnections){ CurrentConnections.Add(context); } } }
// Listens for new requests and enqueues them private void Listen() { while (Listener.IsListening) { // Accept new connection context var Context = Listener.BeginGetContext((IAsyncResult Result) => { try { // Lock our context queue to prevent race conditions lock (ContextQueue) { // Add new connection context to our context queue ContextQueue.Enqueue(Listener.EndGetContext(Result)); // Signal that a context is ready to be accepted ReadyEvent.Set(); } } catch { } }, null); // Wait for exit if (WaitHandle.WaitAny(new[] { StopEvent, Context.AsyncWaitHandle }) == 0) { return; } } }
private static void HandleClientThread() { while (true) { Context context; while (ContextQueue.Count == 0) { Thread.Sleep(10); } if (!ContextQueue.TryDequeue(out context)) { continue; } lock (ContextMapping) { WebSocketServer client = ContextMapping[context]; client.SetupContext(context); } lock (CurrentConnections){ CurrentConnections.Add(context); } } }
/// <summary> /// Replaces the context in the core and saves the old one in the queue. /// </summary> /// <param name="core"> The core whose context had a context switch</param> private void SwapContext(Core core) { // If context queue is empty then keep running the same thread if (ContextQueue.Count > 0) { var newContext = ContextQueue.Dequeue(); var oldContext = core.Context; ContextQueue.Enqueue(oldContext); core.Context = newContext; core.ThereAreContexts = true; } core.RemainingThreadCycles = Quantum; // Restores remaining cycles to the quantum value. }
/// <summary> /// Fires when a client connects. /// </summary> /// <param name="data">The TCP Connection.</param> protected override void OnRunClient(object data) { var connection = (TcpClient)data; var context = new Context(this, connection); context.UserContext.ClientAddress = context.Connection.Client.RemoteEndPoint; context.UserContext.SetOnConnect(OnConnect); context.UserContext.SetOnConnected(OnConnected); context.UserContext.SetOnDisconnect(OnDisconnect); context.UserContext.SetOnSend(OnSend); context.UserContext.SetOnReceive(OnReceive); context.UserContext.OnConnect(); if (context.Connected) { lock (ContextMapping) { ContextMapping[context] = this; } ContextQueue.Enqueue(context); } }
/// <summary> /// Picks off a context from the context queue. /// </summary> /// <returns> Thre next context of the queue or null if the queue is empty.</returns> private Context GetNewContext() { return ContextQueue.Count == 0 ? null : ContextQueue.Dequeue(); }
/// <summary> /// Method in charge of creating and initializing all data structures and objects needed in the simulation /// </summary> private void InitializeStructures() { /** Initialize the data block of main Memory **/ var dataBlocks = new Block<int>[Constants.DataBlocksInMemory]; for (var i = 0; i < Constants.DataBlocksInMemory; i++) { var words = new int[Constants.WordsInBlock]; for (var j = 0; j < Constants.WordsInBlock; j++) { words[j] = Constants.DefaultDataValue; } dataBlocks[i] = new Block<int>(words); } /* Now we initialize the instruction block of main memory and we fill up the context queue*/ var pc = 0; var blockNum = 0; var wordNum = 0; var instructionBlocks = new Block<Instruction>[Constants.InstructionBlocksInMemory]; Instruction[] instructionArray = null; for (var i = 0; i < Constants.NumberOfThreadsToLoad; i++) { ContextQueue.Enqueue(new Context(pc, i)); var filePath = Constants.FilePath + i + Constants.FileExtension; string line; // Read the file and display it line by line. var file = new System.IO.StreamReader(filePath); const char delimiter = ' '; // Whitespace. while ((line = file.ReadLine()) != null) { // Get instruction from line var numberStrings = line.Split(delimiter); var opCode = int.Parse(numberStrings[0]); var source = int.Parse(numberStrings[1]); var destiny = int.Parse(numberStrings[2]); var inmediate = int.Parse(numberStrings[3]); var instruction = new Instruction(opCode, source, destiny, inmediate); if (instructionArray == null) { instructionArray = new Instruction[Constants.WordsInBlock]; } instructionArray[wordNum++] = instruction; pc += 4; if (wordNum != Constants.WordsInBlock) continue; instructionBlocks[blockNum++] = new Block<Instruction>(instructionArray); wordNum = 0; instructionArray = null; } file.Close(); } // If the instructions in the .txt files did not fit evenly in the blocks. if (instructionArray != null) { // Now we have to fill the instruction array and save it to the last block for (var i = wordNum; i < Constants.WordsInBlock; i++) { instructionArray[i] = new Instruction(); } instructionBlocks[blockNum++] = new Block<Instruction>(instructionArray); } // Now we proceed to fill the remaining empty blocks (if any) with the standard default instruction for (var i = blockNum; i < Constants.InstructionBlocksInMemory; i++) { instructionArray = new Instruction[Constants.WordsInBlock]; for (var j = 0; j < Constants.WordsInBlock; j++) { instructionArray[j] = new Instruction(); } instructionBlocks[i] = new Block<Instruction>(instructionArray); } /* * At this point the instruction block is ready. * Now, initialize the Memory structure. */ Memory.Instance.InstructionBlocks = instructionBlocks; Memory.Instance.DataBlocks = dataBlocks; // Creates the four caches. Two per core var dataCacheZero = new Cache<int>(Constants.CoreOneCacheSize); var instructionCacheZero = new Cache<Instruction>(Constants.CoreOneCacheSize); var dataCacheOne = new Cache<int>(Constants.CoreOneCacheSize); var instructionCacheOne = new Cache<Instruction>(Constants.CoreOneCacheSize); // Set each cache with the other cache connected to it. dataCacheZero.OtherCache = dataCacheOne; dataCacheOne.OtherCache = dataCacheZero; instructionCacheZero.OtherCache = instructionCacheOne; instructionCacheOne.OtherCache = instructionCacheZero; // Creates the two cores of the processor CoreOne = new Core(instructionCacheOne, dataCacheOne); CoreZero = new Core(instructionCacheZero, dataCacheZero); }