Welcome back to 353, thanks for joining me today. So today we get to talk about more advanced scheduling. So where we left off last lecture, we made it up to round Robin and we started talking about maybe some processes are more important than other ones. What should we do in that case? So one thing we could do, which basically what airlines love to do is we can just add priorities. So if we favor some processes over another one, maybe we assign each one a priority. And easiest thing to do is just to assign them a number and then we can give meaning to that priority. So maybe a lower number is higher priority. Maybe a higher number is higher priority. Kind of depends. It's up to us as long as we're consistent. So if we just add priorities, one of the first ideas we might have is just always run the higher priority processes first, round Robin, everything that's equal priority and then only switch to other processes as long as there's no other higher priority processes that needs to run. This can be done preemptive. It could be done non-preemptive. Most on most real operating systems, it's going to be done preemptively, meaning we still have control over what processes run when and which ones. So like I said, priorities can just be assigned an integer. So we can pick, like I said, lower is higher or higher is higher. Well, in Linux, what it does is it picks a ish. Lower number means higher priority. So for regular processes, a negative 20, that's the highest priority, and then 19 is the lowest. So if we just implement priority and just round Robin equal priority and then prioritize them ahead of anything else, then while we might lead to starvation, and that means there's some possibility that a process will never run. So if we just have a low priority process with a lot of higher priority processes that we always run ahead of it, while we might create a bunch of high priority processes over time and that low priority process will never run, in which case has the potential to lead to starvation. So we could fix this, we could just band aid it. So with scheduling, there's no one true solution.  So one solution, have the operating system or kernels specifically dynamically change the priority. So it could see that, hey, if this process hasn't run in a very long time, I'll temporarily increase its priority until it actually runs. And then as soon as it runs, I'll reset it back to what it was before. So I could try and work around that starvation issue if I really wanted to. Another fun issue if you just implement priorities is something called priority inversion. So I can accidentally change the priority of a low priority process to essentially de facto be a high priority one. So this could be caused by dependencies. So a high priority process depends on a low priority process. So can imagine we've already seen some dependency between processes. So like when we had a pipe and then we forked and then one was reading and one was reading, well, the process that was reading was waiting for that other process to write before it could continue. So there was some type of dependency between the processes. So if the process that was doing the read and waiting was a high priority process, well, then if we want to actually treat it as a high priority process, the process it's depending on should also be high priority because we want it to actually finish. So we can do our high priority things. We're much more important. So you can think of that as like, hey, if a high priority process is waiting on some low priority peasant that doesn't really matter. Well, they get an express pass to help out the important process. And then after they've helped out the important process, it can go ahead and they can get their priority reset. So that solution is called priority inheritance. So you inherit the highest priority of waiting processes. So if you're waiting on another process and you are higher priority than it, well, it temporarily gets your priority. And then if there's a chain, so if like A depends on B, B depends on C, C depends on D, while the offering system is going to have to detect that priority, which it will, because well, it knows all the system calls, all the processes are making. So it would have to go ahead and increase the priority of everything on that chain until that dependency is resolved. And then it can go ahead and reset it back to the original dependency. So that's one solution to work around this problem of just simply adding priorities. We also might divide processes into something called foreground processes and background processes. Difference between them is foreground processes are something you as a user are typically interacting with. So you want to have good response time for that.  Background processes, typically you don't interact with them. They're doing something maybe important in the background. You don't see their output until they're done. Maybe you might not care about their response time. Maybe you'd rather prioritize them just completing as fast as possible. So back in the day when we had like a physical terminal and it was really easy to figure out what's a background and a foreground process because a foreground process would be the current process that's like directly connected to the terminal and accepting user input. So back in the day when we just had a dumb terminal, really easy to figure it out. Not so easy to figure out anymore because while we have a whole user interface, just because you don't have the window focused, it might be visible to you. You might actually care about response time, things like that. So you don't need to know the specific definition for like what a terminal foreground processes because no one really uses real terminals anymore. They're fake ones. So, but the idea is still the same. You might want to separate out processes that users interact with. So foreground ones, they're interacting with it. We want to prioritize response time and background processes don't really need good response time, just throughput, try and finish them as quickly as possible. So we might try to schedule these differently depending on their needs because well, we might want to do round robin for foreground processes and maybe just do first come first serve for background, something like that. So we can just keep adding things and see how well they work. So we could have multiple queues if we want to separate out foreground and background processes. So like I said, we could just have a round robin between all of the foreground processes and then all the ones that we detect are just in the background. They can just do first come first serve. But now I also have to figure out when should I run a foreground process versus when should I run a background process? And then, well, what you might do is you might just round robin between foreground and background too. So you just add a round robin on top of a round robin and because this is scheduling, there's no right answer. Maybe you want to round robin and have foreground processes take up more time than background. Maybe you want the opposite. Maybe you always want to do foreground instead of background. Again, there is no single answer here. And that's why scheduling can get complicated because there's no right answer. There is only a series of trade-offs and we haven't talked about having multiple cores on your machine yet, which gets even more complicated and it's essentially where most of the complexity in this course is from. So for sake of argument, we will assume like multiple cores or something called a symmetric multi-processing system, which basically just means the architecture of the machine is all CPUs are, and in this case would be all CPU cores are connected to the same physical memory. So they share memory addresses and everything like that. And all the CPUs have their own private cache at least at the lowest levels like the L1 cache is private per CPU core. Maybe L2 is shared too, who knows, but that's what model of computer we'll think of in this course. If you get into real high-performance computing courses, that may not be true or like some enterprise-y machines that have lots of CPU cores and some will be connected to this memory and others will be connected to another bank of memory and then you have to care about which CPU core you're on because well, maybe it can't access some memory and then it gets even more complicated than we want to get into in this course if you can believe it. So we'll assume symmetric multi-processing, just everything's connected to the same memory. Life is relatively simple. So that's what the term SMP is. If you've ever seen that, you might see that when you run your name as well. So one approach I could do if I have a bunch of CPUs or CPU cores, I'll use those terms interchangeably is still only have one scheduler and just keep adding processes to CPU cores as long as the CPU cores are idle. So advantage to this is I don't really have to change anything. I just essentially put a loop on it. So I would have good CPU utilization. I'd still be fair to all processes assuming I'm doing something like round Robin, but the disadvantages of this system is it's not scalable. So you have to coordinate between all the CPU cores to make sure that each CPU core is running a different process because if you had two CPU cores trying to run the same process at the same time, while that would be a whole disaster. So you shouldn't do that. And you kind of have to make a global decision. You have to make sure all your CPU cores agree, which is kind of a little bit of a prelude to when we talk about threads and multiple things trying to contend with the same memory and making our life very, very difficult. Turns out in order to solve that problem, you essentially just have to make it serial. So you just have to make sure that only one thing happens at a time, which is going to be slow. So even if I have 16 CPU cores, I can't do anything 16 times as fast, they all have to wait for the same operation. And typically that's something we want to avoid. The other disadvantages is it has poor cache locality, which might be a new term with those two words together. Basically what that means is when your CPU is executing instructions, it might cache some memory values. So it speeds up like reading and writing to memory addresses. And typically whenever you're using some cache, well, it's going to be valid for a while. It's probably going to stick around for a bit. And if your process can go back on the same CPU core, likely some of your caches are still valid. So you wouldn't have to retrieve all that data from memory again, which is really, really slow. So if you can get scheduled right back on the CPU core, so like you get scheduled off and then back onto the same CPU core, likely some of your caches are still valid and still around. So things are going to be a lot faster than if you just went to a completely new CPU and then nothing's cached, you have to get everything from memory again and slow. So that's cache locality. Typically if you use something, you'll use it again in the recent future. So, oh, was that close? So yeah, poor cache locality is you're not guaranteed that process will always be on the same CPU. So you're not guaranteed that your caches are going to be stick around, yep. So what I mean by everything blocks on the global scheduler is that one scheduler, that's the only thing making the decision. So it has to essentially make the decision for each CPU core. So they all have to wait on that to make a decision instead of each making their own independent decision. And yeah, so this scheduler, so just essentially assigning different processes to whatever CPU core happens to be available at the time, that was the approach in Linux 2.4 which was released way before any of you were born and way before it was even remotely common to have a machine with more than one CPU and certainly not more than one CPU core, that concept just didn't exist yet. So this was like in the 90s or even before then in ye olden times. So first extension they made when it was more common to have multiple cores on your machine is to create like a per CPU scheduler. So instead of just having one thing making the decision and saying what process runs on which core, well, if there's a new process that comes in, we just assign it to a CPU and that's kind of our big global decision. And then after that, each CPU independently manages its own scheduling. So when I'm initially, when new process is initially created, I might just assign it to the CPU with the lowest number of processes currently running. So advantages of this, easy to implement and it's scalable, so there's no blocking on the resource. So each CPU core is scheduling itself independently. It doesn't have to wait on any one thing in order to run. And we have good cash locality in this case because well, as soon as a process gets scheduled on a CPU, it will stay on that CPU. So it won't move between CPU cores. So it's cash is likely to hopefully still be valid whenever it gets context switched out and then context switch back in. So that way we maximize our chances to have cash hits. Disadvantages of this system, oh, yep. Yeah, so that was a good question. So the question was what if we're waiting for, we have a high priority process that's waiting for another high priority process on a different CPU core or a low CPU core or a low priority process on a different CPU core, then same thing, we'd probably wanna do priority inheritance and make it high priority. And hopefully it runs at a higher priority than anything else on that CPU core or otherwise we're in trouble and you can see how scheduling quickly gets out of control with that, yep. Yeah, so the question is, how does this avoid the global scheduler? Don't we still need one? So in this case, in the case we had before, like assume we had round robin, we just have one round robin algorithm that just keeps on assigning processes to CPU cores as long as there's CPU cores available. In this case, our only global decision would be to what, when a new process comes in, what CPU to assign it to. So say we have four CPU cores, each of those CPU cores would be doing its own round robin between all the processes it has. So that's how we avoid that. So we do have a global decision here, but our global decision is what CPU do we assign this process to? And then after that, the actual algorithm runs independently on the CPU core. All right, yeah. So the disadvantage to this is well, if each CPU gets its own independent set of processes, over time I could get really unlucky and there could be some type of imbalance. So say I just have like two CPU cores and I have a whole bunch of processes come in. So I have like, I don't know, 10 new processes come in. So I wanna do five and five, but I might get unlucky where I assign five processes to one CPU core that all finish in like a millisecond or something like that. And then all the other five processes that I assign to the other CPU core, maybe they take 10 seconds each. So if that happens, well, very shortly that first CPU core that just got the very, very quick test, it's gonna finish all five and then it's gonna sit there idle and not do anything. And then that one CPU core is just gonna be juggling all of those other five processes that are all running for quite a long time. So I have the, it might be a case that I can have this type of load and bounce with this system because well, I can't move a process between CPU cores. So yep. So in this case, the scheduler would not keep track of what process gets assigned to what CPU, but it would know it's assigned processes. So the kernel would just say, hey, let's say process two comes in. It'll say, okay, process two, you're on the CPU core. And then that CPU core knows, oh, okay, I have to schedule process two with everything else that I'm scheduling. And then I'll keep doing that. Yeah, yeah. In this case, each CPU works in parallel. Each CPU would have its own, in the case of round robin, each CPU would have its own round robin scheduler. And then it would just, each CPU core would know what processes it has to schedule because it would just be assigned that. So in this case, to fix that load and balance problem where one CPU might become idle and it's done all the processes that it is tasked with. Well, I can make a bit of a compromise between like a global and a pure CPU scheduler. So I can have a global scheduler now that can rebalance CPU cores. So it can go ahead and check, hey, is a CPU idle? Oh, okay, well, if a CPU is idle, I should probably just take a process from another CPU and assign it to the idle one. And this is called cleverly work stealing. So maybe you want more control over which processes can switch because like I said before, switching a process between CPU cores, well, that will essentially wipe out your entire cache and you might have performance issues with that if it's something you really, really care about. So maybe you want some more control over what processes can switch cores. Some may be more sensitive to caches and you care more about performance than others. So there is a term to control this in the scheduler and it's called processor affinity. And what that means is just the preference of a process to stay scheduled on the same core. And this exists in lots of operating systems. So even if you're using Windows, this is an option. So if you had a process you really, really cared about, like I don't know, like a game or something like that, well, you can open up Task Manager, you can right click that process and then in one of the menu options, it'll be set affinity and then you could say set affinity high. And what that means is that process will likely always stick around on the same core. It's not gonna have any problems where it has its caches invalidated or anything like that. And hopefully you get better performance out of it. So that option is pretty much on every single operating system and that's what the term affinity means. So this scheduler, whoops, is kind of a simplified version of the 01 scheduler and that was used in Linux like 2.6 which is getting slightly more recent but not quite there. All right, another term that adds to our fun terminology in this course is called gang scheduling. So especially with high performance computing, you might want to schedule multiple processes as a group altogether. I don't know why they just can call it group scheduling. Don't ask me, I just work here. So here the scheduler on each CPU cannot be completely independent because I want to schedule them all at once because maybe they all depend on each other, maybe they all communicate with each other. So it only makes sense that if I run them all at the same time. So sometimes it's also called co-scheduling. There's a slight difference there. We won't get into what the difference is in this course but basically allows you to schedule a set of processes at a time acting as a unit and that would require context switching all of the CPU cores to this set of processes all at the same time. Mostly this is for high performance computing. Yep, yeah the question was this kind of like grouping the CPUs together, making them like a huge CPU. It's a bit more like as soon as we get into threading and running things in parallel, we'll talk more about that. But this is making sure that like all these processes can run at the same time in parallel because maybe they're all communicating with each other. So likely I don't want to just like have a process depend on another one that's not running. Things like that. Run at the same time meaning like they are running at the exact same time like you've say you have four processes and four CPU cores. We want each process to run on a separate CPU core at the same time. Yep, yeah they could communicate with each other that's IPC, inter-process communication. Yep, so the global context which in this case means like I can't have each CPU core be independent and make its own decision because I need to context everything at once like across all the CPU cores. So that's what global means in this case. And in terms of cache locality in this case, well, depends. Hopefully they're all scheduled on the same CPU core. So there'll be some private cache between the processes but then all the processes can use the same memory because they're all connected to the same memory. And then the kernel, if we want to communicate between them we have to ask the kernel to do that stuff for us. Yep, how many schedulers do you need for this? As many as you want. We can just keep on adding them as much as we want. So in this case, like we can combine like round robin different priorities. Do use different schedulers for different priorities we can do whatever we want. But this technique could be used with any scheduling algorithm we decide to use. So right now we haven't really talked about aside from like round robin and adding priorities other algorithms we could do. So we'll get into what Linux does in short time but there's even more complications in here which makes things even more fun. So there's something called real time scheduling. That's another problem. So real time means there are like some timing constraints or like a deadline. So it's been a while since I took like a signals course but like for audio especially, while there's like a sample rate and things like that and usually for audio devices there's a buffer. So you want to be able to fill it up in time and make sure that the sample rate happens or you'll get weird distortions. You might hear crackling and other things if your audio can't keep up maybe like autopilot that should probably react within a certain time before we like steer into a real child not like a process child or maybe we're directing a missile or something like that. Well, we probably want to react within a certain amount of time otherwise we could hit something. There's like a huge bug with some autopilot thing that was yeah, some weird stuff. So there are two types of real time. There are hard real time. So that means you have to guarantee that a task completes within a certain amount of time and that means you have to essentially count every single CPU cycle that you're in this case process or application or program could make and you have to make actual guarantees about the timing. So likely this will be like for very, very simple things that are running on an embedded processor where we can go ahead and actually argue about the timing. We'll have like a set frequency that our CPU runs at then we count the instructions, how long they take and then we've set limits on everything so that we can guarantee that things complete within a certain amount of time. That's pretty much only for simple systems that are embedded. What Linux uses is something called soft real time. So all it does is critical processes. They just get a higher priority than literally everything else and then the deadlines always met in practice otherwise you complain. And why is it soft real time? Well, it's because the Linux kernel and especially the hardware we have now is insanely complicated and for a general purpose OS there are just some things you can't control. So if you have, you might hit your deadline if you have a single process running or like a normal set of processes but you can't guarantee that the user doesn't launch like a thousand programs that are doing infinite loop things or they're not fork bombing themselves for fun or anything else like that. Like you have no control over the actual system. You have no control really over the hardware. So like even if the temperature changes, right?  Maybe you're not connected to power. Maybe, I don't know, it just decides to do whatever. Yep. Yeah, so the question is do you have control over your priorities, essentially? So stick with me for a second. We'll get into that because that will help us read what Linux is doing. So we can see all the processes priorities and we can change them. But we'll get into that in a second. Yeah, so in this case, Linux too complicated, software time, it just prioritizes those processes ahead of anything else and typically the deadlines met in practice. So like audio streaming, you don't have frame drops or anything like that. If you get frame drops, well, you just get mad. So Linux, those scheduling algorithms like First Come, First Serve and Round Robin, they're actually implemented in the kernel and they are two scheduling algorithms that are actually used. So you can search the kernel sources if you want. If you see schedule FIFO, that refers to First Come, First Serve. If you see schedule RR, that's Round Robin. So it has, at least for soft real-time processes, it has like a multi-level queue scheduler for processes with the same priority and then the OS can dynamically adjust the priority like we discussed before. So for the soft real-time processes, it will always schedule the highest priority process first and the kind of gentleman's agreement between that is, well, the soft real-time processes should just do something that's time critical and then give up the CPU. And then the algorithm it uses for normal processes will get into in a bit. Hand wavy, it kind of adjusts the priority based on aging and how much CPU time it has. So we can almost talk about what the priorities are in Linux. Yep. So aging is just how long that process has been around for or how much CPU time it's got. So on Linux specifically, real-time processes, so that soft real-time, they're always prioritized. So this is where the numbers get weird whenever we want to look into the Linux kernel and see what the hell is actually going on. So these soft real-time processes, they're scheduling algorithm they use or scheduling policy. It'll either be first come, first serve or round robin. Idea behind that is, well, if they're soft real-time, we want a scheduling algorithm that's fairly predictable and simple. So first come, first serve, round robin, good ones to do. So for soft real-time processes, there is technically a hundred different static priority levels, zero to 99. And then the normal scheduling algorithm that runs, it applies to other processes and it's just called schedule normal and we'll get into what the scheduling algorithm is for normal processes in a bit. But by default, annoyingly for the normal processes, the default priority is zero and then the priority ranges from negative 20 to 19. And in this case, a lower number is higher priority and then in this case, a higher number is higher priority, which makes sense, right? So you can actually change your priority of a process with system calls. So this here, these priorities for normal processes, instead of calling them priorities, the latest kernel calls them niceness. So the idea here is that the lower the number, the less nice you are, the more of the CPU you will hog. So if you want to be really nice, that means you will give up the CPU and other processes to go ahead and run. So you can adjust your priority through the nice system call, nice. And basically what that means is adjusting your own priority and there's also a schedule set scheduler, also a system call, so you can go ahead and adjust your priority for different processes. So we can almost read the H-top screen now. So there are those two weird priority systems, like one was higher numbers, higher priority, the other was lower is lower priority. Well, the latest kernel developers were like, that's silly. It's like that XKCD comic, like there are 15 competing standards.  Let's make something that makes sense and now there are 16 competing standards. Yeah, this is kind of like that. So there were two systems before, so software time priority, which was zero to 99 where higher was a higher priority and then for normal processes they had niceness, which lower was a higher priority. So this normal processes went from negative 20 all the way up to 19. So the Linux priority tries to unify these both on kind of the same number line. So for Linux priority, it always means that a lower number is lower priority. So what they did to scale the number is if it's a normal process, they just add 20 to it. So if it's a negative 20 niceness, a Linux priority, it's zero and then it goes all the way up to 19, which is 39, so they just added 20 to it. So in order to take the soft real time and make it lower is a higher priority, they just kind of inverted it. So they took that zero and converted that zero to a negative one and then converted a 99 to a negative 100 and kind of just inverted it so that the lower number means higher priority. And using this Linux priority, we can know if it's zero or above, it's a normal process. If it's negative, it's soft real time. So now we can finally read some more columns of htop. So if I run htop now, okay, so we know this first column, this PID. So that's the process ID of the process. And then the command that we used to run it, hey, that looks like lab one. User that ran it and then this PRI, that is the Linux priority. So if it's zero or above, that means it's a normal process. And then this NI is the niceness. So for normal processes, it's just going to be the Linux priority minus 20. So if I look through these, well, and it has the default priority, niceness of zero. Now we can go ahead and browse and see if anything is fun. So here's a very nice process. So its priority is 39 or its niceness is 19. So it is the absolute lowest priority process. It's called Tracker Miner FS3. No idea what the hell that is, but it's not important. Doesn't seem that important because, well, they opted in to be very, very nice. Likely if I kill it, probably nothing bad will happen, but I'll leave that as an exercise to the reader. All right. So we have this. So this one, the priority is nine. So it's positive. So it's still a normal process, but niceness is negative 11. So it is a higher priority process, and it's called wire plumber.  Hmm. Turns out that wire plumber is the process that is like managing your audio for your desktop. So that should have a higher priority than other processes because typically audio is more important and it doesn't take up that much amount of time. So whoever the wire plumber developers were, they decided they were important and no one really complained. So it seems like they're important. All right. Other fun ones. All right. There's another pipe wire. Pipe wire pulse. All right. You can see pipe wire thinks it's very, very important. So we got this, which is running at a negative two. So if it's negative, it means it's a soft real time. It keeps on jumping around. And it also means it's niceness. It doesn't matter for soft real time. It's just always zero. So there's this process, low memory manager, which might be trying to look around for processes that are using too much memory and killing them. For other ones, there's some other high priority so everything in green here, they're actually kernel threads, which we'll get into threads later. And then there were some important ones like migration that says real time. If it says RT here, that's negative 100. So it's the absolute highest priority of anything. And this migration, that's basically the dispatcher. That's basically what's doing the context which is on your CPU cores. So that's what's represented. Seems like context switching, very, very important. So that's fun. So you can go ahead, you can explore, you can see what things do and look up what they do and why they think they are important. So we can finally talk about the end of this evolution. So what we're using right now for scheduling normal processes on Linux is something called the completely fair scheduler. So the idea behind that is, well, it's fair and it has good interactivity. So if we're using, you know, typical desktops and everything like that, well, we want good interactivity, we want good response times. So with modern processes that 01 that we saw before that had like a per CPU scheduler problem, it has problems with modern processes. Like I said, not easy to figure out which is foreground, which is background. Maybe the kernel can detect it using some heuristics. So like maybe if they sleep a lot, they might be interactive if they're waiting for the keyboard. Maybe that means they're interactive, but that's like ad hoc, they just made up some rules. Could be unfair, you could be wrong. So the idea behind this is we want to have some fairness for different priority processes. Maybe we want to use different time slices, like different size time slices. Maybe the higher priority processes get a larger time slice. Maybe we want to be fair and kind of even them out. Maybe we want higher priority, larger time slice. Maybe there's also situations where that is unfair. So what can we do? So if we could context switch essentially instantly, we could do something called the ideal fair scheduling. So we can assume like we have an infinitely small time slice. And if we're being completely fair, like how I'm sure you with siblings, like shared screen time or whatever, that's definitely completely fair. You tried to say, hey, if you've end processes, then each of them gets like an nth of the CPU time. So if I have one process running, I assume I just have a single core, then it gets the entire run time, it gets essentially exclusive access to it. And then if I have three processes all running, well, they all get a third of the time. And I want to keep my CPU usage divided equally among all the processes at all times. So if I had something like this, so I had four processes that all arrived at time zero and the burst time was like eight seconds or eight time units, four, 16, four, I could assume that each vertical slice here, just to show what contribution of the CPU core it gets. Each of these vertical slices are four time units and I'm going to not show the context switches because I'm assuming I can context switch infinitely fast. So if I have four processes all at once and I have four time units, well, each of them gets a fourth of the time. So each of them is going to run for one time unit. So after my first four time units, I'm being completely fair. Each of them runs for one time unit. And then while for the next four time units, I'm still being completely fair. So they each run for a total of two time units now. And then similarly until we get to 16, where all of them have run for four time units, now process two and process four are done. So only have two processes left. So if I only have two processes left, if I'm being completely fair, well, you get half and then the other gets the other half. So I would now jump up by two. So I'm taking those four time units and I'm splitting it up half and half. So now process one, that would execute for two time units. Process three would execute for two time units. And then once we get to time 24, then process one is done because it's executed for its eight time units. So it's now done. And then the only process that's left is process three. So it would get all four time units. So it would run from eight to 12. And then 12 to 16, and then that would be done. So that's what we could do if we were being completely fair and we could just have an infinitely small time slice. And because we're also assuming an infinitely small time slice, then our response time is also pretty much zero and we're living in a perfect world. So yep. Yep, the six. So where the six came from is each of these vertical bars is like four time units of CPU time. So if I only have two processes left, then each of them will run for two time units if I'm being fair. And then so the numbers in the boxes are like, how long at that point has that process been executing for? So it was at four, it like ran for four time units. And then since it gets a share of two time units in the next four blocks, it goes up from four to six. Isn't which one? So process one wants to execute for eight time units here. Yeah, so it's not done yet. Process two and process four are done. All right, so that's the first policy. Impractical. Every process gets the same amount of CPU time. Not really going to work that well and you also have to constantly scan the processes, which is like an ON thing, which is slow. So this is the scheduling algorithm that Linux actually uses finally. So called the completely fair scheduler and how it works is for each runable process, it assigns it a virtual run time. So it essentially keeps track of how long each process has run on the CPU for and it keeps track of that in terms of nanoseconds. So fairly granular or not granular, fine granularity because a nanosecond, well, if you haven't seen this before, a nanosecond in terms of like how much distance light can travel in a nanosecond, it's like this. It's like about 30 centimeters, which is really, really fast because hey, the speed of light pretty damn fast and nanosecond not very long. So it can go about 30 centimeters. So how this works is at each scheduling point, so where some process runs for some amount of nanoseconds t, it will increase the virtual run time or how much it considers that process to have run by the time it actually ran, multiplied by some scaling factor, which is a weight based on the priority. So that's why we have lower means a higher priority. So if it's a higher priority, which is a lower number, the weight's going to be lower and if it actually ran for like, let's say it actually ran for two seconds, well, maybe the weight is like 0.5, so it only gets one second counted against it.  It means it only increases. So just a fancy word is it only gets bigger, it never gets smaller, just always increases. So the scheduler will just, in order to select which process to run, it's going to select the process that has the lowest virtual run time that's actually had the less, least amount of time on the CPU and then it's going to compute that time slice and dynamically scale it based off the ideal fare scheduling. So the idea behind it is, well, if this CPU or if this process is lagging behind all the other processes and hasn't had its fair share yet, I will give it a bigger time slice in order for it to catch up. Of course, practically it would have minimums and maximums for this, but that's the idea. And then we let the process runs, when the time slice ends, we repeat the process. So this is implemented with a red black tree because hey, keep by virtual run time. What I do? Oh, red black trees.  Hey, here's where it comes up. So you don't have to implement a red black tree in this course, but they're actually used. Look, they have a practical purpose. Yay. So why they do that? Yeah. Yeah, so each process has its own virtual run time, which is just keeping track of how long it's run for. Yeah, so it'll fudge with the virtual run time based off its priority. So maybe higher priority ones, we don't increase its virtual run time that much and that's more likely to run again. Kind of. It's a linear scaling. Yeah, you can switch your priority whenever it would just change that scaling factor whenever it computes the virtual run time. Yeah. Yeah, so the question wouldn't this mean I incentivize new programs over old programs and the answer to that is yeah, if you just run a program, you want it to like interact really quick and get some good response time. So yeah, yep. Yeah, so you might get to the situation where hey, if something's really, really old and has a very large virtual run time, maybe we don't run it anymore. It's less likely. So they'll have scaling factors that for like minimums and maximums and stuff like that. But that's yeah, that's something they would have to consider as well. All right. But yeah, so this tends to favor IO bound processes by default, which means they just do something really quick and then give up the CPU like they want good interactivity. So small CPU burst means we're only going to run it for a little bit so it'll contribute less to its virtual run time so it's more likely to run again and yeah, we went over a bit. So just remember, pulling for you. We're all in this together.


Hi.  I always like coming here to Singapore. It's always a great, great crowd. So here to talk about personality traits for effective UX and to start, this is a picture looking off a cliff in Victoria, Australia, down to the ocean. Just have a look at it for a moment. And what do you feel? What's the feeling that you get from it? To me, it kind of, there's a simplicity to it, isn't there? There's all the hustle and bustle of your day kind of just dissolves away, and all that complexity becomes simplicity. So it's a clarity, I think, if I could put a business term against it, and I think when we get hired as UX practitioners, I think businesses are actually hiring us for this. To take all the complexity of their business model, all the different types of customers out there, the different platforms and technologies, and all that in a constant state of change, and user practitioners are taking all of that in and creating clarity out of it. So that's what I wanted to start with. A bit about myself, I've just, yeah, I've kind of been in UX for quite a while, in-house, UX agencies as a contractor, in start-up incubators, start-ups, and it's been an amazing journey. So now I've ended up being like a UX consultant, so I can go in and identify the projects that I want to work on, and it's a lot of fun. During that time, there's been many people that in conferences and mentoring situations that have come to me and said, what do I need to do? What do I need to know to really get ahead in this? If I'm a junior, I'm really getting into UX, what's that thing that I need? It's a recurring question. And it's amazing, when you look at UX as a term, I'm a UX practitioner, it's this umbrella term for so many disciplines and things that you need to know that are underneath that. And so it's a complicated question, but I think if I look at how most people look at it, it's that we need to know processes. Obviously there's a UX process, and there's many processes to solving design challenges within that. We've all sort of looked at all the literature and watch videos and have learned these processes, and there's methods for doing things. You're going to do a card store, you're going to do an empathy map, you're going to be doing all these different methods to take data in and turn that into fuel for design decisions. And there's tools, but really like a tool kit. So you have your actual and your sketch and whatever tools that you use to get the job done to create artifacts and to represent design in its various states. And really importantly, tools is also like the maps and the models and the, just maybe pieces of paper with some lines through them that help you to, I don't know, get to grips with information and make decisions with. And finally, which I think is very important, particularly to junior people getting into this, is yes, you can learn all these processes and everything, but if you don't have an understanding of the commercial aspect, like how does business work? How do we make a profit? How do we drive new customers? It's a very challenging role. I think this for UX is half the equation. Half. I think the other half is soft skills. You can know all of this stuff here, but if you don't wrap that in a way where you can really connect with people and be a convincing, compelling person to sell all of that, very, very challenging. You need to build relationships. You need to be a good storyteller and be able to mediate situations, to be able to bring people together and get them to collaborate. That is a really uphill battle, if you have an ego, for example. And I'd say that if you don't spend the time to fine tune your personality traits, UX is actually an uphill battle. I think you'll lose steam, and eventually you'll plateau and it's not a rewarding career. I honestly believe that. You'll find again and again that things will start to work against you as you work your way up, and people won't respond in the way that you want them to. So it's interesting, when you look at personality traits and how that plays out, this is not an exhaustive list, but I think probably all of you are starting to realize that UX, when you look at the UX maturity model, which is kind of like a scale that says from like one to five or six, how mature does a business look at UX? The bottom is like, UX, what is this witchcraft? There's skepticism there and there's no commitment to it. All the way up to the top level, which is that UX is woven into the fabric of the business. It's the design thinking thing done properly, and the processes and the way that UX integrates into the business is very matured. When we get up to that level, UX kind of becomes a hub for decision making and for information to flow into and designs to come out of. But the issue is, as you can kind of see here, is that there's a lot of different groups here, and they're all sitting next to you in the chair beside you, right? Sea level might be in a different country. Marketing might be in a different building. The developers, they might be right beside you. That doesn't mean that you have rapport and a relationship with them. It just means they're beside you. I think we all know the guys in the cubicle beside you could be as much of an alien as the sea level sitting in a different country sometimes. So it's about building relationships and connectivity, a two-way street between all of these entities that you'll be working with every day that is so important. You have to break those visible and invisible walls down day by day as you come into a company slowly knocking them down. Think about when you're just trying to meet someone new and build a relationship with them, whatever situation that is. Tell me as a UXer, with all those people that we just looked at and all those departments, it's not the same thing. You're doing those sort of first impressions. You're trying to be someone that they can relate to and understand and you're gaining rapport, right? And that you have their best interests in your heart and what you're going to do with them and for them. But as you move on, the commercial part of this starts to kick in. It's beyond just having a relationship where you're going to the pub and having a beer with a mate. You're trying to show your competence. You have to remember at various levels of the organization, they don't necessarily know what UX is. They might not have the time or the resources to understand it. They're busy doing project management or product direction or all the things, specialty things they do. That's their focus. Don't assume that they're going to dedicate a lot of time to what you do and what your value is to bring to the table.  Like UX is a cost center, not the cheapest people in the world. That's because of the repertoire of things that we have to know is very specialized. You have to be able to demonstrate that that cost center has value coming back and the level of rigor around how you do that. But ultimately, like every relationship, it's trust. Everyone in here is basing their level of a relationship with someone around trust and follow through. It's actually going to do what you've said you're going to do. And that also comes down to reliability. But trust, Jesus, it's so important. So the personality traits sort of are the foundation of building that trust. If I had to list a list of personality traits that we wouldn't want our coworkers to have, we could all come up with a pretty long list, right? I think we could think of a few. So if I said to you, hey, here's Jack. He's going to come be our new UX interaction designer.  But you're going to be working with him every day. It's interesting when you think of it that way, isn't it?  But what's that list, that golden list, that a UXer should be? What is that, you know? So I start to think about it. This is kind of what I put together. I think these are such beautiful things to have as people. But as professionals, when we're dealing with others in so many different ways every day to tackle the challenges that we have, it's an amazing list. So what I did is I put this list together, and you can see here I've tried to have similar things and slightly different, you know, their proximity of these words are similar. And I sent out a survey, got back about 75 respondents and asked them one simple question, other than the demographics and all that stuff. If you were going to hire a UX person, what are the five of these that are the most important traits? Now what would you think that would be? It's an interesting question. So the survey. Gender is about 50-50 split or so. Equals you'd want it to be. Location, a lot in Asia for just because I'm in Asia, but you can see it's a nice cross-reference of different geographies. Professions, so a lot of UX practitioners there. UX management, HR. Here's the results. It's an interesting list. There's the top five. Those are the top five that everyone said should be the top five, if that makes sense to you. And I think there's some usual suspects there. I think some of those are not a shocker, right? There they are. Empathy. There's no shortage of literature about how empathy plays into UX. So I'm not going to go over that one in great detail. Collaboration. This is people designing for people with people. So if you can't collaborate, wow, it's a tough, long career path. Whoa. Inquisitive I think is really important. You know, it's interesting when I have interviews and I'm interviewing people for UX positions and I ask them, so what questions do you have for me? You know, I've sort of gone through and I learned a bit more about you. What do you want to know? If they say, no, that's okay. No, I think everything's all right. There's no callback. It is impossible for a good UXer to not have a billion questions where I'm literally having to say, look, I think my time's up. I got to go. I got to go to the next call. You want that inquisitiveness. You want to be digging deeper. You want to know, like, okay, who am I going to work with? What kind of projects?  What's going on? That's being inquisitive. Adaptive. Tell me every day you don't have to be adaptive. I mean, adaptive is one of those key things that we're so good at. Right? If you just took the standard UX process and said, hey, I'm going to apply this verbatim every single time I have a design challenge. That's a boring job. And not only that, but I think that the standard UX process is a bit difficult to fit in every situation. You'll be adaptive. And then finally, understanding. Obviously, there's two ways of looking at that. Understanding being that you understand other people's predicament and position and things like that. But also understanding in, when you're working with very complex enterprise systems, you understand it. You've taken the effort and the time to fully become intimate with that system so you can make appropriate design decisions. But I don't want to be talking about those top five with you today. Actually, this presentation is about all the runner-ups. Because these were obvious.  Let's talk about resourceful. Having the ability to find quick and clever ways to overcome difficulties. Tell me, we're not doing that every day. You know what, with UX, to do it properly, you're pulling in tons of different information from different departments. You're pulling in analytics for traffic. You're pulling in click reports, the marketing, the online surveys. You're doing live interviews with people, all these things. Would you not have to be resourceful to do that? Persistence. How do you get access to all that information? If you're in an enterprise environment, how many of you have come up to the problem of saying, hey, I need to interview a few customers? Can I get access to them? Or, hey, I'd like to do a contextual inquiry with about 10 people in the warehouse. Do you mind if I just sort of bug them for the next three hours on Friday? Oh, I need to get access to the BI reports so I can do some analysis. Ever run into a problem trying to get access to that stuff? And was it persistence that ultimately got you to what you needed? Articulation. My gosh. The fact that it's an eighth place. If you cannot clearly articulate very complex design decisions, the ways systems work, all these events and triggers and rules and algorithms and things that make your design work, express those clearly to a boardroom of stakeholders. Again, pretty tough. Articulation. Try to talk about a complex shopping cart system where there's a million different rules coming in over a Skype call. And you tell me that articulation is not critically important to convey the information that you need. Look at that. We're the third last now. We've jumped way down the list. How could you not be energetic when conducting a workshop?  They're there for the next two hours and you're there to have an outcome. You have a design problem and you need to come to an outcome. How do you guide those people and keep them focused and on track and on pace for two hours without energy? And to make really innovative design decisions, if you don't have energy, where does that come from? If you don't have energy. Wow. Second last, being selfless. This is kind of like the empathy and all of those types of terms where you're doing this for someone else, not because you're going to get a raise, not because you're going to get a bonus, not because your title is going to go higher, not because you're going to get an award in the industry, but because when you design that new interface for a call center in Malaysia that fulfills insurance quotes that you shave off two minutes of every call and you make it so that they're not using three screens, they're using one beautiful interface. That's being selfless. That's saying I really care that when that person goes to work each day, the interface that I designed for them makes their life a heck of a lot easier each day. This was last place. I was really floored when I saw that being affable, being a friendly person that's warm-hearted, that's approachable, last place. I'd say all of this stuff is a total nightmare to do if you're not affable. But when you're doing a usability test, you have people from the public coming in to use your product for the first time and you're not affable. Wow, think about that. How do they divulge and express their feelings, their thoughts, their emotions to you in a way that you can transcribe and make use of later to make design modifications if they don't trust you, if they feel like you're not affable? I really thought this would be top five. I don't know about you guys, but it goes a long way. And when you're asking for things in a business, tell me affable does not help you get a lot further along. So when you look at that list of all those different personality traits, it's kind of hard because you've just got this huge list. Like, how do you put that together? And I thought maybe the way that we can compartmentalize those is to say, look, a portion of those are about my personality, like who I am as an individual. How do people view me as just a person? And then how do I do things? Like, what's my way of doing things? And what level of energy and drive and determination do I have to get it done and seen through to the end? And then finally, what's my motive? What is my true intention when I'm doing the things that I do each day? So you can actually take that list from before and kind of group it like that, roughly. I mean, maybe someone's debatable, but at least that helps you to kind of break it down a little bit. What interferes with all of that the most, I think? Like, if you could come up with one of those negative ones that we looked at before, what would be one that kind of, I don't know, kind of is like a total room killer? I think it's ego. Let's look at some of the things that we looked at before. If you have a really bad ego, how could you be inquisitive? Why would you delve and deeper into something if you think you already have the answer, right? Look at adaptive. Why would you change if you're already perfect, right? Collaborative. Why would you share ideas if your one's the right one? You're not going to be collaborating. You're simply dictating. Why would you be selfless when it's all about you? Understanding. You're only interested in people to understand your perspective, not theirs. And then, finally, how can you be genuine if it's only your interests that are at heart? It's interesting to think of. We all have egos. It's just varying degrees of them, and it's good to be mindful of how much ego is influencing when I've done a design and I think this is the design that's going to solve everything and then you submit it forward. And I also think being insular. The presentation before mine about the future and all of that, when you're insular, the realities and the changes that are happening around this bubble that you formed around yourself are a very inconvenient truth. And you shield yourself from them. And when you become less insular, you're willing to accept the changes that are happening, the realities that are happening around you. So when we look at all of this, it's interesting. I think we all know life's kind of a balancing act, right? And I like to think that as you practitioners, we kind of have a detachment like an ER doctor, but the passion of a music composer. And what I mean by that is if we go and we make this design and we're fully committed to it, we put it out there in front of the stakeholders and they shoot it down. You know what that is? That's the ER room person coming in from the car wreck and you don't save them. And it's traumatic. And if you carry that baggage with you, gosh, that's a lot of baggage to carry with you. So you have to let it go. On the other side of that, that's not to say we can't be passionate, passionately driven when we're making our designs. Like a music composer. Think of all the best music you love, that you played 100 times, you literally worn out your hard drive listening to that song, guaranteed the composer was passionate about that. So there has to be that happy medium somewhere. And likewise, you know some of these things where you're being humble but you're sort of wanting to have a level of assertiveness, what is that balance of assertiveness? And basically what you're trying to do is pick your battles.  They're literally wiping your feet on you saying, well, I don't like this and well, I think we should change that. And the product manager said, we've got to change that and I don't want that. And you're thinking, well, cheese, I just spent three weeks researching and designing this. Okay, I guess I've got to do it. Your designs will never see the light of day if you're persistently like this. Here's the interesting thing. You could say, well, okay, John, then I guess what I'm going to be is a bit more assertive and strong and I'm going to say, okay, guys, I've done my research, this is what we've got to do. This is what's going to save the business. Let's do it. Not necessarily. When you tell someone what to do, they try real hard to make you know who's actually in control or who they think should be in control and they'll pit every roadblock up to defeat you so that your design doesn't make it through. So again, what is that happy medium to get your designs through? Because luckily, we're armed with facts and data, firsthand accounts and experiences and we've done a lot of research to back up what we've done. So that counters a lot of these things that all of us have come up across. Personal opinions, I like blue instead of red and all of these things. At least we have all that armed so that when we tell our story, we tell the efforts that we've expended to the conclusion that we have. We've presented the data that vets what we're doing is correct. This gets harder and harder to get away with, right? And I think when you're thinking about personality traits throughout your career, think about the different stages of your career. So if you're just learning right now, you're just getting into UX, this is one of your first conferences, consume knowledge and just build a consciousness of this. Just be mindful of how you present yourself and how you go about activities. And like I said before, when you get that first interview and you're talking with a recruiter or someone in the company, people ask, well, how do I separate myself? You do that through having a very clear differentiator which is that you have this consciousness of personality traits and you're exhibiting some of these traits that we're talking about in the call, evidence of it. But as you get into junior, you want to start experimenting and pushing yourself to actually apply these and sometimes it's a bit awkward. It's not going to be a home run every time, but you will get through it. When you're a senior, that's when you're actively implementing it while you're doing things, while you're presenting to stakeholders, while you're mediating between different parties that disagree, while you're doing a workshop, you're actively engaging it. And then when you're in management, you're bringing it back, you're getting the next generation ready to go through. Let's run through a few quick scenarios and see, okay, given typical scenarios that we're all going to kind of come up against in our UX career, what kind of traits would you use? Scoping and defining a project, how hard is it to really clearly understand why the heck we're making a product? Who's it for? What's the real benefit for us to spend the next month building this thing? To get that information, so you have a level of certainty around that and clarity, again, clarity around that, you have to pull in so much information from different people that may not actually have a full grasp of it themselves. And then it comes to us to help structure that conversation. We should be good at doing that. So we have to be inquisitive and resourceful and collaborative. If we're just expecting to be on Slack chats all day to get that kind of definition around of the information that we get in, wow, it's a lot of chatting. Get them in a room. Oh, that's right. So resourceful and inquisitive and collaboration and understanding that all of a sudden you've walked up on the scene and want a ton of information from them. Not everybody's happy about that. And that all comes back to what I was saying before. When you're trying to gain access to stuff and really ask for reports to be generated, all of these things, again, all come into play. Workshop facilitation, like I was talking before. How could you not do a workshop facilitation if you're not a confident facilitator, right? They're looking to you for guidance. And then like I said before, energetic. And if you're not articulate about how to move and progress forward in the steps of a workshop, that's pretty tough. And at the end of the day, I think you want a command of the room, but you also want to be humble. You don't want to be overbearing when these people are with you for the next couple of hours or half day. Some workshops go pretty long. Usability testing. Like I was saying before, I think all of these things go a long way to build a quick trust relationship with the person that you're testing with. So you get the maximum value from that session.  Don't waste it. Have these personality traits come exude from you so that you get the most value from that hour. And when you're presenting to stakeholders, you've done all of this work and now it's all coming up to an hour in a boardroom.   And if you can't articulately sell an idea to them, the patience is thin. So I want to leave you with this, is how do you develop these traits? I mean, I could put an exhaustive list of books and YouTube videos and et cetera, but I'll leave that to you because I want you to shape how that comes about. But I think we're creatures of habit and it's tough to break those habits. We've formed our own personality and for someone like myself to come up on stage and say, hey, you have to change them and now sort of craft them into this list is a pretty big demand. But you need to push yourself out of your comfort zone if you're going to achieve this. And it's not an overnight thing. Don't expect this just to be cold turkey and then you're suddenly a different person. This takes a long time. You're reprogramming yourself. And it's this. The biggest risk is not taking any risk. It is risky to assert some of these personality traits that you're not used to doing. And you need to read. There are so many amazing books about every facet of your personality, about building relationships, the old Dale Carnegie stuff, but there's many modern takes on that that you need to read. You need to watch videos and experiment and practice with these things and just be mindful of it and how you do your work each day and the motives behind your work. And finally, coming from the late Jim Rohn, which is a motivational speaker, he would always say, the things that are easy to do are easy not to do. And I think that is very applicable to applying new personality traits to yourself to develop and enhance them for the benefit of what's really an amazing career path. So, I'll leave you with that. Thank you very much. I really appreciate your time. Thank you, John, for your time. Now we would like to show a token of appreciation from our volunteer, which is also a lecture from Republic Poly. Thank you. Thank you. Is there any questions in the ground, on the floor? Is there any questions that you want to ask John? If there's no more questions, we will move on to the next speaker.


Hi, this is Mitch Mitchell. I'm whooped. I just went outside It's late at night. I walked just under 20 minutes at a very brisk pace trying to Work off some of the bad eating I did today. It's Saturday night and Let's just say that as much as I thought I was actually being good today I really wasn't this isn't a video about nutrition by the way, but I'm starting with that because Then I will talk about why today probably went askew So I had a plan coming into today My plan was that I wanted to see what would happen if I spent a lot more time on social media basically promoting my blog post some of my videos and those of others I wanted to see whether Long-term participation in social media would actually have any kind of effect or benefit or bounce or anything Would it drive anyone to my blog? Would it drive anyone to the videos? You know would anyone even see it would anyone even talk to me? So I actually spent yeah I'm the fool about ten hours straight with maybe about a 45 minute break in there basically posting blog post of mine to Google plus and to Twitter I Participated on Facebook talked to some people I put a video and a link to a blog post on there as well I shared some stuff. I talked to some people today on Twitter that I knew I didn't talk to anyone on Google plus which is pretty standard. Well, actually that's not quite accurate I did have one I think three or four message Conversation with someone on a link that I shared wasn't my video of all things It was a video of some guy saying something really stupid on a recorded program and that was the conversation but in general I wanted to see what would happen see if anyone noticed at all and The experiment pretty much gave me what I thought was going to happen Which is I had a couple of people here and there who shared something that I put up I had a couple of people who on Google plus plus it had some people who favored it on Twitter Nothing whatsoever on Facebook, but I pretty much expected that I don't you know Usually Facebook isn't a place where any of the stuff that I will share will get a lot of action if it's mine if it's other things like baby dears being stroked on their stomach and Wining if the guy tries to put him down Everyone watches something like that, but I'm not gonna create something like that because Mitchell ain't going outside to touch no dears So there you go But I wanted to see what would happen now the thing is I did all that today and I put it out there because one of the things that When you talk to people they say you have to keep pumping stuff out all day long over and over if you want to get seen by the people who were connected with you or follow you and I wanted to know what would happen. I'm not someone who automates anything Okay, let me rephrase that almost nothing I Do have all my blog posts go to Twitter when they post because a lot of times I write those things way in advance And so I might not be around when I want them to go live which is earlier in the morning and It turns out my business blog goes automatically to LinkedIn I had I didn't even remember that it ever did that I don't remember setting that up, but I must have done that a long time ago But in general if anyone ever sees anything from me on any of these things and I posted it Then I was there at the time and I'm live now and if you see it and you want to talk to me There you go. The video is slightly different actually It's if you see it at the time. It actually goes live. I put it there. I haven't figured out how to post time A video yet someone I know my friend Eileen if you ever watch is this she'll say I showed you how to do that Well, I didn't watch it That's on me, but I wanted to see what would happen and you know what happened. I Got burned out. What a day Trying to keep up with all this stuff. I mean, can you imagine reading tweets? and Reading all these Google things from all the different people that I follow for 10 hours At least Facebook was a little bit quiet It was a lot easier to read and I didn't go there as often as the other places and I shared tons of stuff and That got a couple of you know Thank yous and maybe did you like that or you know, what did you think of that? But in general? it really didn't really offer anything and I hate to say I kind of expected that but I did One of the things that I gripe about is that social media really isn't overly social You may have one or two people who will talk to you But on Twitter a lot of people just pumping stuff out and they're not even there So they don't know that you're putting anything out there. They're certainly not there to talk to you And I actually tried to talk to some people.  Is it really worth it and You know, you wonder. Well, is it that is it that no one really cares about the stuff I'm talking about a sharing today. I shared a lot of stuff about blogging and writing and motivation You know ethics And I shared a lot of other folks post on blogging and SEO and stuff like that You just you just never know you really never know what's gonna hit. I Wasn't political at all. I didn't want to talk about The Israel Palestinian thing I didn't want to talk about what bad things Republicans are doing or how Many people hate president. Oh, I didn't want to get into any of that I just wanted to see if putting out stuff that I was hoping would be considered quality stuff and motivational stuff would really get anybody talking to me or You know get anyone to come to my blog or anyone to go to my YouTube channel who Usually doesn't go Didn't happen So because of that I ate badly I had set time frame so Cooking and basically I made one meal today. I snacked on cashews snack on this Oreo ice cream thing. I Did heat up some baked beans and then it turns out those things are killer Oh There's just nothing you can do at least I did close the night once I realized that I was gonna be way over on everything I did close the night with a pulled pork barbecue sandwich and some banana pudding and then I went for my walk So I'm still over but look at this. Well, you can't really tell there's actual sweat on my head Yes, I'm sweating Decide to be interesting So I'm out of here Mitch Mitchell. I'll talk to y'all another time Sounds like a finding mouse