because we are diving into Pond with Mitch Stein, and this is going to be a super cool episode. So thrilled to have you here, Mitch. Mitch is the CEO of Pond. I've had the great pleasure of talking with you very briefly, and we are going to talk more about this tech solution and platform that you've created. But first, we always want to start every episode by extending so much appreciation and gratitude to our presenting sponsors.  We are so immensely grateful to have each and every one of you to continue this conversation across the globe, coming up on 350 episodes. If this isn't it, we are really close to that. So we are really thankful for each of these companies to be here and to support each and every one of you, your missions, because they exist to help you do more good. So thank you to our sponsors, and thank you to Julia Patrick, CEO of the American Nonprofit Academy, and to myself, Jared Ransom, the non-profit nerd CEO of the Raven Group. And again, going back to you, Mitch, thank you so much for joining us today. Yeah, thank you for having me. It's really exciting to be here, and hopefully I'm the 350. I know, I know. You know, I got a witness to you. We do know, because we have a pretty organized show schedule and everything. But we, I think it's next week, if I'm not mistaken. But I'm gonna look real quick, but you look. Because we should know. I mean, it's shameful that we don't know. But anyway, okay, Mitch, you were with us on the Chitty Chat Chat, and you said some things that maybe both Jared and I needed to hear today. And so it totally resonated to the point where I was like, okay, show's over, we're done. I got the message, move on. You had, so talk to us before we get into the topic upon. Share with us where you are and what has just happened in your world in literally not even what, 18 hours ago? 22? Yeah, I guess to afternoon. So yeah, I'm really glad you made space for that. Cause it's just so real. I think a lot of times in these conversations, everyone's like, everything's great. And like, I'm gonna tell you about how amazing everything is. We're hosting an event in New York City tonight with kind of the community members on Pond here in New York. And it was really popular. We had a hundred people RSVP. We had to change venues last week, which was stressful in and of itself. And we found a new great space. And then just yesterday, the building that space is in changed their capacity requirements. So we had to send an update to all hundred RSVPs saying we can only have 30 people on the floor at a time. So we're gonna ask you to pick a time slot. Luckily it's at like an artist's studio. So it's natural to have kind of a time to come and see angry people and kind of cycle out.  And that was like, let's make a plan. What can we do? We've got to email everybody. Let's set up a new event platform that puts people into segments that they can pick and opt in. That gives us a better read on who's actually coming now with closer to the date by putting that extra step in there. We're gonna move around staffing at the event. So someone's gonna be at security, someone's gonna be at the elevator up top to help us manage the numbers. And, you know, there's gonna be some confusion and it's gonna give us more opportunity to engage and talk with people and learn about them at the event. Yeah, that was my first thought. Is that you're gonna actually, this might end up being a blessing because you're gonna be able to read the room of 30 people at each time. And then as that changes, you'll get the lessons from that previous group, right? To be like, okay, let's pivot or whatever. And I think it's like, it's a very, that sort of fear of being human. I find this a lot in the nonprofit space of the perfectionism of like, your donor story has to be perfect, your impact has to be perfect, your grant application has to be, nothing can be wrong with what you're doing. It can't be messy. And I think that we've got, people get it that we're in a pandemic and it's evolving and they're very sympathetic to that and wanna be helpful and don't wanna be an added problem. And so I think it creates opportunity. Do I wish it had just been as according to plan? Yes, but we had tools, we had resources to change. And I think that's what was important to exercise here. And we'll see how it goes. Okay, so tomorrow is our fryer ask and answered, which is a great episode, Jared and I love it. It's very different, but I'm gonna ask a big, big thing to you. I'm gonna ask for you, if you could email myself or Jared before we start the show tomorrow. So you'll have a few hours, because we're Pacific time. Would you just let us know really quickly how it went? Yes, absolutely. Don't you think that would be cool, Jared? That would be cool because we're all navigating this right alongside you, Mitch, as you said, like so many people, we're in this space together and we're all doing our best, we're doing the best that we can and we're continuing to navigate. So I think that would be great. And yeah, thank you and good luck. I think, you know, best of luck to you and your entire team. So let's dive into Pond, complete pun intended, because I really want us to know what this new platform, what is the concept, what is the focus? Tell us about Pond and why this is something that you have designed. Yeah, of course. So I think the easiest way for people to think about Pond is it's like a dating app between nonprofit leaders and the tools and services that they need. It was born out of a gap in the sector where no one really knows what are all the platforms that do XYZ?  And I just observed from working with nonprofits that that happened in a Facebook group and then happened in an email thread and then they were calling friends and then maybe they're hired consultant. And it was just like, there was no centralization in it all. And it felt to me like that was really just limiting access for people, right? Like if there's no centralized place where people are interacting around the tools and services they're using, it makes it exclusionary to people that might not be plugged into a network or have the resources and have access to that. So kind of democratizing the whole system. And we knew we needed to be creative with it. It couldn't be a normal marketplace with the drop-down menu to go like pick the options and as if you're putting a trip together on Kayak. The reason we bring up the dating app example is because it's all about people being able to put some information out there saying this is what I use, the problem I'm facing kind of in their own words on their own terms and then providers of those tools and services able to kind of browse those profiles, those listings and can opt in to say like, I think I could help you but leaving it all on the nonprofit's terms to say another checkpoint to say, no, that's relevant or not before they get any contact or identifying information, they've kind of got a safe space to evaluate incoming offers. And the best part is anyone that they actually talk to through PON, they get $100 in their account for having the conversation. And that's the real innovation is we're taking marketing spends that that company could have been spending on a Google ad or a Facebook ad or all kinds of marketing channels and saying, no, we gave them direct access to see what people are actively looking for and there's a lot of value for them in getting access to that and being able to participate in the system. And so when they do connect with people they're gonna pay for that but we want most of the money to actually go benefit that nonprofit and help them be able to afford the stuff that they need or they're looking for or they're finding through PON. This is so innovative. It is so fresh, so creative. I love it because it really has come with the times. I myself am an expert in swiping left or right or left or right depending on what app I'm on. So I think it's really interesting to have some of like, not some like a lot of 21st century's connectivity that matchmaking system put that into a nonprofit sector platform to match services with maybe a consultant. Now, I have to fess up, right? Like as soon as you and I talked, Mitch, I put myself on Pond. So I am dipping my toe into Pond. I have done just about that. I've entered my profile. I haven't gone much beyond that because I was so amazed at the system. It's so amazed with your ability to see this need and to see this gap and then to provide a solution. So kudos to you, kudos to your team. I know a startup is not easy, a startup in the tech space, but I think you're doing a phenomenal job. Thank you, and I'm glad you brought that up to the honesty around like how you got started or and I think I look at nonprofit tech and it's really about empowerment. And I see a lot of similarities to like fitness or dieting, right? How do you make a change? You take a step, right? You take one step and we wanted to make joining Pond is free. It is anonymous. You can come back and update your profile whenever you want. It takes like two to three minutes. We just want the hurdles to be as low as possible for everyone so that they can take that first step and give voice to a problem they're facing. A lot of people don't even know, obviously I don't know the solution to my problem or I probably wouldn't have it, right? You might not know the right term to be looking for or the right product category and we don't want to put that burden on people. We say put it in your own words. What are you looking, what are you facing? What goals do you have? And put the work on someone else who like knows the problem they're solving because that's their job to reach out and explain how. And that's really, we want to bring that to people and make that accessible and not make it so othering or intimidating because tech is super scary and it's generated a lot of distrust I think amongst folks that have been in the nonprofit space for a while in particular. Well, and I want to invite everyone to look over Mitch's left shoulder as you're looking at him. It's the right, like look at that fun. It's a lily pad, it's a frog and then the logo combined together for pond. So it really is a very like inviting platform not to be intimidating. And I think, again, you've done a great job with the marketing and just the inclusivity when it comes to this. You know, I want to ask you about the overall arching issue for a lot of nonprofits is that, and Jerry and I have been talking about this because it's really been amplified in this last year and a half. There's been a reluctance to investing in tech when it comes to nonprofits. I mean, we see people, we see nonprofits are like, yeah, you know, I'm working off of a laptop that was donated and it's like 12 years old and bear with me, it's not quite working, you know and they don't seem to understand that when you make these investments, it propels you more quickly towards achieving your mission, vision and goals. But how do you sell that? How do you communicate that to an organization that's had a spirit of poverty when it comes to investing in tech? Yeah, I think most problems have a perceived and a real barrier, right? And I think that's our challenge with Pond is how can we structurally with the system lower the real barriers, right? If it's access to information, if it's education or just the ability to meet people where they are to get them started, to start getting them some funding, right, that stays on Pond for you to specifically spend on the things you're discovering there and building up over time. So I think that is a big piece of it is showing that we can lower some of those like structural barriers if you don't know what you need, you don't have the expertise, you don't have the money, you don't have the time if we can structurally lower those, that's a huge win. Now, a lot of the others are perceived barriers, right? It's how are you allocating budget? How are you, you know, there's still hesitation of like getting started on Pond as easy as it could be because there's real trauma, like there's real if you've had a bad experience of the product or you've just like had it drilled into you that 90% of your budget needs to go to the food for the kids you're feeding and your funders or your board or whoever isn't on board with you investing more in infrastructure and those longer-term investments. So I think we're in a position of acknowledging that that's the reality, right? So helping to lower some of the things we can and just creating space for people to engage without having to say, oh, well, I won't be able to afford it. I'll never get this approved. So I'll never have time to do that, right? So getting rid of the like excuse to not dip your toe as Jared said, like, I think that's huge because once we've seen people on the platform get started and they may have previously thought there's nothing that we could afford or there's nothing relevant to help us or my board will never buy this. And yet we've seen many people come through the platform and list and meet with some people. And all of a sudden they were like, well, wow, I was able to take this back to my team. I spent no time on it. I found a bunch of new things I hadn't heard of before. I got $500 from having five meetings and it made it a no-brainer pitch to my board to get started. And that covering maybe it even covered most of my first year, that gave me a lot of runway to prove the ROI on this investment without needing to have a budget battle. And, you know, so I think that that's how we tackle it.  And like, which I think that's a lot of, you know, I'm not born and raised in the sector. I started as an investment banker and then I just made a big pivot to move into nonprofit tech just as a passion area to learn more about. But for me, I was never one that was like, I'm going to come in here and start kind of shouting off the rooftops that funders need to fund more tech and like they should be more grant money going to tech. Like there's room for that and I'm glad people are doing that. But I also think people need to be focused on systems and human beings. And I think those are the two things we can really bring to bear, which is like, how can we empower people and how can we start to change the system? And, you know, that's my approach. You know, if these are big problems, you need a lot of different avenues of people trying to tackle overhead myths and funding gaps. Yeah. So Pond is fairly new. And I, what I find fascinating is perhaps you own this crystal ball that we've all been looking for, Mitch, because this is something that's come about really during COVID, but I don't think it came about because of COVID. And, you know, during this time, and we're still in obviously the global virus pandemic, you know, but so many individuals have gravitated to an increased technology ability. We have seen the ability to, you know, seek out the pond or pond because maybe the expertise you're seeking is not in your backyard, right? Perhaps that expertise you're seeking is in another community, but Pond allows that platform in a tech space to find one another and to have that connection. So that to me is brilliant. And I'm wondering if you could talk to us about, you know, maybe what Pond has provided in parallel with the advances of technology due to COVID. Yeah. I mean, I think a lot of what you're talking to is around access and equity, right? So if you only ever had access to the thing in your neighborhood and the service provider in your neighborhood, you know, that is limiting. It's not ubiquitous and there are information asymmetries and information gaps. The person who's been in the sector for 20 years knows all the right people to call. If you're new and you're closest to the problem you're solving, you know, in an underserved community and wanted to start a nonprofit, you're starting so far behind of a network, of a knowledge base. And because there's no like, oh, you're starting a nonprofit, here's all the stuff you need to do and use and where you can go to find it and make it super easy that doesn't exist. Every step of the way seems like it just is so hard. That really reduces access and equity across the sector. And so I think by democratizing and making that sort of like ubiquitous centralization where, you know, so many things nonprofits utilize are either a tool like a software program, something digital over the internet where it doesn't matter where it's coming from or a virtual or digital service provider also doesn't matter if they're in your backyard. Now everyone can kind of access to everything. And now with that higher volume, you can start to find a lot of efficiency in the matching of people with what they need and who offers it. So I think that that is a big piece. And by the way, the equity and access is not just on the nonprofit side. You also gotta think about the vendors that they're supporting. And if most people took a hard look at their budget line items and the vendors they're paying particularly around tools and technology, they are going to vast majority be white straight men owned operated businesses because that's been the truth in the technology space for so long. And that's another thing I'm really excited about is the access for providers that are diverse owned and operated to now have access to a broader, very accessible pool of potential customers who then can also realistically prioritize finding diverse owned and led businesses because on Pond, we actually flag any business that's owner operated by in itself disclosed with diverse ownership. So people can just share, we're not in the business of saying like, oh no, you're, you know, you don't have enough of a woman or a person of color identity, whatever. It's all self-disclosed by the company themselves. And so then it's up to the organization to say if that's meaningful or not to them, but there's so much access generated in an equity on the provider side where we want people to be starting and building thriving businesses with all types of business owners generating that wealth and prosperity. And I think the nonprofit sector being a catalyst of that is so cool and so fitting. It is fitting and it's really an interesting thing because, you know, we always say you don't know what you don't know and the fear of making an investment or even opening up to somebody and saying, we're not successful at this. I loved at the very beginning that you made this very short statement about how often we fear to move forward because it's quote unquote, not perfect. And it seems to me like what you've created or the structure and the approach that you're taking, it will help you to resolve some of the problems of which you might not even know you have a problem until you get some of that expertise that just helps show you the way. Does that make sense? Yeah, absolutely. And I think that perfectionism and a lot of that kind of white dominant culture that pervades a lot of the nonprofit space given the source of funding and like who the space has been led by for so long, it shows up in so many places, including like someone who's afraid to create an anonymous pawn listing because they're like, well, my question might not be perfect or I don't know, what if I don't know all the tools I use or I don't know the right, and it's just like, get started, right? You're gonna ask a question, you're gonna learn, it doesn't have to be so scary. And I think the urgency of the perfection holds people back in so many ways. And I think a lot of that is good, like obviously we want high standards, you wanna be delivering amazing care and delivering amazing work on your mission and treating your donors as best you can and all of that, but you lose a lot through the like wanting it all to be perfect. And I think applying that energy around perfectionism where it's due and like appreciating where it's not due, like something that you can just get started on and engage with and know it's gonna be imperfect and kind of like seize that, that's how you're gonna start actually to your point finding out things you didn't know because you weren't trying to paint this perfect picture like you've got everything going on. Because if you don't share what's actually going on, you're never gonna get the actual help you need. So it's like, what are you protecting?  I was always one of those kids growing up. It was like, I'm too embarrassed to ask that question, right? Or please don't call on me because I'm pretty sure I don't know the answer.  And now many of our up and coming leaders are, which is fascinating, but I remember in my first fundraising job, the director of development was telling me, she was mentioning about our constituencies. And I said, what is constituency? Like I didn't know that word. And so the vernacular in the sector is very new. And I can only imagine how intimidating it is for someone that's new in the sector or this is their first job, but there's so much potential when we can answer these questions, when we can provide a platform like Pond to provide that expertise, because it is often really intimidating, very difficult to jump into when so many of us, me included, nerd out over this. And I just throw the jargon vernacular the link. Like that's just what I do because I've been doing it for 20 years, but I just want to fuss up to all of you. I wasn't born and raised in this sector either. Like I had to learn this language. So I love that Pond really provides that inclusivity for all levels, all levels of leaders. Well, it's changing. I think the other thing too is, I mean, look at our sector 18 months ago, we're saying and doing things in a way that we would have never, ever thought of, right? Which I love the disruption. And I am going to like say, give you a gold star, Mitch, because Pond is a disruption. It is an innovative disruption. And thank God, because it's time. We need it. Well, yeah, I think it's the important thing with disruption. And I like to think of it more of like an evolution. It's like a growing change as much as less of like a goal to break things in the way that they're done today. Because I do think that the worst driving for is like bringing everybody along into a better system and not necessarily saying like, oh, that's trash, whatever exists today. It's like, it's not about that at all. It's just about evolving with everyone. And a big part of that is, you know, because I came from a different background, I did a lot of fundraising and volunteer board service. And that was my entree into the sector, but I would not claim that means I have deep lived experience leading a nonprofit, which a lot of board members don't realize. I'm only so aware of that. But I think what has it allowed us to do is not think that we know everything, right? As a company and be able to say like, I'm a sponge, I'm talking to nonprofits every day, learning from them. And that's all getting incorporated into how we build this platform. But guess what? It's also changing every week. And we're learning from people that use it. And we are not saying it's done and dusted or perfect in any way. If it were, how boring would that be for us, right? Like we have so far to go in evolving it and meeting needs. And so I would just say cherish the outsider, whether that's like in yourself or in your team or in this conversation, that fresh perspective doesn't need to be threatening. It can actually be really exciting. And sometimes I think we're tempted and I've come across this in a space where it's like, oh, well, you haven't been doing this for 20 years. So how could you have a valid viewpoint or opinion? And the reason we have seen such disruption in the past 18 months is because there are like shifting environments and new perspectives. And that's what we're gonna need to evolve the space. I love the evolution and you're right. So many times people see disruption or they hear the word and they think of it as a negative connotation. And it really simply is this evolution of change as we continue to change and evolve for our constituency, for our community, all of this is necessary. How we deliver our services is evolving. And that's for everyone and we will continue to navigate that just for your event this evening. It's a whole new evolution. And I think the thing too, Jared, exactly what you're saying is that we in the nonprofit sector need to realize that our clients needs and stresses are changing. And so we look at how we deal with let's say the food pantry, food bank sector. It's not just about getting people food. It's about understanding what type of food they need, where to get the food, when to get the food, how to prepare the food. I mean, it's a much deeper discussion than I think a lot of nonprofits have had because we've just been like, okay, this is a crisis. Let's get the bandaid on it and move on to the next move. Yeah, and so I love what you've had to say, Mitch. I'm very appreciative that you actually showed up today because if it were me, I'd be like, oh, but I'm like, can't talk. I would be like, onto the real crisis of the day. And so I give you a gold star and a halo in heaven for actually taking time out to talk with us because this is really impressive. Please let us know how your staggered event went. I definitely will. I will definitely keep you posted. I'm sure it's gonna be great. I'm sure there'll be more surprises in store and I'm just excited to finally get to chat with some of the folks and that's what it's all about. It is, what you have been a really, I don't know, man, I just needed to hear some of the things that you had to say today more than you will ever know, really cool. So thank you from Julia Patrick for making my day better because I'm gonna refocus on some things in a different way. And Jared, I don't know how you feel, but for me, there were some things you said that were just like, wow. Well, it's really gonna be fun to watch your journey. You know, I give anybody a lot of credit who takes on a daunting task during a time that is daunting. You know, and you didn't choose the easy path and I think that's really exciting. So again, everybody, if you haven't met us before, I'm Julia Patrick, CEO of the American Nonprofit Academy. I've been joined today by the nonprofit nerd herself, Jared Ransom, CEO of the Raven Group. We want to make sure that we acknowledge our presenting sponsors. And I was thinking as we were talking, Jared, you know, a lot of our sponsors because of the pandemic have really added digital components to their products and service line that they probably hadn't anticipated. Now that maybe it was on the drawing board, but they've really had to move and be nimble quickly. So we wanna express our gratitude to those folks because they afford us the opportunity to be with you every day. But we are thrilled and honored that you would spend your time with us to all of our viewers and to our sponsors and to folks that are watching us in our archive, even live, we want to remind you to stay well, so you can do well. Thank you, everybody. We'll see you back here tomorrow.


If anyone holds of us by fee farm, by sockage, or by burguage, and holds land of another by night service, we will not by reason of that fee farm, sockage, or burguage, have the wardship of his heir, or of land of his that is of the thief of the other, nor will we have custody of the fee farm, sockage, or burguage, unless such fee farm owes night service. We will not have custody of anyone's heir or land which he holds of another by night service, by reason of any petty certainty which he holds of us, by the service of rendering to us knives or arrows or the like.


All right. Hi. Back. So today is Friday. We're going to pretend like nothing happened this week. And I was here. How many people watch the videos? OK, that's good. Because I'm just going on like pretending like nothing happened. OK, so today what we're going to do after we get done in Mary and Maria-Claue is talk about schedulers. So last couple lectures went out to the point where we've motivated the scheduling problem. You guys understand why scheduling is important. And we've talked about some of the goals of thread scheduling, as I was on Wednesday. Today what we're going to do is actually start talking about some real schedulers. So today we'll present a couple of fairly simple schedulers. And then we'll talk about slightly more complicated schedulers. And then on Monday, I have a lecture where we look at something that was modern four years ago, but a relatively modern approach at improving schedule down on Linux. And kind of a fun story about Linux development in the Linux community. So we'll do that on Monday. OK, so you have two weeks from today to complete assignment two. How many people have started? OK, thank you. So unlike assignment one, we're not going to accidentally give out three-fifths of the points. If we do, I'm just going to take my ball and go home and just give you guys all A's and be done.  That's the other thing. Not me. So we're not going to do that. So the solution that you have right now, we check the assignment one solution set gets zero out of 150 on assignment two. It's exactly the way it should be. The assignment two solution set gets 150 out of 150. So there's a lot of points on the table for assignment two a lot more than for assignment one. So please start the assignment. A good portion of this assignment is also just kind of figuring out what to do. There's not necessarily a huge amount of code to write, especially for the file system system calls. Most of the work is being done for you. However, if you don't know how to do it, then you can end up writing a lot of extra code. And things are really ugly. So please come in, talk to the core staff in office hours. Remember, as I posted on Discord, starting next week, when you come for help in office hours, the first question that I am commanding the TAs to ask is show me where you design this. Show me your design document. So the design document, the format is up to you. I would suggest that you either write it in some sort of markup and check it into your repository so you and your partner can collaborate on it. Or another good alternative is put it in a Google doc. Please don't use Microsoft Word documents or terrible things like that. If you do, we will certainly help you, but we also make fun of you at the same time. But that's going to be the first question when you come into office hours. Where is your design? We want to see this designed. If you haven't designed it, we're going to tell you, go back and design it. When you're done designing it and then you take a stab at implementing it and you run into trouble, then we'll help you. So this is how we're enforcing that you need. You really need to design for this assignment trust me. So before we were getting ready for the class, Isaac, who's one of our ninjas, said, I tried that last year. He said, I tried not designing. And he said, I ended up making a mess and then starting over and designing it. So you can either go down that route if you want to, or you can just take my advice and design first. I know a lot of you guys aren't going to do it, but that's the point. This is a learning experience, but the TAs will be asking you to see designs. So the screencasters sign it to our up. Thanks to Guru for doing those. If you have any complaints, please forward them to Guru, not me. I think they're probably pretty good. I haven't seen them myself. It's awkward enough for me to watch me. I'm not going to watch Guru. So and if you are working alone on assignment two, please contact us. We have some information for you that you will probably want. And so if you haven't emailed us, or if you've emailed us, we haven't got back to you. We'll work through that queue today, but please email us if you're working alone on assignment two. Finally, any questions about test 161? So unfortunately, I wasn't here to see what happened on Monday. I think things went smoothly. It seems like everybody managed to use the tool. Not a lot of changes for assignment two. Actually, Scott's made a lot of, has fixed a bunch of things. So the tool's going to actually get easier to use. A little bit more intuitive. And we're going to be able to help you sort of handle some of the corner cases that you guys ran into where you didn't follow our instructions or whatever. So that will help. But pretty much, same deal for assignment two. Not much changes. Except this time, we'll be running a lot of things in user space rather than the Chrome. Any questions? Yeah? I have really a question about more of a comment. Yeah. How would I recommend putting in the troubleshooting section of that, making sure that it doesn't happen? Yep. Absolutely. This course did have somebody posted on there, because they probably had the same problem that I did. About 30 minutes, I was getting the not authenticating or whatever. And it's just because test was happening. And I'll try to remind you to do that. It's one command, happily. Just one command you have to run. I don't know. Maybe I'll add this to something so it happens repeatedly. But yeah, it's always safe to do. Whenever you want to, just we're not merging things into master for Dust 161 until they're ready to go. So if you're having a problem, it's not a bad thing to try. So yeah, we'll put it to the other troubleshooting document. Thank you for that comment. Any other questions, comments? We'll have the new targets for assignment two in the point breakdown updated on Monday. We have some changes that you're also going to have to integrate from our staff repo to OS 161 as well. OK. Oh yeah, I said the thing about partners. And I think I was trying to remember to say something. And I think that was it. So I'm good. OK. So let's do a little bit of reviews since I wasn't here. So describe what is thread scheduling? Fundamentally, what is the process of thread scheduling? What does it have to decide? Somebody describe the problem to me. Ron, want to take a stab at it? What is the number of things of prioritize scheduling? What resources to allow a particular thread to have access to to give important thread? How long to allow the threads to run? Well, let's try to make it as simple as possible, right? Those are all parts of the right answer. What is if you could boil it down to as simple as possible? Yeah. Yeah, exactly. I've got a bunch of threads that are runnable. Remember the thread state lecture we talked about the fact that there are times when threads are not runnable. They're waiting for something to happen, whatever. But I have a set of runnable threads. I have a set of cores. If that set of cores is larger than the set of runnable threads and I'm in good shape, I don't really have to make a decision. I do. There are some interesting subtleties to multi-core scheduling in terms of figuring out what gets to run where because there's a cost to moving threads between multiple cores. But let's ignore that for the time being. Essentially, if I have more cores than I have threads and I'm in OK shape, if I have more threads that are runnable, then I have cores that I have to decide what thread gets to run next or what threads get to run next if I'm on a multi-cores. And I have to repeatedly do that decision. So another way of thinking about thread scheduling is given a set of threads to run, what order am I going to run them in? Now the problem with that view is, of course, that set that's runnable is changing all the time because a thread is waiting for something, that way it completes, now it can run again, and so it comes back onto the run queue. So the best way to think about thread scheduling is a periodic decision that's made by the kernel where it looks at all the threads that are runnable and decides which are going to run now. Clearly, one of the things I want to consider is making sure that certain threads get to run eventually. If I'm picking the same threads over and over again, I'm not doing a good job of making all the resources on the machine available to all the threads. Does that make sense? So scheduling. So I'm choosing the next thread or threads to run on the CPUs. Why does the kernel have to do this? Why am I, why is thread scheduling something that the kernel has to do? Yeah. Yeah, well, right, I mean, if I don't schedule a thread it never gets to run, but the cores on the machine are one of the most important resources that the operating system is multiplexing. So this is, we talked about context switching as the mechanism by which I multiplex. Context switching and preemption make it possible for the operating system to regain control of a core so that it can choose another thread to run. This is the choice part. So this is the policy, whereas the context switching is the mechanism. Rhonda, do you have a comment or question? Oh, okay, well, I answered. I got to answer my own question. Makes me feel good. All right. And normally, and also it's good to point out, normally we have this problem, right, where I don't need to multiplex a resource if I have enough of it, but usually I have more threads that are ready to run than I have cores that I'm able to run them on. And so it's my decision as the kernel, this is my job, right? You elected me to be in charge of your system when you installed me and allowed me to run first. So I get to run in privilege mode. This is one of the things that goes along with that. So when does the kernel have an opportunity to schedule CPU cores? When does this decision get me? When can't, let's put it this way. When can the decision get me, for Josh? Well, okay, that's one of the cases, right? So if the current thread exits, clearly there's a core that's now free, okay? What else? What are other cases? Okay, yeah. Well, the context which is the mechanism, right? This is, yeah, so a context which occurs, but another way of asking this question is when does a context which happen? Yeah. Okay, so the timer, right? Remember, this is a key component of preemptive scheduling. Those timer interrupts that I know are guaranteed to arrive as long as interrupts are enabled, guarantee that the kernel has a periodic chance to reexamine the state of the world and decide what to do, right? So even if a thread just wants to compute pi or do something else that's very compute intensive, the timer interrupt makes sure that even if that thread doesn't block for other reasons, the kernel still gets a chance to run periodically. It can thus also happen when a thread exits. Thread can, in certain cases, threads can voluntarily give up the CPU. You saw this all over our test code and that's there because we're trying to get a good mix of, we're trying to make sure there's enough entropy in the threads as they pass through the test so that you can't do silly things in your synchronization problems where you assume something about the order of threads. So all that random yield or that you guys all over the place is just forcing that thread to repeatedly some random number of times give up the CPU and allow something else to run. In that case, the thread, remember, is still runnable so it's state doesn't change but it's allowing the kernel voluntarily to make another scheduling decision. When threads make system call, so this is an important opportunity for me to reschedule things if I want to because the kernel is now running. In some cases, a system call will cause a thread to block in which case I have a situation that's similar to thread exit where I now have a core that's free and so this is a chance for me to make a scheduling decision and choose another thread to run on that call and the timer. So is everybody clear about these conditions? Okay, technically the last one you can expand a little that any time there's an interrupt that gets processed in theory, the kernel is running and the kernel could decide that that thread, whatever thread was running when the interrupt fired, has run long enough. It's usually, I don't think usually most hardware interrupts are used to trigger the scheduler but I could be wrong. On your system, they're triggered by the timer. Okay, so on Wednesday we had talked about some of the goals and this is really something that's uniquely suited to interactive systems. On backend systems, the goals are sometimes a little bit simpler and this is something we'll come back to on Monday. So on a server you might say, you know, my goal is throughput, I just wanna maximize the number of tasks per hour, right? Then, you know, if you're Google you might say, my goal with this machine is just to allow it to handle as many search requests or whatever Google is doing with it per hour. Just maximize throughput. On an interactive machine, the expectation is a little bit different, right? So, you know, I need to make sure that when you interact with the machine, the latency is short enough that the machine feels interactive. So when you press a key, what do you expect to happen? You think that there's a character that should appear on the screen at a particular place. If that doesn't happen for a long period of time, the machine feels slow, right? We talked about the idea that certain things have to happen at regular intervals, such as when you're watching a movie or watching, listening to audio. You know, if I decide that it's a great time to compute Pi right in the middle of your YouTube video and I stall that YouTube video for long enough, you're gonna get annoyed because the frames are gonna start to drop. It's gonna stall, whatever. Usually that's not why YouTube videos stall. Usually it's network problems. And then the fact, the final thing is, there are these long running background jobs that you do expect to be able to complete periodically. So we talked about things like virus scans and building indexes for things like spotlight and search features that your computer has. So these are some of the expectations that you have as a user. You know, I've been having this very interesting experience. So I have this sort of insanely overpowered machine under my desk. I think it has like 20 cores. It's like a Xeon with 20 cores that has 64 gigabytes of memory. It has like two flash drives that are rated together for no reason. And it is slow, right? It is irritatingly slow sometimes, like interactively. So I'll hit a key to switch windows and you can like feel it stall. And I'm thinking, how on earth did I do this, right?  So scheduling matters, that's what I wanna point out. Like something is wrong with that machine. It is not the hardware. The hardware is golden. The problem is in some somehow in how the hardware is being used. I have no idea what the problem is. I wish I knew and I could fix it. But something is, something is going wrong. Okay. So then we talked about some ways to evaluate schedulers. So one way to evaluate schedulers is to say, is it capable of meeting these deadlines? So when the input event comes in, the timer starts. And if it doesn't finish some long series of actions before a particular period of time, you start to feel like the machine is lagging. And then this goal of interactivity is at some level very much in tension with trying to allocate all of the system's resources. So if I have a bunch of things to do, try to make sure that the CPU is all CPU cores are fully loaded. The storage is super busy if there are things that are trying to use storage. Essentially putting all of your computer's resources to full use all the time, right? So, and then I pointed out that on these human facing systems, deadlines usually take priority or they should. Again, if something seems to be going wrong on my machine, why is that? And the human facing system will usually try to bias things toward interactivity as opposed to towards throughput, towards making best use of the resources on the system. Why is that? Yeah. If everything for the user is running slow, they're just gonna get up and walk away. Yeah, I like that. It's talking about products. So if your product does a good job of that, then yeah, it's gonna feel slow. Even if it's doing a good job of making use of system resources. And the reason is that your time is way more valuable than your computers. So keep this in mind, always. When you're interacting with the computer, again, computers are super good at super things, at certain things like adding numbers, right? You have higher mental capacities that the computer does not have. So if the computer is wasting your time and it's making you hard to type and stuff like that, that's super annoying. And it's really a poor use of all the resources on the system. The computer may think, hey, I'm making great use of my memory, right? I'm really making all these cores run really fast. And you're thinking, I've been here for hours and I would like to go and think some higher thoughts, right? I'd like to write some poetry, paint a picture, all the stuff that computers cannot do. So stop slowing me down. I've got a life to live. Okay. And then the final thing that we were concerned about when we evaluate schedulers is performance. So if the overhead of scheduling itself is too high, nothing else matters. And this is another thing that we'll come back to over and over again when we talk about operating systems because operating systems are this interesting case. So some of you guys may have learned in other classes these super fancy algorithms and machine learning approaches to doing blah, blah, blah, blah, blah, blah, blah, right? And a lot of those don't get used by operating systems and you might think, well, why? And the answer is it doesn't matter. It doesn't matter enough. If you spend 10 times as long to make a decision that's only 10% better, who cares? Nobody cares. The operating system, you don't care. All you feel like is that the system is slow. Scheduling is wasted cycles. Any cycles that the operating system has to devote to scheduling are wasted. The point of scheduling is to make the resources available to the useful programs that are running, not have the kernel spend a lot of time to do some sort of fancy thing that doesn't improve performance very much. So this is something to keep in mind. Okay. And scheduling is sort of a balance between these things, right? Responsiveness requires meeting deadlines, continuity and other things require through. Okay. Any questions about this? I know we did more of you today than usual. Yes, that's a great question. So what happens when CPUs are idle? So it really depends. There's an idle loop on most operating systems that will just run no ops, right? So a lot of CPUs have a no-op instruction and they'll just sit in a loop running no ops, right? On the other hand, it's also advantageous on some systems for you to actually be able to power that core down. So on smartphones, for example, now there's usually a cost to taking the core on and off line to take some time. So I don't wanna do it too soon, but if your smartphone sees that a particular core has been idle for a while, it might decide, yeah, I don't need this core.  So it turns out going back to this issue of throughput, we've been doing some studies on smartphones and we found that the number of cores that are in use by typical smartphones is not very high. There's some thermal management problems that are partly to blame, but your four core smartphone, hopefully is not using those four cores very often, right? Okay, did that answer your question? Yeah, any other questions? That's a good question. Okay, all right, so let's go on. So today we're gonna talk about a couple of different types of schedulers. Whenever you talk about an algorithm, and scheduling, it's fundamentally, we're talking about an algorithm. It's useful to talk about some simple cases that are as simple as possible, right? So to the degree, so actually, so we're gonna talk about schedulers that use some different pieces of information, but we're also gonna talk about schedulers that don't use any of these pieces of information, right, because they're a good baseline. But what are some of the things that you might want to know, okay? So, again, scheduling is an algorithm. One of the inputs to your algorithm has to be the list of threads that can be run. What are some other things that a scheduler might want to know, or might want to keep track of, yeah? Okay, yeah, so what things are, what programs does the user are working with? That's very interesting, right? So that sort of makes me, I'm gonna lead that answer in the direction of sort of distinguishing between stuff that you're actually interacting with, like an interactive program and something that's running in the background, right? So that could be useful. What else, Ron? Yeah, so I might need to know something about the other resources that that thread is using, because keep in mind, the CPU is kind of the bottleneck for the rest of the system in terms of resources. If I want to use the disk, I have to run on the CPU. If I want to use the network, I have to run on the CPU. If I want to read or write to memory, I have to run on the CPU. Everything goes through the CPU. So even if all I want to do is fire off a network request that's about to take two minutes, I've got to run first. Just to be able to do this few instructions is probably not that small a number, to be able to use those other resources. So yeah, dependencies between resources on the system because the CPU, again, if I can't, even if all I want to do is use some other part of the system, I have to start with the CPU. I have to start by being able to run. Okay, so that's a good point. What else? Just basic stuff. What else would you want to know? Yeah, like I might want to know what the threat is going to do. If I could predict something about what the threat is going to do. I also probably want to know statistics about threads on the system. How often have they been run? How much time have they already had on the CPU? Ron bought off the issue of priorities, which is sort of a way to layer on other information. The scheduler doesn't necessarily know anything about why you've assigned priorities to threads, but the whole point of priorities is to give you a way of sort of layering on other information on top of the scheduler. So when you assign a high priority to a task or to a thread, you're telling the scheduler, hey, this is important. And the scheduler says, you know, I have no idea why you want to run that prime computing program at such a high priority, but it's not my business. I'm just gonna do what you said, right? All right, so here are some of the things. So what will happen next? So we're gonna talk about one scheduler, and this is, again, when you talk about these sorts of algorithms, it's always fun to talk about algorithms that you cannot implement. So this is what I refer to as the oracular scheduler. It is able to see the future. It has a crystal ball and can actually tell things about the future that we cannot in real life. The other, again, the reason to talk about schedulers like this is, again, they're good baselines, because if you can do almost as well as one of those schedulers that can predict the future on a real system, you're doing quite well, right? A lot of times, schedulers use historical information about what just happened. So how long has the thread run? How long has it run since it last blocked? Someone pointed out what resources is the thread using? And then what does the user want? So this is where priorities come into play. This gives you an ability to provide external inputs into the scheduling algorithm that are gonna be used alongside the other. Okay, so let's talk about, but first let's talk about some schedulers that do, that know nothing, right? So all of these schedulers take as inputs is the list of threads to run. So what is probably the simplest, simplest scheduling algorithm? Yeah? No, random, right? Why is random simpler than first and first out? What is first and first out have to maintain? A queue, random does not, right? So yeah, so the FIVO is pretty simple too, right? But random is a little bit simpler, right? So all random does is says, you gave me a list, I take a random number, I pick the one from the list, I'm done, right? I don't have to track anything about the thread. You give me a new list of threads, I take another random number, you get it, right? All right, so I think I have a long, incredibly detailed boring diagram to show you how randomness works in this context. Hopefully you'll enjoy it. But you know, so here's what happens, right? I've got a bunch of threads on the ready queue. They start to run. Now we're gonna use this as a basis when we talk about other schedulers. So something that schedulers also decide, or can decide when they start to run a thread, is what's the longest amount of time I'm gonna let that thread run before I make another scheduling decision? This is frequently known as a scheduling quantum. So here I've got the scheduling quantum right here. Okay, I've used my laser pointer for the day, that felt good. All right, so now what happens? So I've chosen thread T3 to run at random. Either one of two things happens now. There's two possible outcomes here. What's one of them? Well right, I mean it either runs to the quantum, at which point I need to stop it and make another scheduling decision, or it blocks at some point. So it's possible that this thread is going to run to its quantum. This thread is in the midst of doing some piece of computation. It doesn't need to make a system call. It doesn't need to block waiting for something to happen. Okay, now what does the random scheduler do? So the thread is exhausted, it's quantum. Where does this thread go? Go back to our states, right? This goes back into the ready pile. This is a pile right now to queue, this is random. This goes back into the ready pile. Then what do I do? I pick another one at random, okay? Now let's say this guy blocks, so where's he going? He's gotta be waiting for something if he finished before his quantum. Now technically that's not true. He could have yielded, but anyway, he wouldn't have yielded. She might have yielded, right? She's nicer than he is. He did not yield, he blocked. Okay, so what do I do next? Randomly select another one, run it till either it hits the quantum or it blocks. You guys get the idea, right? What else can happen here as I'm going along? What's the reason that I wanna be able to make this decision repeatedly? Yeah, yeah, this is random, right? So I could choose the same thread twice, right? If the run queue only has one thread on it, that I can just keep running that thread over and over. But even if the run queue has one thread on it, why do I wanna probably continue to re-run the scheduling algorithm? So let's say we get to the point where all the threads are waiting except for T3. I'm just picking T3. Why not just let T3 run until it blocks? Say, you know what, T3? Everybody else is asleep, you're busy. I'm just gonna not give you a quantum. I'm never gonna interrupt you. I'm just gonna let you run until you block. Why not? Why can't I do that? Yeah. Yeah, so it's possible another one of those threads that was over there in the waiting, it state changes. So normally what will happen is like some other interrupt will fire, like a network packet was received, and that interrupt will mark this thread as being ready again. It usually will not reschedule anything immediately. All it does is say, okay, this thread is no longer waiting. The next time the scheduler runs, it finds it in the ready pile and schedules it with everything else. This is why even if there's only one thread to run, I need to periodically reexamine my scheduling decision. I might give it a longer quantum because there's nobody else waiting, but I still need to periodically run the scheduler to see if the ready pile has changed. Okay. And on this goes. So random scheduling, here's my algorithm. I choose the scheduling quantum. This is common to a lot of the algorithms and a lot of scheduling, modern scheduling algorithms. We use multiple scheduling quantms under certain conditions, but you can imagine for simplicity's sake, without loss of generality, I choose one. Then I choose a thread at random. I run it till it blocks or the scheduling quantum expires. When the thread leaves the waiting state, I, oh, hello. I guess it's interesting. You guys could probably jam this thing, right? Somebody could be messing with me. Start to collect the signal from this device and start controlling this line. Anyway, if that's interesting to you, try it. I don't know, that would weird me out. So I put it back on the ready pile when it's done, right? Any questions about random? So why discuss random scheduling at all? This seems really obvious. Like why am I telling you about random? Why are we talking about random? Why are we about to talk about Ron Robbins? Why talk about the scheduling algorithm is so simple. Yeah. So it turns out random might not actually be that bad. So let's say you decide, like this guy we're gonna talk about on Monday, who's from Australia did, I can write a new scheduling algorithm. I have a better idea for how to schedule things. And this happens, right? Linux scheduler has changed in the recent history. And you put a lot of time and effort into it, a couple months go by and you're testing it and you think it works awesome, okay? Why might you want to have a random scheduler lying around? Yeah. Yeah, so if random outperforms your scheduler, you're not doing a very good job. And here's the thing, it's unlikely that random is making better decisions than your scheduler is making. But what is random also doing or not doing? Well, that's true, that's true. Ron Boat's out, it doesn't make good decisions or bad decisions. The random is also super fast. So it's possible that the overhead, like I said before, the overhead of your scheduler is actually so bad that random is catching up. Random isn't making good decisions or bad decisions, it's just making more decisions more quickly. And so the overhead of your scheduler is actually reducing some performance. So the simple scheduler is gonna be a great way to, great thing to compare it gets. Cause if you can't beat random, stop with that algorithm and give up. Cause it doesn't work, yeah. What do you mean? You need one. You're allowed to pick random threads in random because you're assuming the threads won't like use parts of memory that other threads are waiting on. They're handling critical search. Okay, so that's a good point. I mean, remember, if I had a critical section, so if I'm inside the kernel and I'm waiting on a lock, where am I going to be? Right? So let's say I've got 10 threads that are competed over a lock. Hopefully, where are they going to be? And I need to give him a point of time. Where? All of them? So hopefully nine of them will be in the waiting pile. One of them will be running. So whatever's inside the critical section will run. And then when it's done, it will use the wait channel to broadcast. Now, you make a good point about the fact that these schedulers can't necessarily see more complex dependencies between threads, right? In terms of using memory, we'll come back to that. I mean, the OS has lots of mechanisms to make sure that threads don't share memory or sound on each other's memory in other ways, right? If a thread dies, it's clearly taken off of the scheduling. Does that make sense? Cool. All right, so round robin scheduling is pretty much the same thing, except I have to establish some kind of order. One way to do it is when a thread goes to the wait queue, just put it back on the end of the queue. When it comes back, I might put it on the front of the queue if I'm trying to be nice because it did some waiting and now I can move it to the front of the line, right? But this is pretty much the same as random, except for the fact that I'm using, imposing order using a queue, okay? Okay, just said that. So, and these, again, these are by far the simplest scheduling algorithms, they don't use any information about the past, which they could collect, or the future, which they can't. And they don't accept any user input, but these are useful in the context of comparing them with other things. Oh, Lord Almighty, what's going on with this thing? The other thing I want to point out because we'll come back to this, is that these algorithms, because they're choosing a fixed size quantum every time, if I'm a thread that blocks a lot, like for example, if I'm a thread that's processing user input, so essentially what happens is the user presses a key, I wake up, I process the input, we go back to sleep, these algorithms have the effect of penalizing me. Why is that? So compare a thread that, when it wakes up only does a small amount of work before blocking again, with a thread that always uses its entire quantum. Who gets more CPU time on random and round robin? Yeah. You have to get blocked for the waiting. Well, okay, let me make the question a little bit different. Let's say that both threads, so let's say both threads have 100 chances to run. Let's say when the one thread blocks, it doesn't block for very long, okay? So it wakes up, does a small amount of work blocks, but then very quickly it's ready to run again. So let's say over a certain period of time, both threads run 100 times. Which thread has been able to use more CPU? That's it? Why? It's lost because it doesn't have an opportunity to reuse it. Yeah, exactly. So the point is if I block, whatever was left in my quantum is gone. Neither one of these schedulers cares. They're like, sorry, you blocked. This is how I work. You're back on the waiting queue. So the thread that runs is computing pi or doing something computationally intensive. It's gonna use all of those 100 quanta. And the other thread by definition is blocking quickly. And so it's gonna use very small amount each time. So it's gonna get a lot less CPU, right? And this is an issue with these types of scheduling approaches. So the last thing I wanna point out is that round robin's scheduling are sometimes random. There's certain cases where other schedulers will get to the point where a group of threads is equivalent from their perspective. I've done some other things. I've made some other calculations. I've used my priorities and other information I'm about to talk about. And what I end up with is to say, eh, these four threads are kind of the same. And so round robin can be a useful primitive at that point, because I might say, well, if I can't distinguish between threads anymore, the most fair thing to do is just to run them in order. Okay. So now let's talk about a different group of somewhat impractical schedulers. And these are schedulers that can actually use information about the future that would not normally be available through a schedule. So I'll call these the know-it-alls, right? And here's some of the things that we might wanna know about a thread before I actually start to run it. The first thing I might like to know is how long is it going to run for? And then, is it going to block or yield? Will it end up in the waiting queue for the waiting pile or back in the ready queue? And if it waits, how long is it going to wait? So if I'm thinking about, well, I'll come back to this when I show the diagram, but if I'm thinking about the case I just mentioned where there's a thread that's maybe rendering key presses, so it does a small amount of work and then blocks for a relatively long amount of time, because it's waiting for you and you're slow. The way I schedule these threads, if I knew this, I can actually make some pretty nice scheduling decisions, right? This is know-it-all cat. I don't know why. I think my cat looks smarter than that cat most of the time. Okay, so let's talk about how I might know this. So let's imagine this is my ready queue, ready pile. And let's imagine that the scheduler actually knows how long each thread is going to run before it blocks. So one way to schedule things at this point, there's an algorithm called shortest job first. So what shortest job first does is it says, and you can apply this either, you can either consider a job as being the time until I block again, or you can imagine that I knew exactly how long this task would take to finish whatever it's doing. But I interact with systems that usually doesn't happen. Yeah. What's that? Yeah, I mean, this is an instance of a greedy algorithm, right? Except that it knows something that the algorithm cannot know, right? So remember, normally I have no idea how long a thread is going to run before it blocks. And to some degree, this is unknowable, yeah. Great question. I was yielding so that could be an estimate for how long it'll run for. Yeah, so in certain cases, I might actually be able to, if I looked, yeah, so essentially if I looked at the code flow, why is this hard? It could. In certain cases, you might be able to pre-compute this. I feel like this is a great midterm question that's emerging out of this conversation. But what frustrates this sort of analysis? In some cases, you're right, right? In some cases, I might get it right. In fact, I might see that there's this huge swath of instructions with no jumps, no branches, no whatever. And I might say, oh, okay, well, this thread is definitely gonna run for a long time. Yeah. Yeah, so there's the problem with this, and this would be a fun thing to try, but the problem with this approach is in general, thread behavior at runtime is highly non-deterministic, right? It depends on state and memory, it depends on user inputs, it depends on all sorts of stuff, right? Now, it turns out, well, we'll come back to this when we talk about memory management in like a month, because it turns out there's, and I'll just leave this as a little bit of a hanging trivia question, there is a brief period of time where the execution of threads on the system is highly predictable. I'll just let you think about when that is, and we'll come back and talk about it when we talk about memory management.  But it'll be a fun thing to try. Okay, so I know this, and what shortest job first does is it just orders the jobs, it runs things in order, from shortest to longest, okay? And why, so why do we use this algorithm? Like what is shortest job first actually achieving? Yeah? Well, the throughput's the same. Okay, so that's a great question. So I would argue the throughput is sort of, now if you look at instantaneous throughput, but if I say how long is it gonna take me to finish these five tasks? It doesn't matter at all, right? So you finish the first three in the amount of time that it takes to finish the last one, so maybe you finish more faster? Yeah, so it minimizes waiting time, right? So it turns out any other ordering of these, if I average out the waiting time, so the waiting time is, this is the waiting time for T2, this is for T5 from here, right? T4, T1, T3, if I average those out, this will minimize waiting time. Yeah. Yeah, so in this algorithm I run things until I know they're gonna finish, right? Because remember, I know that they're going to finish.  They're gonna do some sort of blocking operation that's gonna cause them to stop, right? Because we're not talking about a batch scheduling system here. Now on a batch scheduling system, let's say these were running for hours, this is still a good way to run things, right? Because these are some sort of job, like this is Google updating its indexes or whatever, and Google actually kind of cares about the minimum waiting time, right? Because something has to happen every night and the faster some of these things are done, the faster certain parts of their infrastructure are updated or whatever, right? So on batch scheduling systems, this can be really nice. On interactive systems, this requires, now on batch scheduling systems, you might also know this because you've run this job before, right?  On an interactive system where the threads are going to block, not finish, that's what makes it very hard, right? Because A, the time quantum's are much smaller, and B, it depends on a lot of things that are impossible to predict. Okay. So this minimizes waiting time. But let's try to apply a general principle here, right? So what we're gonna do today, and I guess on Monday, is talk a little bit about preferring threads that quickly give up the CPU. And this is a hint about what threads are doing that has made its way into a lot of schedulers, a lot of schedule in algorithms. So a thread that goes from blocked, runs for a little bit, and then blocks again, what does that thread possibly do? That the scheduler might want to be able to identify. What's causing that pattern of activity? Waiting for input, input from who? You, right? So a lot of scheduling algorithms, and again, we talk about the old, old, the next scheduler next time, that one of the improvements that the guy we're gonna talk about was trying to make to it, is that it had developed this interactivity detection that was completely, as he described it, black magic. It had all these weird computations it was doing to try to figure out this thing that sounds very simple, like is the thread interacting with the user? But it turns out it's very hard to figure out. It's very hard for the scheduler to figure this out. And he proposed something that did a better job with this, right? So, and oh, okay, sorry. So there's another reason for this. Sometimes I should let the slides tell me what to say. The other reason is, if a thread runs for a period of time and then goes back to sleep, what I probably allowed it to do is get some other part of the system busy. Now an interactive thread, that other part of the system is you, right? Because maybe what it did is it wrote the character of the console and now you're thinking. But if it runs quickly in blocks, it could be using the network, it could be using the disk. And so now it's done, and now I have one part of the system is busy, whatever it made busy in that short period of time, and I have a core back that I can use for something else. So in the pursuit of trying to keep a lot of different parts of the system busy, if all the thread needs to do is run, for like a very short period of time and then it's gonna fire off a big network request, that's great, right? I should do that right away, because now I've got the network busy and I can schedule some CPU activity on top, right? Okay, and just let me, so let's imagine in this case, I know not only how long the thread is going to run, but I also know how long the operation that it's about to perform is going to take. Now, these aren't really to scale. On a real system, like some of these would be like this and some would be like, you know, way out here or whatever, right? But this is what I had to do to get to fit on the slide. So you'll see, so here's the worst case scenario. Here's if I do the longest job first, okay? And you'll see that what's happened is that, you know, imagine that this is, you know, when this is scheduled, the CPU is busy, but when this is overlapping with the CPU, I've kept something else busy. And it turns out that all, if I look at the waiting time, so this is essentially the time between when the thread ran and the time it was waiting to have the CPU again. This, you can kind of see what size this area is. This is the worst case scenario. This is if I ran longest job first, okay? If I run shortest job first, what's happened is I've paralyzed a lot of the other things that the threads are doing, like this, this overlapped, this overlapped, pretty much every other operation that the threads were performing was done in parallel with the CPU being used. And so the amount of waiting time among all those threads is small. Can you guys see this on these slides? So if you compare this to that, right? See that, that's bigger, right? And it's bred because it's bad, right? So this is bigger, more bad stuff on this slide and less bad stuff on this slide. The way I've achieved this is simply by running the shortest job first, okay? What's that? Oh, sorry, oh gosh. I feel terrible about that. It should be like an angry face, right? Or, I don't know, be brown. No one likes brown, brown is bad. Okay. This makes sense, this might be a good, see where we are in time. Okay. So, so I'll just finish up here and then we'll come back to this on Monday. So we can't predict the future, right? Normally, right? I mean, we can't predictably predict the future. Let's put it that way. You can't rely on that. Control flow is unpredictable, users are unpredictable. And instead we use, and this is something that operating systems do all the time. This is a major design principle we're gonna come back to repeatedly over the course of the semester. Instead of predicting the future, what operating systems typically do is take a small window of the past, what just happened, and make the best assumption they can make, which is that whatever just happened is going to continue to happen. Is that wrong a lot of the times? Of course. But, it's also right some of the time, okay? And it's better than just doing random and pretending that things are always changing, right? But this design principle, using the past to predict the future, is something that underlies the design of the multi-level feedback queue schedule, which we will talk about on Monday. So have a great weekend. Good luck with assignment two. Please contact the course staff if you don't have a partner.


It's been a hard year, but there's a lot to look forward to. I've never been as optimistic as I am today. What gives me hope is seeing my co-workers working so hard. Every day I get to make sure that vital environmental information is available to all people. I think what motivates me in the fight against climate change is I know we can do it. We have a real opportunity to create jobs to improve public health. We have an administration that's pledged to make climate change and equity issues some of their top priorities. We're focused on telling the stories of people who are making a difference in the fight against climate change. ESI informs decision makers, Democrats and Republicans and independents. We want to be the America that we always say we are. Everybody is treated equally here. We all have a role to play in the fight against climate change. We can all do our part. But we also need the people who work in this building to act. Thank you for your support to help us meet this challenge.


The Minnesota Department of Natural Resources celebrated the 10-year anniversary of an amendment that has provided immense support to the local state and regional parks. Our own Anthony Scott takes us to Itasca State Park for this week's Northwood's adventure. What's your legacy? That was the question being asked all throughout Itasca State Park this past weekend. The What's Your Legacy event is a celebration of the clean water, land and legacy amendment that was passed 10 years ago. The legacy amendment sets aside a portion of the sales tax to be used for parks and trails in Minnesota. Here at Itasca there's a new bike trail that has been developed with legacy dollars. The Bear Paw Lodge, a historic structure, has been redeveloped for public use. Legacy dollars aren't just used for building new parks, it's always really sexy to build a new facility but maintaining what we have is really important as well. Legacy dollars have been used in parks all across the region and the application process ensures the funds go to the areas in need. So it's a three-step process that's strenuous but we want to make sure that those parks and trails receiving the funds really are regionally significant. At the legacy celebration families learned about the wildlife in the area, were educated on tick prevention and there was even an ATV simulator. And if you worked up an appetite at the event, no worries because they were serving delicious sandwiches and pizzas cooked over a wooden fire. My favorite part was this ice cream. But it wasn't just about the great food. We're educating the public, we're providing information about the legacy amendment in general as well as some of the great projects that have been funded with legacy dollars. And we want to listen to people, how should this money be used and what can we do to make it even better than what it's been doing thus far. The legacy amendment might not be around forever. It has a 25-year life to it unless the citizens of Minnesota decide to re-up the amendment. Legacy will go away. And that's a reality the people of Minnesota just can't live with. This needs to continue. You can't ever just build something and say that you let it go. Reporting from Park Rapids, Anthony Scott, Lakeland News. Since the 2010, the legacy amendment has provided over $300 million in grants to parks and trails. If you enjoyed this segment of Lakeland News, please consider making a tax-deductible contribution to Lakeland PBS.


Yeah, so I will start with introducing myself. I'm an Avisu engineer working at Wanda. It's going to start up. So recently I built a game using SpriteKit and 3D Touch technology. So just going to share with you guys about that. And following up with my colleague Tim, he did some cool animations using CreeFrames. So yeah, we're going to talk about SKView, SpriteKitView, SpriteKitScene, then update methods, then SKAction, just the basics of SpriteKit. By the way, how many of you worked on SpriteKit actually? So only? Okay. So I guess I can ask Subha again. Okay. So basically SKView is the subclass of the UIView, which shows the content, whatever content inside the SpriteKit object for that particular view. And also update the frame with the current time. And it also manages the transition between the scenes. Then scene, you can think of scene as a movie scene, like where actor comes and go for that particular scene. And in terms of programming and in terms of gaming, it actually globally characterized for the physics simulation for the SK physics bodies. Then how SpriteKit actually update the frames. So you all know that Apple has this golden standard of updating frames at 60 frames per second, right? So the frame rate is actually 1 by 60, which is like 16.67 milliseconds. So SpriteKit update renders every frame with this update method. So whenever you update your scene, this method update with current time is called, and whatever you want to change in your view, you can do in this method. But let's say your game is paused for a moment or let's say you put the app in a background, then the SpriteKit current time is actually running, is still running, because it always takes the current time.  So in that case, what is SpriteKit does it, like noise SpriteKit, what we should do is take the frame rate, take the time back to the moment where we pause, which we can calculate by like taking the time difference between two frames, which is like 1 by 60, and we can check if the time since last update is greater than 1, then we can change our time since last update to 1 by 60, which is like frame rate and pass it to our last update time interval instance and then update the SpriteKit, update the scene. So we will see that in the code. Later I'm going to show you the code for that as well. Yeah, so basically we do this for like avoiding the frame rate drops and all. Let's say there's a spaceship in your view, there's a spaceship and let's say you touch on some point, you are building a game where you move the spaceship whenever you touch on the screen. So when you touch on the screen, your spaceship move from that point to the touch point. So in that case, you won't see the jumping of the spaceship if you do correct calculation in this update methods. So ASCII action is actually used for the deterministic calculations or actions. Let's say you want to move with constant velocity from point A to point B then you can generally use with ASCII action. It's pretty easy to use. For physics bodies, so every object in a SpriteKit view is defined as a node. So let's say your button is defined as a node in a SpriteKit and it has a texture property. You can set an image of that. So for graphically design, all the complex images is difficult actually. So people just use the rectangular square object and then put an image to it. So let's say your image is circular, but your button is square like 30 by 30. So in this case, let's say you have two buttons and you want to define the collision between them. But you can't define because the image is circular and the edges are like square or rectangular, whatever is your physics body is. So in this case, how you define the physics body around that object is by the frame of that button itself. Let's say the button is 30 by 30. So you go by 30 by 30. Otherwise, you can do calculation for complex graphics. Let's say it's a circular ball of radius 30 or something. So you can define your physics body same as radius of 30, but that's going to be a complex. So we have two kinds of physics body here, volume-based bodies and edge-based bodies. So edge-based bodies are basically, let's say you define a flow in your game or let's say tiles view. All these are considered as edge-based bodies. So edge-based bodies are like they never interact with another edge-based body. Even if you make a contact with them, they never collide or they don't follow the physics rules. But for volume-based bodies, they actually, if you set the is dynamic property to true for them, they do follow all the physics rules like gravity, friction, collisions and impulses as well. Let's talk about the geometry of a sprite kit. So you know that in our UI kit, the X and Y coordinates start from the top left corner of the device which is like 0 by 0 and then you do your calculation wherever you want to place the frame. But in the sprite key geometry, it follows the convention mathematical graph which is like from the bottom left corner. So whatever calculation you do, you do from that point of view. So let's jump into the code. I can show you guys the game inside. So let's start from the game view controller. So here basically we add our SK scene, a sprite kit view. So from the basic start, when you create a project, you just select the project. I can show you guys. Let's say you want to create a new project. So you select game, the next, and you can name it. It will create a game for you with SK scenes as well. So here basically we define, we always put our game view inside a view controller. So our SK view always lies inside the view controller. So you can define is the top view actually a class of SK view. Then you can present the scene by using its file name and you can set its properties. A few things to note here, you can define the scale for the scene to aspect field to cover the full screen. Also, you can choose to show the frame per second and shows the node count, how fast your frames are displaying per second and how many nodes in that particular frame are displaying in a view. This is how you represent actually a game scene, which is very simple. Let's take more into this. So this is our game scene. So this is your first matter, which is going to be called when you move from your UI view to SK view. So what actually I am doing in this matter is I am setting up all the nodes, which I have defined in my game scene. This is like a UI. You can program quickly code it and also define it here and give a reference in the SK scene class. So I am defining my nodes here and also defining the physics words for them. So the gravity and the content, I am also confirming this class with the protocol of SK physics contact because I want to implement the matter when two physics bodies come in contact. I am also using the emitter particle, which you can use a sprite particle file. So Apple gives you few choices of particles like magic rain, smoke. So the one I have used is smoke, which is in my emitter folder. So this is the one I am using. You can define the properties here. With what rate your particle should emit and what angle it should emit, you can simply define the properties here. It's pretty easy to use. Let's go back to game scene. So this is how I add emitter particle for my two. I can show you here. So if you see this, this is how I added the smoke particles to the players. So actually this game is based on 3D touch. So I made this game for a particular target audience of 6s and 7s. But to just make it work, I just use a slider for iPhone 5 or 6 users. Now let's get to these touch methods, which is practically provides the same low level touch methods as your UI kit does. So you can start with touch begin method, which will be called whenever you start touching the screen, the view. So the 3D touch part. So what do you guys think? How many lines of code to be used for 3D touch? Just a guess. That's true. So it's just one line of code, which is like maximum possible force of touch, which you can see is only available for the 3D touch or Apple pencil. So 3D touch is the feature of Apple iPhone 7 and 6s, when you force touch. So the maximum force touch. So as you can see in the documentation, it's only available for 3D touch devices. Or you have an Apple and a pencil. So how does this logic works here? Whenever a user applies the maximum force, you normalize the force. I can show you on the screen. When I press harder, the box got split. And when I press very gently, then it comes closer. So it's all because of the force, which I am applying on the screen. And by normalizing it, I just take the value from 0 to 1. So I can define the position of my player 1 and player 2. So in the game, if you see, you will feel that the particles are going up. But in reality, they are just there. And it's just the illusion of the obstacles coming down, making you think they are going up. So this is just the basic logic for 3D touch I have used here. Then these are the general touch methods, like different events, what I want to do when the user ended the touch from the screen. So the thing I was talking about, to update the time. So this method is really important, because let's say you are updating your frame. Because this method is called whenever your frame is updated, and next frame is get rendered. So here what I do is, I check every time, like my current time, and the last updated time for the frame is, if it's greater than 1, then I put the value for time since last update to 1 by 60. And it again starts from the very point where I left. So it doesn't get a frame drop here. That's pretty much about the game scene. And the elements, the one you see, how I use on the screens, is like how I add the player. So the player 1 is simply a node I use with the image, and I defined his physics body. So the isDynamic property for player 1 and player 2 is false. They are not affected by the physics in your scene, like the gravity, the friction. That's why they are always at the same positions, just moving horizontally, that's it. And the category bit mass. So the category bit mass is actually, for every physics body in a game scene, you can define up to maximum 32 categories. And so for this one, I defined as a player category. So both belong to the player category. And when I add an obstacle, so I defined them as an obstacle category. And collision, I didn't use the collision bit mass, but you guys can use the collision bit mass to check whether these particles collide with the same category of collision bit mass. For this one, I use the contact test bit mass. Whenever your particles come in contact with the obstacles, it will call the method, which we actually confirm the protocol to physics, physics delegate protocol, sorry. It will call the method did contact, and you can implement whenever these two things are, these two things come in contact. So this is the contact test bit mass I defined for players. Like they can come to contact with obstacles or gems. Gems are like the coins I collect in the game. So this is the method where I add my obstacles, the rectangular blocks coming down. They are dynamic because they confirms to the gravity physics in the scene. The jack position here defines like they will always be behind the scene. Let's say, I mean, your jack coordinate is always like perpendicular to your device. So defining in minus one will keep always them in the behind every other nodes. So these are just the random nodes I defined like a small, medium and large. So whenever I get a random number, I check the type according to the random number and I just display them on the view. So SK action, we talked about SK action for the constant velocity objects. So here I am using the SK action to move obstacles from top to bottom. So as you see, like the coordinate for sprite key start from bottom left corner, 0 by 0.  Like it will travel a distance in three seconds and the new obstacle will come. And sprite key is quite good about managing the memory. But still you need to remove the nodes which are not displaying on your SK view. So we need to append a method, remove from parent and run this for every obstacle object. Node actually. This is how I add the gem randomly. The gems are randomly placed between the obstacles. So if you see, so these gems are randomly placed around your obstacles or between the obstacles to collect. Similarly, I add the movements for gem which will be same as the obstacle movement. This method is simply to add a row. How? I want to add a row. My one row defines how many numbers of obstacles and what type of obstacle I can have. So I just simply check the row type and according to my random number I just add number of gems and number of obstacles in a row. That's pretty much about it. Yeah, I guess so. So yeah, this is how like a simple game you can build using a sprite kit which is quite easy to use. Okay, any questions? Yeah. What is your highest score? My highest score is 175. So actually I have put on my app store that earlier I put like whoever can cross 300 can win some amount of prize. But one of my friend he crossed actually so I remove that bounty and place it to whoever crossed 300 I will remove ads for them. Yeah. So that's about it. You can download the game from app store is already available called split up and up. Well, yeah, because I just want to build it like fast. So I just did this app in like three days. So I just use a storyboard. So you want to game use them? No, storyboard is actually for game view controller because you can present your game scene with game view controller, right? So I do some pause scene. Let's say, okay, I can show you on the app. So when I hold, so I show this pause screen on my game view controller. So, yeah, but this is by code. So yeah, that's why, yeah. Do you write text? Well, there's no text for game right? No, I mean there are, but I didn't write any. Okay. So any questions guys? Okay. When you create this game, right? Yeah. Do you read up on some game theory or something? Because there are some game theories that you introduce in your slide. Like update function, the collision. Oh, yeah. I mean definitely I went through some tutorials and I saw a few examples on GitHub. So I got basic idea from there. And yeah, because this app is quite simple to build.  Using that collision bitmarks. Yeah. Yeah. So this is the method actually did begin contact. So which is defined for two physics bodies coming in contact. So you can see if my contact body be whatever name you define in your game scene from your UI editor. Let's say, okay. This one I define here obstacle. The name is for this kind of object. I define name as obstacle. So yeah, I check if the body is obstacle, then just show game over screen. Yeah. And if it's game, then add at the score. Yeah, that's simple logic. Yeah. In any shape or does it be, is it only standard square or a typical shape? So yeah, what I said earlier about collision is like, let's say you have a complex shape images. So generally it's quite hard to define collision between them because the shape can be like anything in a 2D space. So what for our convenience we do is like for that, let's say that image is of like in a frame of 20 by 30. Sorry. So you can define your physics body 20 by 30. So you can check that any other objects comes in that frame, not just touch that image, but comes in that frame. And you will consider it as a contact or collision. So this is how generally physics bodies are defined. Yeah. Okay. I guess that's it. Okay. So you mentioned that for your game, whenever the object goes out of view, you throw it away. Yeah. So here in the game element, I added a movement to the obstacles and gem as well. Like movements of actions array. First is like move from point x to the white, which is like negative height, like from the top to bottom. And then I append an action, which is like remove from parent to this obstacle. So when I run this obstacle, the run action is actually a sequence of actions like first because in an array it always takes from object one to two. So my first action was to move it from zero to the bottom part and the second action was to remove from parent when it's like going out of the screen. So yeah, that's why I run this sequence of actions. Yeah. So this is just x, y, z, x. For this factory, actually, basics is basically for 2D, Apple has seen kit or metal framework for 3D gaming. So you can use that. Yeah. Thank you.