Task scheduling - vxworks
My system composed of seven task.
I created some demo RTP in order to examine my system as follows:
int main()
{
taskSpawn("/task1" , 107 , VX_NO_STACK_FILL , 2000 , (FUNCPTR)task1, 0,0,0,0,0,0,0,0,0,0);
taskSpawn("/task2" , 106 , VX_NO_STACK_FILL , 2000 , (FUNCPTR)task2, 0,0,0,0,0,0,0,0,0,0);
taskSpawn("/task3" , 105 , VX_NO_STACK_FILL , 2000 , (FUNCPTR)task3, 0,0,0,0,0,0,0,0,0,0);
taskSpawn("/task4" , 104 , VX_NO_STACK_FILL , 2000 , (FUNCPTR)task4, 0,0,0,0,0,0,0,0,0,0);
taskSpawn("/task5" , 105 , VX_NO_STACK_FILL , 2000 , (FUNCPTR)task5, 0,0,0,0,0,0,0,0,0,0);
taskSpawn("/task6" , 106 , VX_NO_STACK_FILL , 2000 , (FUNCPTR)task6, 0,0,0,0,0,0,0,0,0,0);
taskSpawn("/task7" , 101 , VX_NO_STACK_FILL , 2000 , (FUNCPTR)task7, 0,0,0,0,0,0,0,0,0,0);
taskExit(OK);
}
void task1() { taskDelay(7); }
void task2() { taskDelay(13); }
void task3() { taskDelay(313); }
void task4() { taskDelay(19); }
void task5() { taskDelay(188); }
void task6() { taskDelay(10); }
void task7() { taskDelay(10); }
I ran the RTP and i connected the Performance profiler.
The performance profiler gave me the CPU usage of each task.
What i want to check is that each task executes on time,
for example i want to make sure that task1 executes every 7*16 = 112 millisends
(my system clock rate is 60HZ meaning scheduler invoked every 16 milliseconds)
Questions:
1.Is there any way in the profiler to make shure this is happen.
2.If not how can check this?
Thanks.
I have never used the profiler, so I don't know anything about it, but I have done what you want before in vxworks. Here is how I did it:
1) Spawn a task with priority = 255 (or lower than any of your real time tasks) which consumes 100% CPU as follows:
void lowPriTask()
{
volatile int forever = 1;
while (forever) {}
}
2) Install a task switch hook with taskSwitchHookAdd() and your switch hook callback should keep track (in memory) of the old taskId and the new taskId, and the tickGet(), basically just compile a list of this information in memory.
3) Then when you have run your tasks for a while dump the memory to a file and figure out some cool way to examine it/visualize it, maybe with the help of excel or so.
The reason for this lowPri task is because in vxworks the taskSwitchHook is only called when a task switch occurs (obviously) the subtle detail is that if the system is idle then a task switch doesn't occur. So if you are keeping track of the times when a task switches in and out, and the system is idle then you will have some tasks that appear to be hogging a bunch of CPU time, when in fact the system is idle. Like so:
taskSwitch_In
taskRuns
task is done, but no other tasks are ready, so system goes to idle....
some ticks later a task becomes ready...
taskSwitch_Out
So if you have a low priority task that consumes 100% of the idle time, then that always forces a task switch immediately after any (higher priority) task is done. So you always see a pattern like this:
taskSwitch_In
taskRuns
taskSwitch_Out (to lowPriTask in the event that no other task is ready)
In addition to this it gives you an accurate estimate of how much idle time there is based on the amount of time that this low priority task runs.
It is crude, but it works.
Related
Running jobs concurrently with multiple steps
I need to run 10,000 pipelines, each consisting of 5 steps (processes) Another requirement is that I want to run about 300 concurrently. Meaning, I want 300 to start, then for each pipeline that finished the 5 steps, I want to start a new pipeline. I couldn't find how to do it using channels. Some initial thoughts: start by splitting the 10,000 channel to buffers of 300 items. But it doesn't help with starting a new one when one ends... proteins = Channel.fromPath( '/some/path/*.fa' ).buffer( size: 300 ) process A { input: file query_file from proteins output: } process B { }
You can achieve approximately what you want using the following in your nextflow.config: process { maxForks = 300 } executor { queueSize = 300 } The maxForks directive sets the maximum number of process instances that can be executed in parallel. By setting this value in your nextflow.config, we ensure it is blanket applied to each of your five processes. If you have other processes that you don't want covered by this directive, you can of course use one or more process selectors to select the processes you want to limit this configuration to. Alternatively, just add the directive to each of your five process definitions. The executor queueSize just defines the number of tasks the executor will handle in parallel. This of course won't guarantee the completion of a chunk of five processes before starting a new chunk, but that usually isn't much of a concern.
Coroutines "Asynchronous withTimeout" official tutorial strange behavior
In the official guide "Cancellation and timeouts" section "Asynchronous timeout and resources" there is an example that is supposed to... "If you run the above code you'll see that it does not always print zero, though it may depend on the timings of your machine you may need to tweak timeouts in this example to actually see non-zero values." var acquired = 0 class Resource { init { acquired++ } // Acquire the resource fun close() { acquired-- } // Release the resource } fun main() { runBlocking { repeat(100_000) { // Launch 100K coroutines launch { val resource = withTimeout(60) { // Timeout of 60 ms delay(50) // Delay for 50 ms Resource() // Acquire a resource and return it from withTimeout block } resource.close() // Release the resource } } } // Outside of runBlocking all coroutines have completed println(acquired) // Print the number of resources still acquired } I do not understand how that work. If we let the timeout to 60, instances of Resource are never created. We had to go up to 120 to see instances been created. However 60ms looks enough to let include a delay(50) + an instance creation. No? Does someone could explain that? Thanks in advance.
You should not assume these timings are accurate. delay(50) waits for about 50ms and withTimeout(60) timeouts after about 60ms. I believe both of them gives "at least" guarantee, but they may have to wait practically indefinitely. delay() may wait for a longer time than expected, because there are no free threads to resume. withTimeout() may timeout after a longer time, because coroutine does not cooperate for cancelling. In your case it is possible that it takes more than 50ms for all 100_000 coroutines to get to delay() point. In that case they aren't resumed after 50ms, because they still wait for the thread to become free to handle them. But this is just a guess. Try to replace it with e.g. delay(150) and withTimeout(160). The main point of this example is that if the timeout happens after the delay has resumed, but before the end of withTimeout() block then exiting from withTimeout() will throw CancellationException. As a result, Resource() will be invoked, but resource.close() won't.
The main reason why instance have no chance to be created is that execution of delay(50) and more generally the whole task take lot of time because 100_000 coroutines competing on the same thread don't let much time to execute in the delay. So reducing the number of created coroutines to 10 or 100 (a more realistic situation), tasks look to complete quickly, respecting time and timeout. Here's results Number of | Created | Still | coroutines | Resource | Opened | | instances | Resources | -----------+-----------+-----------+ 100_000 | 0 | - | 10_000 | 8588 | 635 | 1_000 | 1000 | 0 | 100 | 100 | 0 |
Testing Flink window
I have a simple Flink application, which sums up the events with the same id and timestamp within the last minute: DataStream<String> input = env .addSource(consumerProps) .uid("app"); DataStream<Pixel> pixels = input.map(record -> mapper.readValue(record, Pixel.class)); pixels .keyBy("id", "timestampRoundedToMinutes") .timeWindow(Time.minutes(1)) .sum("constant") .addSink(dynamoDBSink); env.execute(jobName); I am trying to test this application with the recommended approach in documentation. I also have looked at this stackoverflow question, but adding the sink hadn't helped. I do have a #ClassRule as recommended in my test class. The function looks like this: StreamExecutionEnvironment env=StreamExecutionEnvironment.getExecutionEnvironment(); env.setParallelism(2); CollectSink.values.clear(); Pixel testPixel1 = Pixel.builder().id(1).timestampRoundedToMinutes("202002261219").constant(1).build(); Pixel testPixel2 = Pixel.builder().id(2).timestampRoundedToMinutes("202002261220").constant(1).build(); Pixel testPixel3 = Pixel.builder().id(1).timestampRoundedToMinutes("202002261219").constant(1).build(); Pixel testPixel4 = Pixel.builder().id(3).timestampRoundedToMinutes("202002261220").constant(1).build(); env.fromElements(testPixel1, testPixel2, testPixel3, testPixel4) .keyBy("id","timestampRoundedToMinutes") .timeWindow(Time.minutes(1)) .sum("constant") .addSink(new CollectSink()); JobExecutionResult result = env.execute("AggregationTest"); assertNotEquals(0, CollectSink.values.size()); CollectSink is copied from documentation. What am I doing wrong? Is there also a simple way to test the application with embedded kafka? Thanks!
The reason why your test is failing is because the window is never triggered. The job runs to completion before the window can reach the end of its allotted time. The reason for this has to do with the way you are working with time. By specifying .keyBy("id","timestampRoundedToMinutes") you are arranging for all the events for the same id and with timestamps within the same minute to be in the same window. But because you are using processing time windowing (rather than event time windowing), your windows won't close until the time of day when the test is running crosses over the boundary from one minute to the next. With only four events to process, your job is highly unlikely to run long enough for this to happen. What you should do instead is something more like this: set the time characteristic to event time, and provide a timestamp extractor and watermark assigner. Note that by doing this, there's no need to key by the timestamp rounded to minute boundaries -- that's part of what event time windows do anyway. public static void main(String[] args) throws Exception { ... env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime); env.fromElements(testPixel1, testPixel2, testPixel3, testPixel4) .assignTimestampsAndWatermarks(new TimestampsAndWatermarks()) .keyBy("id") .timeWindow(Time.minutes(1)) .sum("constant") .addSink(new CollectSink()); env.execute(); } private static class TimestampsAndWatermarks extends BoundedOutOfOrdernessTimestampExtractor<Event> { public TimestampsAndWatermarks() { super(/* delay to handle out-of-orderness */); } #Override public long extractTimestamp(Event event) { return event.timestamp; } } See the documentation and the tutorials for more about event time, watermarks, and windowing.
How to trigger a new state in a timed state machine (solidity)
I am creating a perpetual trivia dapp (for learning purposes) that has 3 stages. Each stage should last approximately 30 secs. Example: enum Stages { AcceptingEntryFees, RevealQuestion, Complete } modifier transitionToReveal(uint _playerCount) { _; if (stage == Stages.AcceptingEntryFees && now >= creationTime + 30 seconds && _playerCount > 0) { nextStage(); } } modifier transitionToComplete() { _; if (stage == Stages.RevealQuestion && now >= creationTime + 60 seconds) { nextStage(); } } modifier transitionToAcceptingFees() { _; if (stage == Stages.Complete && now >= creationTime + 90 seconds) { nextStage(); } } function nextStage() internal { stage = Stages(uint(stage) + 1); } Im struggling with a solution on how to make the stage increment once the time requirement has been met. I don't need exactly 30 seconds by any means. Take the first transition (accepting fees). function payEntryFee() external payable transitionToReveal(getPlayerCount()) atStage(Stages.AcceptingEntryFees) { .... } I currently have it set up where people can pay to play up until the 30 seconds is up. However for the stage to increment a tx has to take place. So for this setup the first person to join after the 30 seconds is up will incur the gas price and trigger the next stage. This is not ideal because what if another player doesn't show for a while. From my research there is no way to trigger a method internally by time and trying to trigger it from the front end would require gas and then who pays it? Can anyone think of an elegant solution to this? I would like the stage to increment every ~ 30 seconds without interruption to the game.
You would either need an external entity, like a game master web application which changes the state using its own timer and sending transactions but that would cost you gas for every single transaction. Or you could keep track of the state on the front end (kind of like syncing) and then whenever the player interacts with the ethereum dapp to make a function call, you could do a fetchState() to get the new state and then route the player to the correct game state. For example, after the web app frontend gets confirmation that the user has paid, it personally keeps track of the state and presents the user with the UI options related to predicted state of the dapp, then when the user sends something like "submitTriviaAnswer" the dapp would update its state and verify that the user can submit a trivia answer. function SubmitTriviaAnswer(int responseID) public { fetchState() ... }
MassTransit capping message rates at 10
I have a mass transit consumer service set up to work with RabbitMQ and I can't figure out how to increase the speed of the consumer - it seems to hard cap at 10 messages received per second. I have tried the steps listed here: https://groups.google.com/forum/#!msg/masstransit-discuss/plP4n2sixrY/xfORgTPqcwsJ, with no success - setting the prefetch and the concurrent consumers to 25 does nothing other than increasing the acknowledged messages, but it doesn't increase the rate at which the messages are downloaded. My config is as follows: ServiceBusFactory.ConfigureDefaultSettings(x => { x.SetConcurrentReceiverLimit(25); x.SetConcurrentConsumerLimit(25); }); _bus = ServiceBusFactory.New( sbc => { sbc.UseRabbitMq(x => x.ConfigureHost( "rabbitmq://localhost/Dev/consume?prefetch=25", y => { y.SetUsername(config.Username); y.SetPassword(config.Password); })); sbc.UseLog4Net(); sbc.ReceiveFrom("rabbitmq://localhost/Dev/consume?prefetch=25"); sbc.Subscribe(x => RegisterConsumers(x, container)); sbc.UseJsonSerializer(); sbc.SetConcurrentConsumerLimit(25); }); I'm setting the concurrent consumer limit in two places as I'm not sure whether I need to set it on the default or in the bus configuration, and the consumers are registered via unity - I have omitted the consumer subscription as all subscribers are receiving. I'm a little confused as to whether there's anything else I need to set or if I need to change the order in which I'm setting the configs. Any help greatly appreciated.
After spending a romantic evening with the problem and trying out different things suggested by Chris, I've found out that there is yet another thing you have to do to make it work like it should. Specifically, yes, you need to set the prefetch on the consumer queue address: sbc.UseRabbitMq( f => f.ConfigureHost( new Uri( "rabbitmq://guest:guest#localhost/masstransit_consumer" ), c => { } ) ); int pf = 20; // prefetch // set consumer prefetch (required!) sbc.ReceiveFrom( string.Format( "rabbitmq://guest:guest#localhost/masstransit_consumer?prefetch={0}", pf ) ); But this is still not enough. The key is available in the code of the mtstress tool Chris mention in his comment below his answer. It turns out the tool calls: int _t, _ct; ThreadPool.GetMinThreads( out _t, out _ct ); ThreadPool.SetMinThreads( pf, _ct ); Adding this to my code resolves the issue. I wonder though why this is not required with MSMQ transport, though... Update #1 After further investigation I've found a possible culprit. It's in the ServiceBusBuilderImpl. There is a method to raise the limit, the ConfigureThreadPool. The problem here is that it calls CalculateRequiredThreads which should return the number of required threads. Unfortunately the latter returns a negative value on both my client Windows 7 and my Windows Server. Thus, the ConfigureThreadPool effectively does nothing as the negative value is then ignored when calling ThreadPool.SetMin/MaxThreads. What about this negative value? It seems the CalculateRequiredThreads calls ThreadPool.GetMinThreads and ThreadPool.GetAvailableThreads and uses a formula to came up with the number of required threads: var requiredThreads = consumerThreads + (workerThreads - availableWorkerThreads); The problem here is that on my machines this effectively does: 40 (my limit) + 8 (workerThreads) - 1023 (availableThreads) which of course returns -975 The conclusion is: the above code from the Mass Transit internals seems to be wrong. When I manually raise the limit in advance, the ConfigureMinThreads respects it (as it sets the limit only if it is higher than the read value). Without setting the limit manually in advance, the limit fails to be set and thus the code does as much threads as the default thread pool limit (which seems to be 8 on my machine). Apparently someone assumed this formula will yield 40 + 8 - 8 in a default scenario. Why GetMinThreads and GetAvailableThreads return such unrelated values is yet to be determined... Update #2 Changing static int CalculateRequiredThreads( int consumerThreads ) { int workerThreads; int completionPortThreads; ThreadPool.GetMinThreads( out workerThreads, out completionPortThreads ); int availableWorkerThreads; int availableCompletionPortThreads; ThreadPool.GetAvailableThreads( out availableWorkerThreads, out availableCompletionPortThreads ); var requiredThreads = consumerThreads + ( workerThreads - availableWorkerThreads ); return requiredThreads; } to static int CalculateRequiredThreads( int consumerThreads ) { int workerThreads; int completionPortThreads; ThreadPool.GetMaxThreads( out workerThreads, out completionPortThreads ); int availableWorkerThreads; int availableCompletionPortThreads; ThreadPool.GetAvailableThreads( out availableWorkerThreads, out availableCompletionPortThreads ); var requiredThreads = consumerThreads + ( workerThreads - availableWorkerThreads ); return requiredThreads; } resolves the issue. Both return 1023 here and the output of the formula is a correct number of expected threads.
What amount of work is being performed by your consumer? If it runs fast enough, it's likely that the .NET runtime need not create additional threads to handle the inbound message rate. We have many systems in production that use specified counts where we match the consumer limit with the prefetch count, and in all of those cases under load, the unacknowledged message count shown by RabbitMQ is equal to those settings. We typically see nearly the same number of threads processing messages. Initially the .NET runtime is conservative in the allocated threads used, but it quickly ramps up to the full thread count when consumers are simply waiting on a remote operation such as an HTTP request or SQL command. If there is an area of the consumer that is single threaded, it might be limiting thread scaling based on that bottleneck, so verify that your threading model is properly configured as well.