All righty, welcome back to 353.  So, how many of you have done the lab four pre-lab thing? No one? Would make you feel better if it was due like Saturday? Yeah. All right, it's due Saturday, whatever. Even though it takes like 15 minutes, but still, whatever. You have three midterms this week, although, yikes. All right, so, we get to talk today about semaphores. Oh, and I guess I'll also release feedback forms and other stuff to look forward to. So, we get to learn about semaphores today. We should review locks, so locks ensure mutual exclusion. We can have a lock and an unlock called a critical section. Only one thread can be executing that code at a single time. Doesn't help you ensure ordering between threads, so how would we ensure some ordering between threads? Well, hopefully that's the topic of today. So, here is our problem. So say we have two threads. They both have a print line. One prints, this is first. The other says, I'm going second. And then, if we actually execute this, well, we should be able to reason about things that it could do. So, most of today will be fun code examples. So, here is that code. So, in the main, we create two threads. Tell one to run print first. Tell the other to run print second. And then, once we've created two threads, which one runs first? Don't know, all right. Everyone should be shrugging their shoulders. Don't know who runs first. So, after that, we join them. So, the main thread waits for them both to terminate, but we don't know which one is going to run first. So, if print first runs first, we get this is first. Print second runs first, and we see I'm going second first. So, if we go ahead and run this. So, I execute this. I see I'm going first, I'm going second. Does this mean I am a programming God and this happens every single time? Yes. Yes, no bugs. And we just send it, goes off to production. And what happened yesterday? All meta shut down. So, we just killed meta, yay. Probably not a bad thing. All right, oh, I executed again. Oh, now it's wrong. Okay, now I'm the worst. So, do we know how to solve this with, can we solve this with mutexes? So, let's think. Is there a way to ensure ordering between threads using mutexes in a way that is actually not undefined behavior? So, I will argue maybe watch me be a programming God. So, I will create a mutex here. I'll call it mutex and then I'll just initialize it. Say I always want to run this is first. So, what I'm going to do is I will put a pthread mutex lock right here. So, it's called mutex. So now, if I put a lock right there, well, that would acquire the lock and then this doesn't help me yet. So, I'm not quite there. So, I want to definitely prevent this line from going first. So, maybe I just like try locking again. So, I lock it and then I have the lock and then I will try to acquire it again, which would prevent me from running, I'm going second, but right now that would just prevent me from ever running, right? If I run this, it should freeze. Oops, that's the other course. So, it should just freeze and all I'll see is this is first because the other one's just waiting over and over again. All right, so here's where I become a God. I do this. So, I just have this thread unlock the mutex after it prints. So, now if print first executes first, well, let's say print second executes first. So, it locks the mutex. Okay, so it has acquired the mutex. The value has changed from a like zero to a one and then we lock it again. So, it's waiting for something to unlock it and then I execute the first thread, prints off this as first and then I unlock the mutex. So, now it can relock it and then print I'm going second. Does this work? Am I a God? Well, we can execute in C.  Yeah. Yeah, so I never unlock it again. I could do that. I could just do this. Yeah, yeah. So, I have one bad situation here. So, remember, these two things run concurrently so we don't know when they can switch back and forth. What could happen, which isn't great, is print first executes first, prints off this as first and then unlocks, which the mutex currently is unlocked. So, unlocking and unlock mutex is undefined behavior. So, we have just screwed ourselves there and then also if we did that, then the second thread would lock, let's just assume that unlocking and unlocked mutex just did nothing. Well, then the second thread's going to just lock, lock and then it's going to be stuck there forever. So, if we run this, you'll see that it actually works. Most of the time, except when it doesn't. And when it doesn't, it's because the second thread here is stuck on this lock and the first thread already called unlock, so nothing is ever going to unlock it. It cannot make any progress. So, questions about that? Close, kind of a clever idea, right? I was kind of close. So, we'll see how to fix this. Oh, and also, what we need to argue about too is, well, we're kind of assuming printf is also atomic here. So, we assume that it just doesn't print everything all at once and that it, like we don't get something weird because an implementation of like printf, it could do like three system calls, right? It could do like this is first, all with different system calls and then the other printf could be also three write system calls. And if I go ahead and I run this, okay, sometimes it works, this is first, this is second, but sometimes when I execute it, there, I got something weird. I said, this, I'm, is, going, first, second. Could we fix this? Yeah, we could probably just fix this with a mutex, right? If I just, here, I just won't write the whole thing. If I just create a mutex here and then I lock, unlock and then do the same thing for the print statement, then that would fix it. So, that way I get a whole line at a time. I don't, I can't get switched halfway between it because if it has a lock and you switch back to the other one, it couldn't acquire the lock and we get stuck. Yeah, so, like why don't I have it around the regular printf statement? So, the reason I don't have it around the regular printf statement is it turns out that printf is thread safe, so it kind of behaves atomically. So, now whenever you use any function and you have multiple threads, you get to look it up and see if it's thread safe or not. Okay, that's the wrong printf. So, now you have to look at your documentation and at the very end of it, wow, it explains printf, a lot of printf, there we go. There's this attributes table and then there's one attribute that says thread safety and then if its value is mt, so multiple thread safe, then it goes ahead, it locks itself properly, it won't have any of the issues where we see with this one where we might see some letters interposed with the other one, so we don't need locks for it because they essentially guaranteed us that they have done it already.  Yes or no? And most of the time it's in the documentation. Some, and if you're using someone's library and they don't say whether or not it's safe to use with threads, assume it is not safe and they don't know how to program it, especially if they don't know what the hell thread safety even means. So, back here. So, do you still see mist up if you write? Yeah, so in this case, if I went back to this and I did all in one system call, the system call will kind of behave atomically, so system calls are thread safe, thankfully, so we'd see the correct thing. Yeah, yeah. So thread safe in like the printf context means it won't, like if you have multiple threads calling printf, they won't interfere with each other. But if you give printf like arguments that might have a data race in your code, that's your fault. So, yeah, if I tell it to print a value that might be subject to a data race, your fault. It only guarantees that the printf itself is gonna all happen or all not happen. All right, so we want to fix this issue. So, we can't use mutexes. Oh, yeah, and another thing. Whoops, so if I go back here. So there's actually two things of undefined behavior here. So locking and already lock lock, well, that's technically undefined and you'll lock forever. And also, if it was successful and this one say locked twice and waited, well, remember what I said before, unlocking a mutex that you did not lock is also technically undefined behavior. So when it worked, it worked by chance. Technically, if we referenced the sea gods and all their rules shouldn't have worked, wasn't guaranteed to work, it just happened to work. All right, so center fours are the thing used for signaling. You might have heard this term before, probably not, has to do with like ship signaling and they have a bunch of weird flags and stuff like that. Thankfully, this one is a lot less complicated than that because it's basically just a number. So center fours, the way to think about them is that they're just like an int, they just have some value and it's shared between threads. Optionally, you can use it to share between processes as well, but just think of it as an unsigned integer or if you don't want to use the word unsigned, think of it as an integer that is always greater than or equal to zero. And we have two fundal operations we can do with it, a wait and a post and they operate pretty simply. So the wait, all it will do is decrement that value atomically and a post will increment that value atomically. So the only thing that makes this useful is this following rule. So wait doesn't actually return until the value is greater than zero. So if the current value of the center four is zero and you call wait, it will sit there and actually block and wait until another thread increments it from a zero to a one and then it can go ahead and decrement it from a one to a zero. So that number is never allowed to be negative. If you call wait and it's currently zero, it will sit there and wait for another thread to increment it. So initially we can set the initial value of the center four to whatever we want. And basically you can think of that as that's the number of wait calls that can happen without any post calls. So the API, kind of similar to pthread locks except it's in its own header file. So there's a center four.h. Do not use this on macOS. They decided they didn't like this and it essentially does nothing. So that's fun. So just like pthread mutexes, we can initialize it, takes three arguments. So a pointer to the center four structure itself. There's this optional parameter pshared. So that's whether or not it should be shared whenever we fork between processes. So if we just set to zero, it is independent for the process and then not shared, but shared between threads. And then that value is just the initial value of the center four. When we're done with it, of course we should destroy it. And then there's the wait. So that will decrement that value atomically and only wait if the current value is zero for another thread to increment it. There's also a try wait if you don't want to block. So you can just try to decrement it and it will tell you yes or no whether you successfully decrement it. Then there is post and post just increments that value. So like the pthread library, all of them return zero on success. And let's just not worry about this pshared argument. If you want to use it for inter-process communication, you can for this course, we'll just argue about center fours just within a process with threads. All right, so with the center four, we should be able to fix this problem. So the way to think about doing center fours is you have to do three things.  So easiest thing I like to do is the first thing you should do while it's probably the fine one. So we can just say, let's just name it SEM and I need to include the library. Hold on, let's go to center four dot eight. All right, so first thing I need to do is create the center four and after that, the first thing I like to think about is where do I need to place my weight, right? What do I need to prevent from running? So in this case, I want to prevent this function from running and well, if I want to prevent this print line from running first, I should probably place my weight like right before. So I should probably do a weight here. So if I do a weight here, well, I haven't initialized it, so I should next think about what the initial value of the center four should be. So I can call SEM and knit, give it the address of the center four. I don't care about p shared and then I need to think about this initial value. So if I set the initial value to one, will that do me any good? Probably not. So if I set the initial value to one, well, let's say either thread could run first. If print second actually gets picked to run first, we hit SEM weight. If the current value is one, it can decrement it from a one to zero and it won't do anything to prevent that from going first. So it's fairly useless like that. I can't make it negative. So if I want it to actually wait there, then I should set the initial value to zero. So now if thread or print second actually executes first, well, then the current value zero, it tries to decrement it, it's not allowed to, it has to block until another thread posts. So now I can think about, okay, well, when should I let the second thread actually make some progress? And where should I place my post? Well, if I place it here, will that likely work? Probably not, because what could happen is, okay, maybe this thread gets scheduled to go first, so it waits, so the current value is zero, it waits, it blocks, and then we have no choice, eventually we have to schedule print first, then it would increment that value from a zero to a one, and now we could switch back to print second because it could now be unblocked because now it could decrement it from a one to a zero, and then it could do this print f first, so we should probably just move it down one line so that the only way that this second thread is going to run this line is after the first thread is done with its print f function, and then it increases the value from a zero to a one, and then print second can go ahead and unblock it and actually work. So now if I run this, that was a called order print, I get, this is first all the time, and then I'm going second, and it always works. So questions about that signaling too? Where'd you get the word signal? Oh, so signaling in like the English word, signaling, yeah, so if you wait on it and you're blocked, it kind of waits for another thread to do a post, and then it'll be like, it'll wake you up and you can actually successfully get by the weight and actually do something. So that's what I mean by signal on that slide, like pretty much just unblocking it because you posted it so you're kind of poking other things that, hey, you can run now, I'm done whatever I need to do. All right, other questions for this? Yeah, so on macOS, you can't use this because the cypher board doesn't have a name, macOS forces you to name them, so it just gets more annoying. And another question, why can we do mutexes? We started off trying to do mutexes, but we couldn't. So might have to review that. In this silly example, oh, yep. Oh, what about if we have three threads? Okay, that's a good one. What was your question gonna be? Yep, you can do multiple posts in a row, multiple weights in a row. Yeah, you could just post over and over again. I could post 10 times in a row. It just atomically increments. Yep, or I could set the initial value to 10 or do whatever. So yeah, we have this question. So if we have something that wants to print, all right, let's make it excited. So I'm third. So that's a good question. What do I call it, print thern? I probably should have put that in a loop or whatever. All right, so yeah, let's think about this. Oops, non void function. Sorry, return null. So yeah, now if I run this, it should always print, I'm going first, I'm going second, but we have no idea where the hell I'm going third is gonna be, right? Could be first, could be second, could be third. So let's make sure. So second, it seems to like going second or sometimes third. Doesn't seem to like going first that much. So how would I fix this? Yeah, yeah, so in this case, I can't really reuse that same center for because let's say I just did this. So now I have two threads waiting. So now I have two threads waiting and in this case, while the initial value is zero, so let's say either thread executes here and this is kind of like what an exam question would be. So now either thread could run first, current value is zero. So both threads get blocked. The only thread that could run is the first thread. This is first would definitely print first and then it posts. So now it changes that value from a zero to a one and well now both of them could make it by weight but only one can make it by weight this time, right? So we'll either see I'm going second, I'm going third and then nothing, right? We have no idea. So if I go ahead and run that, let's see that I'm right. So now I saw, oh, the first one and the second one and then the other one got stuck and then oh, now I got good luck. This one, the third one run, not the other one. So this, if I wanted to not have any order, I could do what you suggest and just do two posts. So if I do two posts here, I won't have that problem where one gets blocked forever. So they're both waiting and then once print first is done, it increments it twice. So zero to a one and then a one to a two or it could do it in a slightly different order. Let's just say it was two. Well, if it's two, both of these can pass weight. Again, we don't know what order they're going to be in but at least both of them are going to print now. So still didn't quite solve a problem. We got some of the way there where this is first always goes first. But like you said, we probably just need another center for. So to fix this, we just create another center for, I'll name it SEMA2 because I'm creative and we could just go ahead, initialize it with the value zero and kind of do the same thing again. So this was our solution for a single like this is first, always printing first before this is second. So we can do the same idea before. So this is third has to wait for this is second to print. So it could wait on the center for its initial value zero. So it can't make any progress. And then we could post it only after we print this only after we print I'm going second like this. So now I have two center for's now when I run it, it's always going to be an order all every single time. Yeah, yeah. Yeah, there's not really any smarter thing to do than this. You could write it in a loop or something like that to help you out, but yeah. So if you wait on the first and post, wait on the first and then wait on the second and then post the first, well then essentially if you only use two center for's and say you have a hundred things, you've like 50 of them waiting on like waiting on the first center for 50 of them waiting on the second and then they post the other one. So when you post it, you don't know which of the 50 is going to run. So you would need 99 otherwise you've no idea. So yeah, a lot of people, so don't get into the trap of like trying to reuse center for's cause probably it will be wrong. Even if it seems to work some of the times and yeah, another question about doing try weight instead of weight, I'd have to add like air handling code to it. So like I could maybe it's like a performance sensitive application. I could do try weight and then if I didn't decrement it means I shouldn't print third, but I might do something else that's like independent for the thread, things like that. And yeah, so that works for that. We'll see a more complicated example at the end. So here's the solution for you. So one, just make a center for weight in the second thread post in the other one and now they work all every single time. So you might notice that set of four is kind of maybe look like a special case of mutexes. So turns out that we could actually use the center for as a mutex. So how would we do that? They kind of look the same, right? Yeah, yeah, close. Yeah, so you set the initial value to one and then instead of lock, you do weight. So only one thread could make it go from a zero or a one to a zero. If another thread tries to weight, same thing as locking only ensures mutual exclusion. And then instead of unlock, you post. And as long as you follow that, so the only difference is mutexes would have to like the lock and then the unlock would have to come for the same thread for set of fours, you don't have that restriction. But if you were careful and you always made sure that instead of lock, I did weight and instead of unlock, I did post and I set the initial value to one, then it behave exactly like a mutex. So if you want mutual exclusion, even though you could use the center for mutexes are a bit easier to understand because you don't have to set an initial value but if you really wanted to, you could. So you could do like that count example here where I set that center for the initial value to one and then instead of lock, I do weight instead of unlock, I do post. I would suggest against that because it's very easy to screw up. So it being correct depends on this initial value which is typically far away from the code. You might not even be able to find it if it's a big code base. If someone comes along and changes this one to a zero, what happens, you're screwed. So whenever it calls weight, it'll just block there forever. If someone comes along here and changes the one to two, you're also screwed. You don't have mutual exclusion anymore. So point of the story is if you want mutual exclusion just using mutex, it's a lot harder to screw up than using a center for for mutual exclusion even though you could. Good rule of thumb is if I wanna sure a border between threads, use a center for. If I wanna ensure mutual exclusion within a thread, use a mutex. So now let's make our problem way harder. So can we come up with a solution to this problem? So assume you have a circular buffer. What's a circular buffer? Just a fancy word for just an array that if you make it to the end and you go to the next element, it just circles back on itself and restarts and goes back to the first element. So we will assume we have a circular buffer and we have a bunch of consumer threads that are going to read the data from it and do something and then producer threads which are writing data to this. So the rules are the producer thread should just write data to the buffer only if it's not full. So let's say we have a lot of producer threads. Well, if it fills up the entire buffer with values, we don't want it to overwrite values that a consumer has not read yet. And similarly, while the consumer should only read data from the buffer if it's not empty. So if it has no data in it initially, the consumer shouldn't just read some random data. It would be useless and probably be wrong. So the rules for this to make it a bit easier too is all the consumer threads share an index and also all the producer threads share an index. And I went ahead and made sure they were thread safe so that when we have multiple producer threads, they would fill up in order and they wouldn't interfere with each other. And initially they both start at zero and they increase sequentially. Yep, yep, so we already skipped ahead to the solution. So let's look at the code and we will develop the solution. So here we go. So this is a lot of code. So this first while thing, I probably should have just hid this from you. So internally it's using center force to just figure out how many values it needs to produce and consume. So you can just read this while, like while there's still something to produce because I'm assuming I have a finite amount of something. In reality, you might just have this running forever. So in order, because this is the producer code, I will just sleep for a little bit of time, simulate doing some work that I'm assuming is independent per thread so they can all run in parallel. And then I will fill a slot. So that is going to be all thread safe. So it's just going to start filling slots, starting at slot zero. It's just gonna be an array up to, I believe in this case, my array holds 10 elements. So start just filling them up in order. Now the producer or the consumer, same thing. So it is just going to consume some data. It doesn't have to wait because, or it doesn't have any work to do until it gets some data. So first thing it does is empty a slot and then it simulates doing some work on that value. It could be doing anything that is fun. So if I go ahead and run this just as is, I don't have any synchronization between them whatsoever. And let me see what the default values are. So I can say the number of producer threads, the number of consumer threads, and then optionally the number of elements to produce, the size of the buffer, and then how long each of them takes. So I'll just say, let's say we have, I don't know, four producers and four consumers. So if I run this, chaos assumes. So if I go back at the beginning, I essentially print a red message anytime something bad happens. Now there's two bad things. There is emptying a slot. So the rule should be that you do not empty a slot that has not been filled up yet. So first thing that happens is one of the consumer threads tries to empty slot zero. It doesn't have any data in it yet. So it complains at me and turns out it looks like all four of my consumer threads run before any of my producers and they all just read invalid data, which isn't good. Then we go through my producer threads, fill up those slots, but the consumer threads are still just chugging away and they're emptying more slots. Then we fill some more slots and then it empties some more. And then finally it loops back from slot nine all the way to slot zero because it's a circular buffer. There's only 10 elements. So this actually read valid data. This actually read valid data. And now we are filling slots eight, nine, zero and one. So that's okay because it just emptied out this slot so we can fill it again. And then it empties out some more slots. We fill some slots and we are good. In the case where we have, let's see, more producer threads and consumer, well, we have more producers. So eventually we get to the situation where we essentially lap the consumer threads and we start filling slots that are already filled. Yeah. So fill slot will write a value to that buffer and then empty slot will read a value from that buffer and since we read it, it should be able to be reused for something else. So shouldn't we all? Yeah, so we have a few things we need to solve here. So first, like I said, probably easier to think about like placing weights and giving center fours names. So there were two problems with this. One was emptying a slot that isn't filled yet. And the other was filling a slot that is not empty. So maybe I make a center four, let's say I call it. So some try weight just goes ahead and tries to decrement it. So this is just a silly hack to make sure that between all of my producer threads, it produces 15 values and all my consumer threads consume 13 values or 15. So don't wait about that. That's just some, yeah. Basically this just takes advantage that this will just atomically decrement it and it's atomic. So the body of this will only run 15 times between all of my producer threads. And then once it's zero, well, it's not successful and then it just finishes all my producer threads. So just a little hack so that between all my producer threads, they run 15 times and all my consumer threads run 15 times. All right, so in order to fix the first problem, I might create a center four called number of filled slots. So with that, first thing I want to think about is when I should wait. So I should probably wait right here before the empty slot. So I could do weight on a filled slot. So this would make sure that none of my consumer threads would run hopefully what I want before my producer threads run. So I want to prevent them from running immediately so they don't read any invalid data. So after I place that weight, I should probably think about what is the initial value of that center four I want. So let's say, what was it called, filled slots? So what should that initial value be? Sorry? Zero, right? There's initially no filled slots. Yeah, so yeah, initially everything's empty. So if that initial value is zero, well, if I place a weight here, that makes sure that no consumer threads will run before any producer threads run, right? So now I can think about the post. Well, if I fill a slot, I have filled exactly one slot. So I should probably just post that value. So if I post it, whoops, that will let exactly one of the consumer threads make it by weight, right? So if one producer thread fills up one slot, well, we post once. So now one of my consumer threads can run, empty the slot that just got filled up. And let's say all four producers ran first, well, we would post four times. So the value that center four would be four. And now exactly four consumers could make it past this weight. So we could decrement it from four to three, three to two, two to one, and then one to zero. And then all the other ones have to wait. So if we run that, hi, we fixed it, right? No red, all good. Am I done? Yeah. Yeah. Yeah, so this one happens to work because in this case I have more producer threads and consumer threads, so they kind of lag behind. But if I made two producer threads and four consumers, likely when I run it, okay, we're not gonna get unlucky. Okay, it still seems to work. Still seems to work, god damn it. Oh, okay, that one's, there's way too many. Oh, more consumers. Oh, more producers, all right. There we go. Okay, didn't think that through. Yeah, so if we have more producers and we have more consumers, the consumers or the producers start lapping the consumers and then we get into the situation where we are writing or we are trying to empty a slot that is already empty. So we kind of lag behind. So in order to solve the other issue, we want to essentially have another set of four that keeps track of the number of emptied slots, right? So if we keep track of the number of empty slots, again, we should think about where we want to put the weight. We probably want to wait here, so we want to wait for the empty slots. So now we can think about what the initial value of emptied slots should be. Oops. So should the initial value of emptied slots be zero? No, what should it be? Yeah, it should be n where it ends the buffer size because right now, if we said that zero, well, producer threads should be able to run first, but then they would all hit weight and current value is zero, so they all block there. And then current value of the filled slots, therefore, is zero, so they all block, they all get weight there. So if we want to think about how many could run at once, well, they could all run in parallel, like up to 10 of them could all run in parallel and all fill up the buffer. So we want to be able to let 10 of them work. So it turns out that I defined the buffer size. Yeah, so there's a variable called buffer size. So we should set the initial value to the buffer size so that way we could have, in this case, all 10 go. So next thing we need to do is place the post and all we want to do is put the post here. So after we empty a slot, we just post up the number of emptied slots. And now, if we run this, okay, boom, no problem, they're all waiting, right? No way that they can't wait out of order or anything like that because everything is bound by their center force. So there's one center for keeping track of the number of filled slots, one keeping track of the number of empty slots and those two by themselves just enforce all of our rules. So any questions about that? Yep, so I just wrote that just because that demonstrated our problem too where there was like, we started emptying slots that were already empty, I think we're writing the slots that were already filled. Yeah, so that was just to demonstrate the other one. I could change them around. So let's say I have 10 of each, boom. So I could have 10 of each, I could have 10 or one producer, 10 consumers in which case, well, because I have that, they're essentially all bottlenecked on the one producer. So as soon as we fill a slot, one of the threads goes ahead and immediately empties that. So, but if I have five and five, they kind of alternate and you could see how this affects them because maybe the consumer takes less time than the producer and then the number of threads that would be optimal might change depending on your workload. And yeah, why do I have a weight here? Okay, you're not sure, I might have to do the discord comment after, but so this will always work, right? Any arguments about that? And the nice thing about this is, well, this thing that's actually simulating doing real work, which is hopefully most of your program, this can be all done in parallel with all the other producer threads and all the other consumer threads, they don't have to be mutually exclusive because, well, we're assuming that they're independent and then if that was fast enough, this thing would use all of your cores, it would be super fast and it would be great. Yeah. Yep. Yeah, so, so depends on how we implement weight. So it might be like mutex where it might keep like an order if who called weight in what order and then unblock them in that same order if your question's fairness. Yeah, so the implementation probably will do something with fairness. So that, yeah, I don't have to worry about it. And in terms of using this, like even if it wasn't unfair, it would still work. It might not work as good as you would like. And in that case, you just blame whoever wrote that and use someone else's implementation, that's better. But with all things in computing, oh, maybe that's like way slower and then maybe you wanna use something that's unfair and it seems to work out for you. Again, who knows. All right, any other questions with this? Yeah, yeah. So to do this in practice, like this fill slot has to be thread safe. So it writes data to it in a way that another thread won't try and read what we're currently writing to it. So if you look at, so you have all this, I made it thread safe because I did mutex locks. You don't have to actually read this stuff, but it's all there, so it is all thread safe. Yeah, so there's one mutex that protects fill slot and empty slot because they're both modifying the buffer. So there's a potential data race there, right? So I have to have a lock. Safest thing is just to put it around the whole thing. That way I don't have any issues. So the idea is fill slot and empty slot cannot run in parallel, but that is like reading and writing a value to a buffer doesn't take very long and you would hope that this dominates. So this, that sleep can be done in parallel, assuming that they're all independent. But yeah, if you wrote this and then the amount of work you have to do in each thread takes less time than it does to actually get data from the buffer, then probably you just don't wanna use threads and it's just gonna make things slower. But always the thing in the follow-up course for that, you'll learn tools where you can go ahead, profile it and see if it's worth it or not. All right, so solutions are on the slides. So yeah, so we use center fours and share proper order, have an initial value we can choose, increment it using posts, decrement it using weight. They're both atomic, weight blocks at the current value is zero. Still need to prevent data races. This should only be for ordering. So just remember, phone for you, all in this together.


What does it mean to know a pain so intense, so all-consuming, that you no longer chase anything in existence other than the meager scraps of relief that are forever outside your grasp? No longer is pleasure a concept to entertain nor comfort nor joy merely the cessation of suffering. Pain can drive one to madness stripping away the self in a crushing vortex of agony so that nothing but a crazed broken thing remains in place of something once whole. Greater pen men than I have wondered if fury could possibly do the same to the being that stalks the stars once more. I believe they are one and the same. It is truly an abomination, a thing of material artifice wedded to one of the cardinal aspects of primordial annihilation. The brain, the self, the mind boiled into a toxic sludge of corrupted instinct, the iotus of something once human consumed now in fire and blood. Empathy, dead and gone, murdered by hatred itself, replaced with what its abominable patron needed most. A slave and one too far gone in every single respect to realize how much a slave it truly is. It is a comfort others no doubt indulge in, to imagine that nothing remains of the individual this thing once was. It helps us reconcile the horror of it all, that the monster that howls at the gates is no longer what he was born as. I doubt this. I believe quite staunchly that the nearest shard remains, but it is tumourous, swollen in aspect. The hatred, the fury, the rage. It is not granted anything remotely approximating consciousness, of course. A slave doesn't need to think. A slave doesn't need to know that it is a slave. A weapon simply fires, bludgeons, stabs. Woe betide us, oh benighted humanity, that the sins of our past stalk about the realm with this reckless, unthinking odium. Know then, that this is a record of the fate of Battlefleet Quartus, of the Malak Calamity, and of the reemergence of one of the most truly abominable foes the Imperium has ever stood against. The Continuance of the Saga of the Arcs of Omen. Upon its launch at the beginning of the Endometous Crusade, Battlegroup Quartus had departed with much fanfare and great hazzaz. As with its sister fleet of the Primarch Reborn's Grand Endeavour, it slipped those first moorings possessed of a fierce conviction. The Imperium, still reeling from the horrors of the Noctis Aeturnus, still bereft of hope in the face of the birth of the Kikatrix Maledictum, nevertheless resolved to strike out, to reclaim those worlds recently lost, to stand against the hordes of the arch enemy and bring order to a chaotic galaxy. These flotillas were truly vast things, hundreds of ships bearing billions of souls from all arms of the Imperial military, possessed of martial strength enough to bring entire sectors firmly back under the boot of Terra. Quartus, for instance, was bound to push into the galactic east and west of the segmentum solar, intended to follow the primary fleets of the Crusade, in securing and fortifying those systems its forerunners had swept through, as well as subdividing its forces to purge nearby volumes of space of remaining hostiles. While perhaps a role not necessarily redolent of glory, the Fleetmaster, Trinicus Abcondis, was nevertheless resolved to his duty, counting it as a supreme honor to have been assigned such a role by none other than Rebut Gulliman himself. When the Son of a God has deemed something a necessity, that is all one should need to hear, after all. His best comportment, and that of those under his command, would be given to Quartus' role. But despite these noble intentions, the challenges rapidly increased. Three sub-battle groups were dispatched to the Bargeist Stars to reinforce the rift stalker's chapter of the Adeptus of Stardes, only to become embroiled in a conflict against a massive orc horde, committing them essentially indefinitely. Next, another sub-battle group suffered losses of almost two-thirds when its bellicose aristocrat of a commander ignored obvious warnings to blunder into a trap laid by the Night Lords and the Alpha Legion, heretic Stardes. The supposedly pacified, agorad belt erupted in a gene-stealer infestation, bleeding the rearguard of strength, while incessant Zenos raids, the assassination of a famous prognosticator, and even a heretic Astartes raid upon the flagship befell the reeling battle group. Fleetmaster Abcondis was wounded in the latter engagement, painstakingly recovering and unable to attend to his duties as everything from supply chain woes to localized warp storms ground battle group Quartus' progress to a standstill. Whispers moved throughout the souls aboard the Armada's vessels, as whispers are wont to do. Musings that if battle group Quintus, the ill-favored and, according to many, cursed fleet of the crusade was so poorly fairing, what must the Primarch feel of Quartus? Even as Fleetmaster Abcondis was able, albeit painfully, to return to the command throne of the battleship Honor of Terra, the material conditions in the fleet's local volume only continued to worsen, rendering warp travel near suicidal and silencing the astropaths of the ships to quiet lunacy. In desperation, Master Abcondis bade his subordinates to seek out any means, even so far as to liaise with the most radical of rogue traitors, that may give his Armada some chance of keeping up with the demands of the endometous crusade. His salvation would come from an altogether oblique angle, and the humble, shaven-headed form of inquisitor Gloria Imagna presented herself upon his bridge. Abcondis no doubt felt his judgment had come. Despite presenting herself as a simple penitent, Imagna was a hereticus inquisitor of implacable ruthlessness, a paragon of her ordo in her utter loathing of psychers and all psychana. To her, such beings were not human. They were merely tools and weapons in human form, granted existence by the will of the God Emperor to be utilized by the Imperium in whatever way they could be most efficacious. The sight of any inquisitor is rarely one to elicit anything other than dread, such a grim-faced member of the hereticus even less so. Yet Imagna came to the Fleetmaster not with a bullet, but with glad tidings. In the nearby Malak system, upon its planet-primus Malak Bale, her agents had uncovered a mighty boon to the Imperial war effort, a device, archaeotech born of the dark age of technology, that possessed potentially incredible power. Had such word come from any but an inquisitor of her standing, it would be cause for immediate suspicions, and even still Fleetmaster Abcondis was initially quite ill at ease. Imagna was nevertheless firm. She stated forthright that the device had been subject to the fullest spectrum of tests her magi could perform, and all were, according to her, the most devout and dogmatic of the machine-God servants. The machine had nary any hint of immaterial corruption, nor possessed a trace of the abominable intelligences so often found in devices from that benighted period of human history. She named the device the Coral Engine, and stated that, if fed the correct crop of human psychers, it would produce an immaterial beacon, a pharros in the warp, that would be second only to the Astronomicon, the guiding light of the Emperor himself, by which all ships set their courses galaxy wide. Imagna, like so many of her inquisitorial colleagues, was not precisely forthcoming with the full nature of her operation. For one, the attendant magi of impeccable character she professed to employ were quite the opposite. Far from being paragons of the machine-God's scriptures, there were a motley collection of crypto-historators and archeotechnologists. Radicals all, whose theorems and specializations perched them forever upon the cusp of tech heresy. However devout Imagna was personally, this did not extend to the rigors of who she chose to employ, means to an end justified by their results, not their beliefs. Their work on the excavation, reactivation, and attention of the coral engine had been the work of decades, and despite their monumental efforts, the entire scope and nature of the machine eluded them. What they had established, after significant and rancorous debate, was that the device had been constructed on manic bail during the dark age of technology, sunk so deep into the planet's crust that it was essentially one with the world itself. Indeed, the segment of the device the Magi had dubbed the Siphon Coil drew massive amounts of geothermal energy from the core of the planet, facilitating not only its immense energy demands, but also a self-repair system entirely beyond the Mechanicus's understanding. Central Resonance Chamber was surrounded by what Imagna's retinue had come to term the Choristry Pits, rows upon rows of sarcophagi, into which psychers could be placed to power the machine. Depending upon their health or willpower, an individual could expect to survive for anywhere between three and ten days of purest agony, before their withered, smoking husk would need to be removed, and a new, screaming human would be installed in their place. For Imagna, the cost was not even a cost at all. Psychers were not human in the strictest sense. Never mind how much they wept. The results of his pact with Inquisitor Imagna exceeded Fleetmaster Abcondis' wildest expectations. Astrophatic links were established almost immediately following the Coral Engine's activation, and contact re-established with battlegroup courtes' scattered subgroups. The Armada's navigators were said to have described the device as functioning like a focusing lens for the Emperor's Astronomicon, strengthening the light of Terra to pierce the roiling tumult of the Imaterium. Such was the apparent power of the Choir screaming themselves into incineration upon Malak Bale that the warp storms around the volume began to recede, their fury tempered by the power of the engine. Within two months, by courtes' own endometous chronology, four of its groups were advancing into entirely new systems, and on all fronts, imperial elements beheld the power of the arch-enemy wane. On Amnarris, word-bearer heretics attempting foul summoning rituals found their never-born allies falter and fail to incarnate, the lesser emanations seemingly fearing the light of the Coral Engine. Elsewhere, sanctioned imperial psychers found their aetheric powers bolstered to hitherto unknown levels, the destruction they were capable of wielding upon the battlefield, suddenly making them even more prized military assets in the face of reeling chaos warbands. Victory after victory, they reached the flagship of courtes. Foes denied, worlds liberated. Malak Bale became the command hub of the entire battle fleet, Abcondus ordering elements from its subgroups withdrawn to garrison and fortify the world, lest the prize of her inquisitor a magna be threatened and with it the fate of his forces. The Fleetmaster did not fully trust the hereticus inquisitor, nor her cabal, nor the Coral Engine itself. She frequently placed excessive demands upon him for more and more psychers to feed to the device, seconding elements from various subgroups often without the Fleetmaster's say in order to accomplish this. Abcondus knew both she and her magi were aware of far less about the engine than they professed. He was no fool, and he knew his histories. Devices of the Dark Age were temperamental, prone to completely unforeseen function manifestations. He knew his position rested upon its powers, however, and could not deny that, after not two years under his tempus endometus' reckoning, Primark's initial orders for courtes had been accomplished and were soon to be exceeded. The slow bleeding of the fleet's manpower and resources prior to a magnus offer had been completely arrested. Whatever his reservations about the inquisitor and the Coral Engine itself, he was at least assured that his decision at the time had been a sound one. Yet, he knew not to the eyes that had been drawn to the machine's workings, the first set of which were soon to reveal themselves. The Astartes of the Grey Knights, granted battlegroup courtes absolutely no warning of their arrival, not of their strike cruiser unrelenting, appearing as if from nowhere in Malachabil's orbit, nor to their actual delegation, which teleported into the Fleet Master's very presence. Announcing them to be of the fourth brotherhood of that secretive chapter, Brother Captain Drystan Crom and his paladins demanded a fulsome explanation for precisely what was being used within the system. Despite his nominal standing within the upper echelons of Imperial military hierarchy, Abcondus had never heard of the Grey Knights. But regardless, the appearance within his very stratigeum of giant silver armored Astartes bedecked in weaponry and armor of clearly peerless artifice was not exactly a group to be questioned. Once more, he feared his execution for crimes not of his doing was at hand. But nevertheless, he delivered to Captain Crom as thorough an explanation of the Coral Engine as his unenlightened mind could offer. He recounted the victories it had won for courtes, its effects upon his psychers, astropaths and navigators, its ability to cast back the tumult of the aether, and, peppered throughout, assurances that everything he had done had been undertaken under the express permission of his Imperial Majesty's Ordo Hereticus. Captain Crom's impassive face gave not a hint of what he may have been feeling about it all. But once the Fleetmaster had delivered his defense, the Grey Knight stated bluntly that he would tour the device himself. The implication hovering in the air that this was as far from a request as it was possible to be. The Astartes additionally had a missive to bring to the commander of Fleet Quartus the enemy approached, in numbers the likes of which the Fleetmaster would scarcely be able to comprehend. The beacon was a light for far more than just imperial eyes. Like a fire lit in the darkest forest, predators were now circling it. Amcondus must immediately summon the entirety of his battlegroup's strength with all possible haste. Log entries recovered in the aftermath of the Malak Calamity, ascribed to the Fleetmaster himself, record that despite his long and storied career, despite decades of service against the worst the galaxy could pit against the guns of the Imperium, and despite his personal selection by none other than Gilliman, the encounter with the Grey Knights had shaken Fleetmaster Amcondus to his core. Quite aside from the transhuman dread so often elicited by Astartes, not least of all those of the Grey Knights themselves, Amcondus once again found himself questioning precisely why he had agreed to a magna's entreaties. He wondered had he, despite best intentions, been party to heresy, had he simply sold his soul to alleviate the traviles his battlegroup were under, and he damned himself simply to stick to a timeline. These concerns he kept private. The situation demanded the confidence and charisma he was known for, for if Brother Captain Crom was to be believed, the enemy was coming and his Armada would soon face a foe beyond their comprehension. Orders were delivered, vermilion security coded, and the grand muster of battlegroup Cortus was undertaken. The warp, cam under the influence of the Coral Engine, delivered these reinforcements with stunning speed. The orbit of Malicabale was soon full of thousands of warships, while yet more were formed into interdiction pickets to patrol the outer system, scrying for any immaterial bow waves that would indicate incoming ships. A staggeringly colossal force of arms hung in the void, joined now by imperial elements that had heeded the Fleet Master's call despite not being pledged to Cortus' banners. Below, on the planet, the massive Citadel of Light, a fortress constructed in the previous two years to surround and defend the Coral Engine, was likewise reinforced. Abcondus knew he must simply wait, sitting in the words of the mysterious Grey Knights, but after nearly a full week passed when the muster had been essentially completed, he knew that whispers were spreading about such a concentration of military might. While they waited, encroachments were no doubt even now beginning across imperial territory. Desperate for an enemy, there was no doubt a sort of twisted relief in the Fleet Master's heart on the seventh hour of the eighth day, since the muster had been considered finalized, Osbeck's Klaxons burst into their wailing refrain as an arch enemy warfleet tore the skin of reality at the system's outer Mandeville Point. Through the tears in real space, poured the enemy Armada, led from the van by the Ark of Omen Stygian Heart, surrounded by numerous monstrous battleships, mutated Grand Cruisers, and Starship-sized Demon Engines. It was a fleet to Sunder Sectors, and had it been arrayed against a force other than the one it now faced, its appearance would have caused total panic. Yet the muster had buoyed the confidence of the Imperial defenders. In material strength, they had the capabilities to cast back this invasion. Cortes' naval elements were strung throughout the system, and would take time, even at full burn, to rendezvous with the fleet master's flotilla around Mallekebale. Abcondis was unconcerned. He observed with pride as a tidal wave of long-range torpedoes were launched at the inward-bound enemy and reaped to the first casualties of the battle. The void war unfolded in the typical fashion of such affairs. The slow, almost-delatial progress of ships through the dead of space punctuated in their interiors with the howling of alarms, the roar of damaged fires, and the screams of the dying. Minute by minute, hour by hour, torpedoes burned, lances spat, macro cannons roared, and a strategic picture emerged that, much to Abcondis' pleasure, was firmly tilting in favor of the Imperial defenders. The surviving enemy capital ships around the ark were wounded beasts, and as more and more fell, it appeared that soon the space-hulk itself would be ready for significant boarding actions. The fleet master of Cortes was on the cusp of hailing Brother Captain Crom of the Grey Knights to deliver the glad tidings that the Astartes' portents of doom had not been as dire as feared. Before his auger scryers cried out in alarm that a new signal was emerging from the system edge, only for their hails, to be drowned out by a thunderous shout exploding through the minds of all on the bridge. Blood for the Blood God. Planetside, in front of a stunned inquisitor, a magna and her coterie, the cikers lashed to the coral engine began howling in pain and terror far beyond the torment they had been enduring, a deafening cacophony of pure animal fear, through which only two words could be discerned. Red Angel. He came to them. The Lord of the Old Red Sands, Butcher King, Slaughter Lord, broken master of a legion sundered, murder incarnate the howl of the predator that plunges teeth into next to slake the blood of civilizations. Eater of worlds, a cursed fallen, the sin of rage filled humanity cast in un-flesh and clad in blood brass. Angron, demon primarch of the 12th Legion, come anew to the material universe, cloven footsteps the tread of ruin itself. He came to them then, aboard the Conqueror, glorian atlas flagship of the world Eater's Legion of Old, now a haunted palace of lunatic bloodshed, an incoherent rage, rents in her hull speaking all too clearly of a craft commanded by the power of the warp more than hands even remotely human. The fleet surrounding her was vast beyond a scale of anything Cortes had ever seen and dwarfed the previous bail fleet by a degree almost laughable. It was said imperial augury screens were drowned by so many red threat idents that they appeared coated in a sheen of blood. More and more and more and more ships joined the Armada of the Eaters of Worlds, the heedless aggression of their shipmasters and shipmistresses, allowing them to plunge into the system far closer than almost any warp translations would typically allow. Rare had it been recorded in imperial annals that a fleet of this size had ever been gathered. For many, it was a thing from legends dread and terrible, mythic in scale yet now rendered dreadfully real. The flush of victory faded and gottered out and the imperial defenders of Malakbale realized that it was now they who were outnumbered and doing so as roaring from beyond the bounds of the real echoed through the darkest and most primeval reaches of their minds. In a manoeuvre that belied an intellect, however faint, behind his demonic fury, sensorium suites tracked the chaotic hordes as it divided into three prongs separating to use the gravity wells of the system stars and planets in reckless slingshot manoeuvres, harnessing forces of celestial bodies themselves that they may blood their enemies all the quicker and rob the defenders of precious time to mount coherent resistance. Abored the Grey Knight's cruiser Unrelenting, the prognosticators of the chapter had witnessed their divining mirrors crack and begin to bleed under the sheer etheric presence of the monster now within the local volume. At the moment of the conqueror's arrival every single ward aboard their ship upon their armor and inscribed upon their very flesh and flared into painful brightness, behex a grammatic scripture attempting to hold back the tides of etheric pressure that pounded upon the material plane like the crashing of a stormy sea. Across the system the first tragically futile attempts at imperial resistance were mounted. Task Force IV, out of position relative to the concentrated defense of Malakbale, resolved upon a hit-and-run picket against the Arch Enemy Fleet segment led by the battleship Ex Sanguinator. Their desperate boarding actions reaping a minuscule tally against the foe before the ancient starship at their van murdered the Astartes void talon cruiser Noble Blade in a single cacophonous broadside barrage. Elsewhere in the system the Task Force assigned to guarding the jungle world of Malakra could scarcely believe the augury reports their systems were tracking. The inbound prong of the armada was accelerating rather than slowing. Their extrapolated trajectories were making them perilously close to the planet's atmosphere rather than into the teeth of the imperial ships. The Fleetmaster wondered if they were possibly going to attempt planetfall without engaging the orbital defenders first and even more a suicidal maneuver than their speed would indicate but all too late was the enemy's plan revealed. Arch Enemy ships plunged at impossible speed into imperial lance, cannon and torpedo fire with their own guns howling eagerly seizing on the gravitic forces of Malakra to shoot themselves deeper into the system. Even for a single ship such a maneuver would come with massive risks. Not only were there an entire armada of world eater vessels attempting it they were doing so under fire and at battle stations themselves. The void war for Malakra's orbit was conducted at speeds unimaginable for such a conflict. Coronet ships collided with imperial defenders many accidentally many others entirely deliberately. The blood-mad captains sought to use their vessels bladed prowls for lethal ramming actions. Given the speeds involved many such collisions resulted in immediate mutual matter annihilation events chain reactions from these miniature suns emerging in the orbital volume consuming many other hapless ships in the process. Yet more attackers had their trajectories poorly planned or thrown off at the last minute plunging into Malakra's atmosphere impacting its surface with such force as to pierce the upper crust like an asteroid. The Clarion Dyer, the Ark of Omen attended to by the mad armada plowed through entire squadrons of escorts and barks without compunction its sheer mass carrying it forward inexorably. Almost as soon as a fight had begun it was over. The arch enemy continuing on their lunatic course in system and the imperial defenders mauled horribly orbiting a world now consumed by firestorms in tectonic upheaval from the wounds of so many falling starships. In the inner system Fleetmaster Abkondis let two of his group masters Thranadar and Zeng off their proverbial leashes to interdict the conqueror and her escorting armada before they reached Malakbale. The arch enemy outnumbered the Imperials considerably but the group masters were amongst Quartus' most professional and were counting on the rabid ferocity of the arch enemy to work in their advantage. Initially this was pulled off with a plomb working with magnificent feats of deployment the imperial commanders were able to lure the foe into killing volumes where concentrated fire from dozens of ships bracketed world eaters vessels as the bait ships conducted evasive escape trajectories. Fragmenting heretic formations were then susceptible to the surgical strikes of the adeptus astartes launching dazzling boarding actions to cripple enemy command ships. Boyed by the successes group master Thranadar formed a strike group of three battleships around her own, the resplendent to move on the conqueror herself. Such a challenge was seen early and clearly as no sooner than Thranadar had assembled her picket the conqueror flooded her reactor and powered forward aiming directly for the midst of the command group supernaturally powerful void shields took the hails of punishment that sought to stymie her advance before she unleashed her broad sides forcing the blade aquilent to abort her attack run lest she be crippled and sending the veracity spiraling out of her path. Should records of the conqueror's past have been available to the group master she may have foreseen what was to come. Alas, all that Thranadar could register was the purest shock as the conqueror fired her infamous urses claws massive harpoons that speared through the void and punched through the hull of the resplendent to drag the imperial ship bodily closer. As both ships continued to fire weapons at each other at point blank range tearing at their superstructures like two predators locked in a lethal embrace something broke from the conqueror's hull with more speed and force than a meteor spurred on by the hammering of the butcher's nails fused to his brain all those millennia ago driven yet madder by the howling of the coral engine in his aetheric senses Angron had torn himself out of his own ship to hurl himself across the void towards the resplendent. Witness reports stated that a red comet that was the demon primarch was hit by a lance be mid-clunge only for his warp-fuelled body to reform within seconds tearing through space like a macro cannon shell made from the core of a dying star Angron punched clean through the superstructure of an imperial frigate before tearing his way into the resplendent herself violating her hull as easily as he defied the flaws of the physical world. By what accounts survived? Groupmistress Strenadar died with her saber in her hands as her bridge crew tore their own eyes out with the sheer madness of the demon primarch that had torn his way into their midst with their most charismatic and competent leader torn to shreds by Angron's weapons and the corrupted primarch's flagship now in their midst like a vulpine amidst the yard foul the real line began to falter ultimately collapsing coordination that had yielded such results earlier in the battle now succumbing to the fury of the blood god servants The demon primarch's rampage did not halt stirred now into full battle fury loosed from the bowels of the conqueror Angron continued to carve a path of wanton insane destruction through the heavens powering from vessel to vessel by aetheric forces directed purely by his own impossible hatred seeing the fate of the engagement turn groupmaster Zheng ordered a full retreat of the ships remaining under his command leaving the stragglers to die screaming as they were encircled and bled by pacts of ravenous world eater ships fleeing for the orbit of Malekbale Zheng hoped that what strength the bloody task force remained could add to Abkondis's armada helping to stave off the heretic fleets but when battle was now fully joined in orbit around that world it was with the fury of elements clashing thousands of vessels now dueled in the orbital volume unleashing firepower that would have scorched whole worlds clean entire armies of soldiery fighting and clashing boarding actions through it all the needless of the symphony of destruction conducted around him for him in his name in the name of his unholy master plunged Angron aboard Conqueror his attention fixed purely on the planet and the coral engine the thunderclap of the Primark's entry into Malekbale's atmosphere was heard across continents plunging as a blood-red meteorite his passage ignited the air around him in fury below him lay Inquisitor Amagnus Citadel of Light the mighty Castellum raised around the coral engine to protect it its defences now took up the refrain training orbital laser batteries away from the fight in the void to focus their killing beams on the Primark himself joined now by flak cannons stripping away hell-forged brass armor and incinerating warp stuff of his own flesh nothing slowed Angron nothing could his will overcame all the pounding, pounding, pounding of the nails more powerful than even a ship-killing cannon deploying his demonic pinions the red angel arrested his descent becoming now a murderous Seraph corrupted icon of fallen holiness and flinging himself at the ramparts of the Inquisition Citadel Adeptus astart his and Astromilitarum troops alike manned those battlements Angron dashed them asunder like chaff rending armor and flesh with the ease born of millennia of contempt he sundered armored towers tore gun emplacements from their moorings and smashed gunships from the sky he was everywhere at once a crimson and brass blur of purest violence the howling of the psychic beacon below driving him to greater and greater heights of destruction the walls were next providing only scant more resistance to the Primarch's onslaught than a starship had in orbit, the situation was worsening for the Imperial Armada Fleetmaster Abcondus, in the eye of the proverbial storm watched in horror as traitorships plunged planetside to aid the unknown, unstoppable monster that was devastating the Citadel but his attention was forced back to his own ship as reports of world-eater dreadclaw drop pods attaching themselves to his battleship's flanks blared over the vox lines ordinarily such an action would not be in a special cause for concern aside from several regiments worth of naval armsmen the honor of Terra, counted in her compliment under arms several maniples of Martian battle robots and an honor guard of ultramarines astartes it was however the latter that delivered the grim news to Abcondus the world-eaters were led by Karn, named Betrayer former equary to the Primarch, now fallen and debased madman while the ultramarines stated their resolve to move an intercept their captain informed the Fleetmaster bluntly that if he wished to live, he must abandon ship immediately planetside, heretic forces had now landed in such numbers that the war for Malakabeil had become a towering inferno traitor titans from the legios Carnivorum and Scarifactor laid waste to the shrine world's cathedral cities stalking through tidal clouds of dust and rubble harassed, consistently, but ineffectually by imperial knights from House Terran and artillery regiments from the death core of Krieg in the city of Hallowed Helm, astartes from the sons of Medusa and imperial fists chapters ranged themselves against the lord invocatus of the world-eaters and ultimately were overwhelmed by the warrior priest's hordes sacrificed in bloody exultation upon plinths made from broken churches the more heretics burned into the atmosphere the more the blood flowed the sacred sites of Malakabeil were turned into charnel houses pits where desperate imperial soldiery fought blood crazed lunatics at every turn only to die piles of decapitated heads votive offerings to carneth the god of blood were raised skywards the combat itself was more prayer than the lord of brass and battle could ever demand of his subjects the torment of reality was refracting through the warp such a chaotic inferno of bloodletting drew the attentions of the blood god's emanations lesser and greater both they strained against the veil hardened by the workings of the choral engine swarming around the immaterial aegis of the device probing, questing, howling seeking their material incarnation at first they flickered into the real as candle lights in a storm guttering momentary but as the blood flowed in ocean so too did their power grow until whole hosts of the demonic tore their way into Malakabeil's now cursed reality the citadel became their loci drawn as they were to the power of angron to his violence that continued unabated and more and more and more of the blood god's legions incarnated eight bloodthirsters the greater demons of Khorne emerged from swollen red portals to wreck further havoc accompanied by thousands of bloodletters gibbering and screeching as they shredded imperial soldiers and slaked their tongues upon imperial blood it was an apocalyptic panorama unseen in the galaxy since the first war for Armageddon and at its center angron primarch demon unstoppable murder of civilizations tore his way deeper and deeper into the citadel Fleetmaster Abcondis seeing the dire tactical picture for what his was worth ordered an immediate landing in force of all drop capable imperial forces currently in orbit the Navas imperialis elements within the system were bloodied but still numerous the majority of flotillas were caught off guard by the sheer speed of the traitor assault and were now almost in reach of Malak Bale's volume it appeared that even at this juncture the master of Qortus believed victory could still be won against the demonic apocalypse and likely continued to feel this way until the very moment Karn the betrayer slaughtered his way onto the command deck and reduced the famed master of Qortus to chunks of bloody meat the late fleetmaster's feelings were nonetheless shared by Inquisitor of Magna who was utilizing the citadel of light's vox network to pour scorn upon the demonic invaders and deliver sermons in the emperor's name as she did so her adepts were hastening through the coral engine's workings disabling every failsafe they could in an effort to increase the device's ill-understood power output many magi begged the Inquisitor to cease as to overload so ancient and mysterious a machine could invite fates worse than imagination could conjure but they were overruled often fatally and Magna is rumored to have cut the final limiter herself although this cannot be verified suffice it to say when this last failsafe deactivated the howling of the implanted psychers took on an altogether more desperate pitch accompanied by a tidal wavefront of psychic energy from the depths of the engine the pulse tore the demonic emanations from their reality anchors the never-born hordes shrieking as they were banished to the immaterium once more the power of the coral engine was now such that every mind in the system a loyalist or heretic was filled with the mad pained screams of dying psychers triggering visions, nosebleeds, headaches or spontaneous cranial detonations bereft of their never-born allies the attacks of the world eaters faltered just enough for the imperial defenders to redouble efforts many commanders resolving to mount what counterattacks they could upon scattering heretic formations that were possible in their bloodied states only Angron and his bloodthirsters remained there not flesh writhing in agony against the aetheric assault of the engine's light it is impossible to say if the primarch's rage could have deepened yet further but what sense he had was torn completely the light of the choir filled his brain and all that could be done in answer to it was death Angron's emergence into the coral engine's sanctum howling in depth-less fury was answered initially by the detonation of sanctioned explosive traps that did not even scratch his armor plate but subsequently by a storm of bolterfire from every grey-night battle-brother present in the system the final line was the scions of Titan in their hallowed plate chanting rites of purist banishment accompanied in doing so by inquisitor Imagna's frothing zeal over the vox the gunfire was a torrent impacts so punishing, so continual that the demon primarch's immaterial flesh began to ripple his form began to flicker his armor began to blacken for not since his banishment at the chapter's hands centuries previously had he withstood such a total deluge of resistance both psychic and physical his god, after a fashion, was his saviour the greater emanations of the bloodied one now tore their way into the sanctum and began to simply slaughter inquisitor Imagna herself was one of the first casualties her head removed from her shoulders with an imperceptibly fast slice of a bloodthirster's axe others slammed into the grey knights in doing so freeing their primarch knowingly from the onslaught he had been enduring the unspeakable destruction that unfolded was no doubt much to the pleasure of the thing that sits on the skull throne grey knights fought bloodthirsters and everywhere around them inquisitorial agents and tempestous scions died in their droves brother captain Crom faced Angron personally managing to land not one he blows upon the primarch smashing the monster's head twice before the red angel's axe spine grinder slammed in a perfectly straight fall onto the crown of the grey knights helm it continued thus living up to its name although far slower than it had landed driving downwards bisecting captain Crom in a fountain of gore the grey knight reportedly screamed for as long as he had a mouth the insects opposing him removed or occupied the blurred bloody vision of the lord of the red sands now fell upon the engine and in a single leap he was upon it with axe and blade both he did smite the machine the moment of impact transforming him into a singularity conduit for the untrammeled purest rage of the blood god he was bound to a thousand million deaths a billion skulls offered to the skull throne the screams of countless dying oceans of blood all the pain and suffering and misery coalesced around the malak system reduced to a single act of divine destruction angron's physical form what at that point remained was annihilated in that instant every being in the chamber was reduced to less than atoms the resonance effect rippled to the coral engine the veins of that dark age machine infused with the blood god's celestial hatred in the instant of its destruction the fail safes had they been designed to mitigate such a psychic annihilation event were of course deactivated by inquisitor amagnus orders aetheric fire consumed the psychic crop boiling them alive within their own bodies as their blood turned to superheated evaporating gas and through it all their pain mingled with angron's rage within the coral engines vast unknowable circuitry explosions consumed all cascading detonations devastating the mechanisms of countless millennia before one resonated into the planets crust itself this final blast killed the world embedded into the very bones of this planet like a mechanical parasite the coral engine now sundered its host above ground imperial forces not killed by the world eater's destruction of the sanctum were now consumed by apocalyptic earthquakes and volcanic eruptions a scant handful of evacuations managing as the world's magnetic field began to collapse tearing the atmosphere asunder in continental hurricanes of unspeakable ferocity the crust erupted flinging mountain ranges into the void colliding with ships loyal and traitor alike the relief fleet of admiral pel racing to the defense of the citadel was caught in one such mass ejection to ruinous effect such was the violence of the planet death that segments of the world were caught in the orbital paths of its sister planets causing impact events that destroyed what life remained on each polluting their atmospheres beyond all recovery the calamitous death of malak bale was not just confined to the material the release of so much psychic energy in such terrible concentrations tore massive rents in the fabric of reality ships imperial and chaotic alike were caught in the empirical whirlpools sucked into vortexes of warp tides with no chance to activate their geller fields despite the unspeakable calamity that had been wrought through the slaughter of the world the survivors of the cataclysm were arguably the most unfortunate of all upon them now had befallen a curse a plague of the mind whose horror was rivaled only by its totality across the system loyal servants of the imperium felt their minds cloud their eyes filmed over with a sheen of blood their lips curled back from their teeth as spittle frothed at the corners of their mouths and one by one they began to kill it mattered not who for these cursed simply killed whoever was in reach they heeded not cries for mercy nor outrage they could not speak they could not reason one by one by one every mind still within the malach system fell to the murder curse it was the blood god's work shunted through the mind of his puppet and gran channeled through the now dead coral engine psychic plague of unparalleled ferocity friend tore at friend comrade butchered comrade and everywhere was filled with the howls of the now mad warships fleeing the chaos floundered as each and every member of their crews put down their tools and stations to simply murder each other the illustrious career of many a shipmaster and mistress was ended that day as they were eaten alive by those they had served alongside or slaked their own blood mad thirst upon their erstwhile colleagues had any clung to a scrap of sentience and possessed an act of sensorium sweet they would have detected the material incarnation of Vastor the archiphane come now in the catastrophe to claim his prize for his great scheme that the archiphane was present at malach bale or what remained of it is confirmable thanks to recovered aspect screeds although what precise key fragment the demonic demigod had obtained is hitherto unknown for the poor souls of fleet quarters their deaths in malach at each other's hands would go on to have a wretched legacy indeed the murder curse was opportunistic and spread through the very minds of the surviving astropaths out to the battle groups yet attempting to rendezvous in addition to the casualties sustained in the malach bale calamity some eighty percent of battle groups Baitaris Dominus Forthrax Erasmus Jovia Alphae and Kylox fell to the warp magics turning heretic killing or running renegade in blood fever only their custodies and silent sisterhood compliments resisting the blood god's depredations once thought stabilized the territories previously occupied by Cortis descended into unspeakable anarchy and depravity far worse in all respects than even the predations that had seen their liberation in the time since the calamity the fleet has been declared excommunicatoris in its entirety accommodating within its proclamation several millions of imperial subjects who were neither present at the site of the murder curse nor victims to its spread the loss of an entire Indomitas battle group has been simply staggering for the imperial but it would not be the last of the truly seismic events this chronicle is to bear witness to until such a time as I may continue I must rest Ave Imperator Gloria in Excelsis, Terra If you'd like to receive more updates about the channel and any future videos you can contact me or follow me on Twitter at Oculus Imperia Otherwise, please like, subscribe, comment, let me know your feedback and as ever, thank you very much for watching


In particular, Simon Michele from FIG Securities joins me. Simon, good to speak to you now. There is this growing political uncertainty and it's even affected the bond market. Good afternoon, Helen. Yes, absolutely. We've certainly reached that tipping point. It would appear that we're seeing quite a bit of a safe haven flow and that's really on the back of the continued political issues over in the US and that really flows down, you know, is the US government going to have the ability to implement the fiscal policy initiatives, the tax cuts, the infrastructure spending, if they're focused on these sorts of issues and so people are starting to pull their money off the table, essentially. So what happened to the US 10 years? US 10 years is now now to only about six basis points above its low for the year, at 2.23%. That's down or held its drop down by about five to 10 basis points over the last 24 hours and would likely drop a little bit further when the US opens later tonight. So how has that... What's that done to sort of the June rate hike by the Fed? Well, it's interesting. Only a week ago, we were talking about an 80% chance of a June rate hike. That's now down to 60% and more interestingly, Helen, if you have a look at the Fed funds futures rate, which is what the market's telling us, it's really not pricing in a full rate hike until November this year. So it could be possible that we only actually see one more tightening before the end of 2017. Yeah, so is it this sort of diminishing chance or the perception of a diminishing chance of the US tax cuts and the infrastructure spend happening? Is that because of the political turmoil around the Trump presidency? Look, it really is. I mean, really, what long-term interest rates tell you is the bit of a proxy for growth and inflation. So, you know, we've seen the equity markets get very carried away. We've seen good growth over there as people have sort of bought into a higher growth environment, the benefit for business of tax cuts. But we haven't really seen that reflected in the bond markets. The bond markets sort of like to see the devil in the details. So, you know, what we're seeing now is yields continue to fall. That's good for bondholders, but you're also seeing a lot of a risk off-trade and people moving out of equities and in for bonds, and that's creating that demand. Simon Michele from FIG Securities appreciate that very much. Have a good day. Thank you, Helen. You too.


In current times, when the rising demand for energy causes the deterioration of our planet, the transition towards renewable sources seems inevitable. This article was authored by Manuel Atferinovichian.