Good morning. Friday. End of synchronization week. OK, now that's a good idea. Let's have a round of applause for Friday. All right. Friday, we all get a couple of days off. So today, we're going to finish up synchronization week. And we're going to finish up synchronization week by talking about synchronization problems. So I'm using problems in two different ways in that sense at the same time, because I can do that. Problems in terms of problems with synchronization, what are the things that can happen? The bad things that can happen when you try to synchronize your code. So we're going to talk about deadlock, which I am guessing that everybody in this class will create a deadlock by the time they finish these assignments. If you don't, then you're not trying hard. And then priority inversion, which is a little bit more, what do I say, more of an exotic synchronization problem. But we'll talk about it today. And it's kind of a neat case where there's an interesting interplay between scheduling, which we'll talk about next week, and synchronization, which we're finishing today. Do I hear music? Robert, we're having class now. Can you turn off the tunes? And then we're going to talk, we're going to work through together a sample synchronization problem. So we're going to walk through one example of a case where I have a couple threads that need to be synchronized. And we're going to talk about, thank you. We're going to talk about, I wouldn't mind having a background track for this class, right? Should we just start leaving the music playing throughout the entire class? We need some very sort of drum and bass electronica or something like that, something that I can talk about. Maybe we'll experiment with that next week, maybe not. And then we're going to walk through this problem together. And decided to do one problem today. You will see more synchronization problems during recitations next week. Sonali's going to be covering several example synchronization problems in her recitations. And if you've seen Assignment 1, there are several synchronization problems we ask you to solve on Assignment 1 for real in real code. So synchronization is like anything else. Practice makes perfect. So the more examples you walk through, the more chances you have to see these kind of acted out, the more likely it is that when you actually have to do this on a real assignment when it matters, you guys will be ready. OK? All right. So a couple of announcements. Assignment 1 is out. Hopefully everybody saw the email yesterday. And my typos go on the slide. Please get started on Assignment 1. The technique that many of you guys employ down Assignment 0 of waiting until the very last minute to start I think will not work as well on Assignment 1 if it worked on Assignment 0. If it didn't work on Assignment 0, then you really have a reason to get started on Assignment 1. But even if it worked on Assignment 1 on Assignment 0, I would suggest that you start this earlier. Because this is the first time this semester where we're actually going to ask you guys to write some real kernel code. And we're going to test that code for you. We're still kind of working out exactly how we're going to do the testing. And I'll tell you more about that as kind of the assignment progresses. But for now, all the instructions that you need, all the requirements for the assignment are up on the website, and so you can get started with it. And at some point, it will update you about exactly how to test your system and what we're going to require for that. So again, as I announced, on Wednesday, the Tuesday recitation has been canceled. The Wednesday recitation has been moved to Talbert 106, which apparently, according to the email I received, is a room that has technology. I mean, at some level, all rooms have technology like, this is technology. This is older technology than we're used to talking about. But anyway, this room maybe has electronic technology, like something like a projector, for example. I moved my office hours partly, I shouldn't say partly, entirely because they conflicted with another meeting I had scheduled a long time ago. And also, that's it, I think. So we're done fiddling with this. I think this is how we're going to rock for the rest of the semester. And the website is your best source for all this information. And I'm working on getting the slides in the video up there. We're continuing to learn how to do that better and better as the semester goes on. Any questions about this? Has anybody started the assignment? Raise your hand. Were you able to get the sources that we updated? OK, awesome. Because somebody was having a problem with that, I wasn't sure if I fat-fingered it or botched it in some way. All right. So last time, we kind of did this whirlwind tour of synchronization primitives. We started out talking about the trade-offs between spinning to wait for a resource and sleeping to wait for a resource. And then we went through locks. We talked about condition variables. And we talked about semaphores. And several of those introductions were a bit brief. So if you guys have questions, this would be a good time to ask. Of course, we're going to do our review. Anybody have questions about stuff that we talked about on Wednesday? Yes, up front. Yep. Isn't there like a hybrid lock? Sure, sure, sure. Yeah, I mean, there's a number of different ways to implement locks. Some of the things that I've read when they talk about hybrid locks or hybrid mutexes, what they're actually referring to are mutexes that will spin on a multi-core system, but will sleep on a single-core system. Because remember, we talked about on a single-core system, spinning is just almost never, ever a good idea. Probably categorically never, but I'm sure there's some corner case that I'm forgetting about. But yeah, I mean, and if you wanted to implement that for your kernel, go ahead, actually. One of the things I want to make sure I impress on people is you guys start programming in OS 161 is this is your system, and you are free to build whatever extra functionality you want into this system. So there are actually some things that students in the past have found helpful to do. One of them that just came to my mind was that if you've seen that we've given you implementations of some kind of useful container data structures. So there's a queue implementation that's used a few places. There's an array implementation that you may want to use. I don't think so. Maybe David has changed this. But for a long time, those implementations were not thread safe, meaning that they were not safe under current accesses. And if you want to use those data structures with multiple threads, you might want to actually do the work to make them thread safe, to make them safe under synchronous, under interleaved access. And that might be something that helps you do later assignments, because you can imagine, I mean, one way of synchronizing access to a data structure is just to synchronize the methods that you use to access the data structure. And then people that use the data structure just get the synchronization for free. So that's just one example of something. But anyway, don't think that the assignments are where you have to stop. If you are solving a problem for assignment two and you think, hey, it would be really cool to have this different kind of lock, build a different kind of lock. I mean, that's kind of what's fun about this class. This is your code base. And the tests that we run, especially for assignment two and assignment three, are just tests that things are working. And how you guys get that to work is totally up to you. So there can be times when the right thing to do is to actually build a new primitive, or build a new data structure, implement a new data structure, or add some functionality to something that's already there. And that might not be in the assignment, but it might be the best way for you to complete the assignment. Any other questions about 74 loxivies? Yeah. Semaphores, yeah, yeah. So that's tricky, actually. So I have one example today of a use case for a semaphore that actually came up. And it's actually in your code tree now, because I used it in the driver code for your synchronization problem. So we'll talk a little bit about it. In general, as I said before, semaphores with their semantics just don't always tend to lend themselves in an obvious way to certain problems. Lox and condition variables are frequently a better choice. But remember, semaphores are counters. So in cases where you have a counted resource, semaphores might be a good fit. Semaphores can be implemented in a variety of ways. You can certainly, yeah, part of the internals of a semaphore is a count. That count is shared by multiple people who are accessed in the semaphore. One way of establishing a critical section that allows me to modify that count is to use a lock. Yeah, that's a certain ledger. All right, any other questions about primitive slacks, condition variables, semaphores? No other questions? Robert? Yeah, so why don't we come, can I answer that question later? So we're going to work through today an example that uses condition variables. But in that example, there is a critical section that we will talk about. Yet the other thing I would encourage you to do is, and you will need to do this for assignment one, go look at the implementation of semaphores that we've provided. So semaphores are properly implemented in the kernel tree that we gave you. And if you look at the semaphore implementation, you should be able to identify the critical section. And the way that you can identify it is how do you think you would identify the critical section in the implementation of semaphores that we've given you? Like I said, it's correctly implemented. So the critical section, it has a lock, acquire and a lock release that bracket. And you should look at that, and you should look at what's inside the critical section.  So you should look at that, and you should convince yourself, why is this stuff in the critical section, as opposed to some of the other things that might be outside. OK, other questions? So please today, I know I've been doing, I haven't given you this bad habit of jamming a little bit too much stuff into the lecture so that we have to go into turbo mode at the end. So I've tried to avoid that today. I probably failed again. But I don't think that I did a fantastic job of teaching the primitives on Wednesday. So if you're confused, it's my fault. But please stop me today, or slow down, and we'll come back to this stuff. You're also going to learn this by doing it. So I feel a little bit like, OK, I'm off the hook. Any other questions about this stuff? Before we do our usual review? So I'm going to work over here today. So spinning is almost never a good idea on a what? Single core system. I'm picking on people. You guys can't help. Single processor system. But let's say I'm on a multi-core system. So I need to establish a critical section. I'm trying to decide whether I should spin or I should sleep. How do I make that decision? You spin if the critical section is short, and you sleep if it's long. That's right. So if I know that the critical section is short, I might consider spinning. I still might sleep, but I might consider spinning. And if I know the critical section is long, then it's almost always a good idea to sleep. All right, let's keep going here. Why? Wow, there's it. It's only three letters, but such it. So what happens if I sleep? But how do I do that? What's the mechanism? Sleeping means that the thread that's running is going to what? Stop, and that means what? Well, what happens after that? The processor just sit there doing nothing? It goes a different thread. Right, so what do we call that? Context switch. And what did we say about context switches? It's expensive. Exactly. So if, and the other question that's not up here is, when I have a critical section like this and I have multiple threads that are trying to bang their way into it, what am I trying to do? What's the goal? I've got a bunch of threads that need to go through this little critical section. And to make the system more efficient, what would I like to do? So that's important for correctness. Only one thread can be in the critical section. But once that thread leaves, what do I want? As soon as possible. So I don't want the critical section. If I have a lot of threads that are trying to get into a critical section, you could think of the critical section as a shared resource.  And so if I have a small critical section, it might make sense to spin. Because spinning might actually improve the throughput through the critical section. If I don't, again, if the critical section is short, the context which overhead will waste cycles. If it's long, spinning is going to waste those cycles. How far is east from west? I mean, that's a design decision. It depends on how long the context which overhead is. It might depend. And critical sections don't always have a fixed length. I mean, critical sections might have loops in them. They might have arbitrary control flow. So sometimes it can. Now, I think one of the things about designing a good critical section is to try not to do that. Do as little as possible in the critical section and have the critical section be as predictable as possible. Because then you can choose a primitive that works. But in general, I mean, this is a trade-off that really depends on the sizes of other things. So I think I've successfully whizzled out of that question. But I think the answer is really that it just depends. Oh, there are questions about this. Yeah. Again, I mean, it really depends on the system. With your system, you can go and you can just, I mean, you can profile the system and you can essentially count the number of instructions. So it's kind of from, essentially, what are the boundaries? So what starts a context which? It's going to do two. What's that? No, but what initiates a context which? What are the two ways I can initiate a context which? Either a hardware interrupt, which might initiate a preemptive context which, or a thread might go to sleep and essentially ask to be stopped. So essentially, I can benchmark from when that happens, how many instructions are executed until the other thread begins to run. And that's going to include the overhead potentially for the scheduler, which we'll talk about next week. But it definitely includes the overhead to save all that state that I need to restart the thread the next time it begins running. I'm not going to call it constant. It might depend, particularly, on how much work the scheduler has to do or other things that are happening on the system. Something's about to collapse. OK, what is the interface to the lock? To a lock. What are the two functions? Let's get one function back there. Yeah. What can I do to a lock? What's that? A simple lock. Yeah, a lock. I mean, what can I do to it? What's the interface? Do you know what the interface is? So this is important to understand what an interface is. Let's go forward, Robert. What's one of the things I can do to a lock? I can acquire it. I can call a lock a choir. If the lock is available, I'll be granted it. If it's not, I'll be put to sleep, or maybe I'll spend depending on what kind of lock it is. But when lock a choir returns, I have the lock. That's the semantics of lock a choir. What's the other thing I can do with a lock? Release it, right? Pretty obvious, right? And that's not true, actually. Whoops, bug on this lie. Release the lock. Lock release will not sleep. Don't look. OK. What are locks for? What are locks for? What's the primary purpose of a lock? Yeah. Protecting critical sections. That's the most common use of a lock. To protect a critical section or to protect a piece of state. That's accessed in critical sections. OK. What's the interface to a condition variable? Anybody remember? Let's see. Wait signal broadcast. Wait signal broadcast. Oh, man, we got this. I was going to try to trip these out slowly, but it took all of them all at once. OK. So I can wait on a condition variable, which indicates that I'm waiting for the condition to change. I can signal, which means that the condition has changed, and I want to wake up threads that are waiting on it. And signal will wake up one thread, right? And then there's also a way to broadcast, to say to every thread that's sleeping on the condition variable, the condition variable is changed, right? OK. Now, what are condition variables for? I mean, we just talked about the interface. I mean, what does this sound like a good fit for? Yeah. So it allows me to convey more information than a lock, right? But again, I mean, condition variable, right? I mean, think about the name. What is the condition variable useful for? Right. If I'm waiting for a condition to change, right? If there's some condition that I want to essentially be able to wait for to change and to notify other people when it's changed, right? So when we come back to an example today, use condition variables, you'll see that there's a very clear condition that's embedded in the statement, right? And part of using condition variables is identifying what the condition is and identifying when the condition changes, right? Because when the condition changes is when you need to use one of these signal or broadcast mechanisms, OK? Yes, the signal changes to shared state. That's what I just said, kind of. OK. Now, I actually didn't tell you this last time. But if you look at the interface in OS 161 and in general, condition variables are always associated with a lock, why? Can anybody figure this out? So it's condition variables to signal changes to shared state. That's true, but why would I always have a lock associated with a condition variable? So normally, the semantics of condition variables are, in order to call CV signal, broadcast, or weight, I actually have to pass the lock and I have to hold the lock when I call those functions. Why? Yeah? Point of shift. OK, so it means I have to be the owner. But what is the lock protecting? Signal. So condition variables signal changes to shared state. How do I protect shared state? Lock. With the lock. So the lock is there to protect the shared state. It means that, because again, we'll see how to use CV weight, right? CV weight is normally used, check a condition. If the condition isn't the way I want it to be, weight. In order to protect the condition from changing, in between the time I check it and the time I call weight, I need to have a lock. That lock protects that condition from changing from some other thread changing it and me going to sleep. If that happened, I might never wake up. Because I might be waiting for a condition to change. The guy just changed it. I didn't get the signal. I didn't see the change to the state. I'm sleeping and now he's gone. So that would be a case where that would not be good. Lock protects the shared state that the condition variable allows me to signal changes too. Semaphore interface. Anybody remember? P and V. So Carl? Carl came to my office and we were having this discussion. He said, I always struggle using semaphores. Is that OK to say? Yeah. And I would say, and I have the same problem.  So it turns out, does anyone know why P and V are used? It was Dijkstra, right? And what was the problem with Dijkstra? It was Dutch, right? So he spoke Dutch. And it's funny because we looked this up. It turns out that so I was always taught that P is for proberan, which in Dutch means to test. And V was for something else that I forgot, right? Which means they know to release or whatever. Apparently, according to Wikipedia, it's even worse than that. That the word that Dijkstra said that P stood for, it's not even a real word. It's what's called a portmanteau. It's a combination of two words that he made up. So not only was he speaking Dutch, but he was making up new things in Dutch. But anyway, P and V, I always have to stop and think, what do those mean? And it's annoying. And we could just say, hey, Dijkstra, thanks for your legacy of incredible contributions to computer science.  We're going to call them up and down. And then we can all use them correctly. But I guess we did that. But you can do that if you want to. You can change your semaphores. You can change the semaphore interface. Just make sure you fix all the places where it's used. OK. So yes, P, decrement the semaphore. So semaphore is a shared counter that I guarantee atomic access to. And the semantics of the semaphore are, it cannot go below 0. So if I try to decrement it below 0, that decrement operation will have to wait until somebody else increments it. So another way of thinking about semaphore semantics is the semaphore is not allowed to go below 0. If I try to make it below 0, the system is going to stop me and say, nope, you cannot complete that operation until somebody calls V an increments. OK. So how are semaphores different from locks? So a binary semaphore. Let's say I have a semaphore that only is 0 and 1. And I don't only use the P and V. Yep. No sense of ownership. No sense of ownership. So a lock has an owner. And when you call lock release on a lock, one of the things that your lock release implementation should do is ensure that the thread that is trying to release the lock is the one that holds the lock. And that's just a semantic requirement. And it's designed to make locks easier to use. And the fact that semaphores don't have that semantic requirement can make them more difficult. All right. Any other questions about this stuff? Locks, CDs, semaphores. You guys are also going to implement reader-writer-locked, another synchronization primitive. And I will leave that to your reading of assignment one to figure out what those are. OK. So let's talk about some of the problems with locks. So up until now, we've really kind of thought about, or maybe I've been thinking about, I've been in this fantasy world where threads get one resource at a time. And in the real world, threads may need access to multiple resources. And locks may be used to protect those multiple resources. And so acquiring multiple resources may mean that I need to get multiple locks. And this is where we start to run into problems. So let me walk through an example. I've got two threads, thread one and thread two. Nope, actually, there was threads A and thread B. They both need simultaneous access to resources one and two. So let's imagine that the following happens. Thread A ones grabs the lock for resource one. Bam, context switch. Thread B runs, grabs the lock for resource two. Bam, context switch. Really, I have fun with that, but I'll stop now because I think it's starting to give me weird looks. Thread A runs, tries to acquire the lock for resource two. Now, what will happen? It's going to wait. Let's say it goes to sleep. Now, what happens? Thread B runs, tries to get the lock for resource one. What will happen to thread B? It will also go to sleep. What is thread A waiting for at this point? It's waiting for thread B to wake it up. If I didn't want to sleep, it said, hey, it's like if both of you got it. Imagine you're in a class that's at 9 AM and you have a midterm.    All right. OK. So this is a condition that we call deadlock. And deadlock occurs when a thread or set of threads are waiting for each other to finish and nobody ever does. And deadlock is always associated with what we just established here with a circular resource dependency. So thread A has resource one is waiting for thread B. Which has resource two, which is waiting for thread A, which has resource one. If you can't establish a cycle in your resource dependency graph, you cannot have deadlock. And that's one of the ways that we use to fix this problem. Now, people might think, well, deadlock sounds really like it's an interesting problem. But thank God, if I only have a single thread, I can't deadlock. A single thread can deadlock. And I actually think from my experience with this class that a lot of times the deadlocks that you guys experience in this class are single thread or self-deadlocks. How could this happen? How can a single thread deadlock? Ben? Yep? Oh, yeah. You got ahead of me. So in general, yes. Thread A requires resource one. And then thread A tries to re-acquire resource one. OK? So this is even worse. Now I have this little, tiny little loop here where thread A is waiting for who to wake it up. Thread A. So this is not good. Now, again, if I just state it this way, this seems totally an A. Like why would anybody do this?  It's like if you set a variable to null and then try to dereference it in the next line of your code.  Why would this happen? Ben actually already told you. Did anybody here already said? Right. So imagine that I have function foo, which needs access to resource one, which it's going to do by locking it. I have function bar, which also needs access to resource one. And while holding the lock to resource one, foo calls bar. And this happens on systems. And it happens especially when you have multiple people developing the system and you don't want to know what bar does. As the foo developer, you just want to call bar and expect bar to do what you want it to do. What you don't realize is that bar needs exclusive access to one of the resources you're holding and you calling it with a lock held means that you will solve deadlock. So this is not an uncommon thing to happen when you're writing complex systems. And it might not be this simple. It might be foo calls, you know, baz calls, cab calls, cat calls, bar. So the function chains can get arbitrarily long. Can we solve this problem? So can we get out of the situation? Remember, I mean, when you guys start to do, I alluded to this before. When you guys start to write code for OS 161, there are two ways to solve problems like this. One way to solve a problem like this is to fix the code that's causing the problem. Another way to, what's another way to solve a problem like this? Talk to the second function and the second function will verify that they're on it. So that's an interesting idea. If you look in our code, in general, the locks that we've given you, the lock do I hold or call. So there is a function called lock do I hold. Using that in your code generally means that you're trying to do something bad, like dumb. There's only a couple of cases where that function is actually used correctly, and you guys are going to write one of it. But what about this? So what's part of the problem here? Locks, the lock implementation that we're talking about here, will self-denlock. So if a thread tries to re-acquire the same lock, it'll wait. Can I fix this? No? Robert. Well, let's not talk about programming solutions. Let's talk about semantics solutions. You have a guess? So I'm going to accept that answer. And I'm going to go with it. So I am going to make the lock function return. I'm going to allow the lock function to proceed if I already have the lock. But what am I going to do? So that would be what would happen that would be bad. But what I can do is I can write a recursive lock implementation. And what a recursive lock implementation does is it says, I'm going to relax the semantics of locks. I can write a separate implementation. This is usually the right way to do this. Don't change the semantics of something that's already in use. Write a new lock that you can use in cases where the lock needs to be locked recursively at multiple levels of the function stack. So I can write a recursive lock implementation that says, if you already hold the lock, I'm just going to return. But what do I need to do to make the semantics of this sane? Essentially, what I want to be able to do is lock a lock that I already hold, and I don't know that I already hold it. And then later I want to be able to release it. So I'm going to end up with multiple calls to lock acquire. What do I want to make sure about lock release? So I think from this murmur over here, we have the right answer, which is I need to make sure calls to lock acquire and release are paired. And the way I do that is I can use a counter inside the lock itself. So when I lock the lock multiple times, I essentially keep a depth on the lock, and I keep incrementing the depth. When I call lock release, if the depth is non-zero, I just reduce the depth and return. So essentially, I can lock the lock at five different levels in the function stack. And then when the guy at the bottom calls release, the lock is actually not released. Because the guy, as I pop up the stack, everybody needs to call release again before the lock is actually released. So you can build this lock in mutation. It's not that complicated. And there are cases in your kernel where it actually might work well. But this is a way to solve, one way to solve the self-deadlock problem. All right, I already said that. OK, so let's talk about the conditions for deadlock. There are several conditions. One is that I need protected access to shared resources, which means that when I try to get a resource, I might wait. If I don't have thread sleeping, I can have this deadlock where multiple threads are sleeping waiting for each other. Second thing, in this system, resources are not preemptible. So we talked about the CPU being preemptible. What does that mean? Does anyone remember? When I preempt a thread who's running on the CPU, what do I do? Essentially, what I'm doing is I'm taking the CPU away from the thread, and I'm giving it to somebody else. In our world that we've established here, resources are not preemptible. Once a thread grabs a lock, I can't tear that lock away from the thread and give it to somebody else. So that's what creates this problem, because if I could do that safely somehow, I could get out of this by essentially recognizing that there's a deadlock and basically stopping one thread and saying, OK, these other threads could run, and then maybe I'll give it back to you later. So multiple independent requests is the fourth condition. That means that I'm allowed to hold one resource while I request another resource. If I can't do that, I can't deadlock. And finally, I need a cycle in my dependency graph. I need to have some loop where I can establish that thread A is rated for B, C, D, and it has to loop back around. The reason that I bring these up is that if I relax any one of these conditions, then I cannot deadlock. So I need all four of these to deadlock. And so let's go through an example. So this is like this classic synchronization problem. It's probably in the textbook, and it's discussed all of this. So this is the dining philosopher's problem. Imagine that I have these five people who were labeled on the web as modern philosophers. I have no idea who these guys are. And they don't look super modern, right? But anyway, I should know who some of those people are. Well, my liberal arts education has totally failed. And they're sitting down to eat, and each one of them needs two chopsticks to eat. The other thing I found when I was creating this graph, it is impossible to find a picture of just one chopstick. You look for chopsticks online, every picture has two chopsticks in it. So I made chopsticks using thick black lines. And so let's imagine what happens here. Let's say that my algorithm is I grab the chopstick on my left, and then I grab the chopstick on my right. And what can happen here? Well, this guy gets this chopstick, this guy gets that chopstick, that old dude gets that chopstick, this guy gets that chopstick, that guy gets that chopstick. Everyone has one chopstick, right? And no one at this point is going to make any forward progress, right? Because they're all holding one chopstick, and no one is going to surrender another chopstick so that anybody can eat, right? So this is this classic sort of sad problem of the hungry philosophers, right? So how do I solve this problem, right? So breaking deadlock conditions normally, I shouldn't say normally, always requires finding a way to invalidate one of the things that are necessary for a deadlock to occur, right? So in this case, let's think about it, right? So the first thing is, remember I had these resources that I was going to wait to acquire, okay? So the first condition is if I can't grab the second chopstick, drop the first chopstick. Now the locks that we've given you don't support this, right? Because there's no way to tell if the call is going to succeed, right? I just have to call a choir, and if the resource is held I'm going to sleep, right? So this requires some sort of different approach to figuring out how to allocate these resources, right? Another idea is don't make multiple independent requests, right? So in that case I was requesting one chopstick and then the other chopstick. So a solution to this is somehow figure out a way to get both of them at once, right? Maybe I lock the whole table and I grab two chopsticks and then I drop the lock on the whole table or whatever, right? So this would require some different approach to this problem than the one that we established. All of these do, right? Another way, so this is probably the one that would allow me to use the idea that I've already tried here, right? If I can establish an ordering that allows, that means that cycles cannot occur, then I can avoid deadlock. So let's say I number the chopsticks at the table zero through four, and the semantics are that I always grab the lower number chopstick first. That cannot produce a cycle. I'll let you think about why, but what does it also mean? So if you remember the philosophers all grabbed the chopsticks with their left hand first. Will this lead to the same approach? No, there will be one person at the table who because of the ordering, so if I have chopstick two and chopstick three, or let's say I have chopstick three and chopstick two, I grab the left one, right? Everyone at the table will grab with one of their hands except for one guy, right? Who will grab with the other. And it's that guy who allows this cycle not to deform, right? Because his first request will fail, and the other chopstick next to him, the other guy will be able to grab, right? So that will break this condition. And then the final solution is to just detect the deadlock and preempt one of the resources, right? So imagine that I see this condition and I just go in and I whack one of the philosophers over the head, right?  So that's another way to do this. And the mechanism for doing this is really not clear, right? So, and it's certainly not clear, give an end to the tools that we've given you, but this is one thing you could potentially do, okay? Let me talk about two other things in relation to deadlock. So there's another problematic condition that you can run into, and you guys may experience this when you work on your reader writer locks for assignment one, right? So there's another problem that also prevents forward progress, which is called starvation. And starvation is not deadlock, right? In a deadlock system, no one will ever make forward progress. In a starvation condition, the activity of some threads is preventing other threads from ever acquiring the resource, right? Meaning that, you know, if a thread continues to show up, this other thread will never enter the critical section, right? Will never get access to the shared resource. And I'll leave you guys to thinking about how this works with reader writer locks because you need to be careful because badly built invalidations of reader writer locks can starve writers, okay? So one last observation about deadlock. What is better, deadlock or race condition? Anybody wanna take a position? Deadlock, why? Because the program stops, right? I'll choose the deadlock, right? Because I can tell when my system is deadlocked. And in some cases, deadlock, deadlocks occur because I'm actually being too conservative about my synchronization. I'm doing too much work to protect resources, right? I need to relax that a little bit, right? Whereas race conditions usually happen because I'm not doing enough, right? So in this case, go with the deadlock, right? You will be able to tell if your system is deadlocked and frequently deadlocks, you know, I mean, one of the best things that happens with deadlock is the system just stops, right? So you might have a chance to break in with the debugger and try to figure out what the threads are waiting for. All right, so let me do this. I'm behind as usual, so I'm not gonna, let me not do priority inversion. What I am gonna do is talk about, let's go through an example together in the last 10 minutes. We'll do producer-consumer using condition variables, okay? And again, if I expect you guys to know priority inheritance, I'll record it and you guys can watch it online. Fair? Okay. So let's go through solving an example synchronization problem using one of the primitives that we've discussed, okay? So producer-consumer, right? This is kind of a classic thing that might happen in an operating system. I have some set of threads that are producers, right? And they're gonna put data into a buffer. And then I have another set of threads that are consumers. Those threads are going to withdraw data from the buffer and do something with it, okay? The producers and consumers share a buffer. This is part of the shared state, right? And the semantics are that if the buffer is full, I can't produce into it. So whatever producer is trying to access the buffer will have to wait. If the buffer is empty, I can't consume from it. So the consumer will have to wait, okay? Other things, so whenever you solve these problems when the best things to do is start by figuring out what are my requirements and then what are other things that I need to avoid, right? So for example, if there is room in the buffer, a producer should not be sleeping, right? A producer should not be waiting if there is room in the buffer. If I'm not careful, this can happen, right? And also the equivalent condition, consumers should not be sleeping if there are items in the buffer, right? They may sleep for a second and they should always be woken up if there are items in the buffer, right? They should not be sleeping for long periods of time while items sit there in the buffer. That's a problem. Now that might make your solution incorrect but it makes it not work the way I want, right? As soon as there's items in the buffer, I want them to consume and as soon as there's room in the buffer, I want there to be producers, yeah, yeah. So producers are putting items into the buffer. Consumers are withdrawing items from the buffer, right? Let me put up the code, maybe it'll make more sense, okay? So here's my skeleton code. This is our starting point, okay? So I've got two calls and assume that put and get our work properly, okay? So my producer is passed an item and puts that item into the buffer. My consumer pulls, tries to pull an item out of the buffer and returns it, okay? So what is the first thing I need to do here, right? What is the first piece of information about this system that I need to keep track of in order to establish the semantics that I want? What's that? Take my data, the buffer is full. So check whether the buffer is full. How do I tell if the buffer is full? Number of items in the buffer, right? So I need a count of how many items are in the buffer. All right, this count is gonna allow me to figure out whether the buffer is full, empty or in between. And depending on the state of the buffer, I'm gonna do different things, okay? Now that I've got the shared state, what do I need to do? Lock it. I need to lock it, but I also, right now I don't need to lock it, right? Because I'm not doing anything to it. So once I have the shared state, what's the first thing I need to do? When I produce, when I put something into the buffer, right? What do I need to do to the count? Increment, right? Yeah, I mean, until I start changing variables, I don't need, so I don't need to lock count right now. Because count is never accessed, right? So the first thing I need to do is I need to, oh, actually, sorry, okay. So let me add a variety of things to this, right? So I do need to update count, okay? This is a limitation of my slides right now. Things come in order on the slide, okay? And then the point is that, if I'm trying to produce into a full buffer, I need to, I can't do that, right? Something else has to happen, right? So if I'm trying to produce into a full buffer, I need to do something, okay? And then the equivalent for the consumer. If there's nothing in the buffer, I can't consume, I have to do something else, okay? And I need to update the count on the buffer, right? So this example, kind of, in certain conditions, this example might actually work, even if I just spin, right? But you had a great idea about something to do here, right? So what do I need to do to count now? No, no, I've got that, right? But what was your original suggestion? Right, I need to protect the count, okay? So I need to lock around the count, and then, but I already gave this away, right? But what synchronization primitive is a good fit for this? A semaphore, okay? That's, a semaphore would be one vote. Anyone else want to vote for something else? I need a lock for the count, for sure. Count is shared state. A condition variable. Why? Right, I have three conditions here, right? I have a buffer empty condition, in which case something has to happen or not happen. I have a buffer full condition in which case something has to happen or not happen. And I have the buffer in between condition, in which case something has to, multiple things can happen, okay? So I'm gonna solve this using condition variables, right? And that, and also remember, I have a variable too. I have a variable and it's conditions on that variable, right? So this is a classic example of this. I have a count, right? That's my variable, and I have conditions. This is one condition, this is the other condition, okay? All right, so let's talk about how to do this with the CV. So first, I need a CV, right? But what else do I need here? A CV is always associated with a lock, right? And as someone pointed out, I need the lock anyway, because I have shared state. I need to lock around count. So even if I wasn't using the CV for whatever reason, I would still need to protect count somehow, right? From this multiple axis. Okay, so now, so I definitely need to lock around my access to count, right? So I'm gonna add, well, actually let's see here, okay? So again, this is kinda gonna go faster than I want to, right? So let's look at what the producer is gonna do, okay? So I have, so as Robert, you asked before, right? Can I give an example of a critical section, right? Here it is an example of a critical section, right? I have a shared variable count that's accessed by multiple threads, either multiple threads running one produce or multiple threads running a mixture of producers and consumes, right? I'm testing the count here, and I'm changing the count here, okay? And in order to do that safely, I need to lock around this entire section, right? Okay, similarly down here, right? I'm testing the count here, and I'm changing the count here. So I'm gonna lock around that entire section as well, okay? Now I'm using the condition variable, and one of the conditions is, I'm testing right here. So for my producer, if the buffer is full, I'm gonna wait, okay? And on my consumer, if the buffer is empty, I'm going to wait, right? And the semantics of CV weight are that CV weight will drop, essentially CV weight, if the condition, you know, CV weight will drop the lock, right?  When CV weight returns, it returns with the lock held, okay? So when I check the condition again right here, I still have the lock, right? If CV weight didn't return with the lock held, I'd have to acquire it again. But because CV weight returns with the lock held, I can write this, right? So CV weight drops the lock, goes to sleep, when it's awakened, returns back to the thread with the lock held. So I can check the count again safely. All right, so we're done, right? This looks good. Is this correct? It looks good to me.  You know, I used the CV to go to sleep and yeah, this should just work, right? How will we wake up? Oh my gosh, this is not good, right? So yes, this is the problem here. If you call CV weight, you had better broadcast on that CV or signal on it somewhere, right? Because otherwise those poor threads that are waiting on this condition will never wake up, right? So CV weight and signal broadcasts are similar to lock and acquire and lock release in that they have to be paired, right? So if you start using condition variables, you need to think, where do I wait? Where do I signal, right? Or broadcast. Okay, so where? Now, where am I gonna put this? So I need to tell the threads that are sleeping to wake up. Where do I do this? More specifically, before I release the lock, but why right there? Because I change the count, right? Remember the count encapsulates the condition that these threads are waiting on, right? The condition does not change unless the count changes. And if the count changes, I need to tell people about it, okay? Where does the condition change? The condition change can potentially, potentially change here or here, right? That's when I'm adjusting the count. So let's put in some broadcast there. Okay, now I've got a CV broadcast. So I have to count and I broadcast and when I deck the count, I broadcast, okay? Does this work? Yes, this actually does work. And it says so on the slide. So good, reading comprehension. Does it work well? Okay, so that's a good question, right? But let me ask another question. When does the condition, what are the conditions that I'm checking for, right? This condition is checking something very specific, right? If the count is equal to a particular value. And this guy is also checking something very specific. If the count is equal to a very specific value, right? Now this will work. But what will happen is when I broadcast, let's say the count is going from, you know, well, in that case, I guess I wouldn't have people waiting. So this actually probably would work, right? But one of the things I might wanna do here is actually check if the count has changed in a way that changes the condition, right? So here what I've done is I've said, if the count is equal to one. So the buffer used to be empty, and now it's not empty. So the buffer has gone from empty to in between. And down here what I'm checking is did the buffer, was the buffer full, right? So in this case the buffer went from full to not full, right? If I don't do that, I can still do this and this will work fine, right? But what should happen is CB broadcast will get called and if the count up here went from one to two, there shouldn't be any threads waiting on the buffer being empty. So the broadcast is just not needed, right? And same thing down here, if the count goes from, you know, half to half minus one, there shouldn't be any threads sleeping, waiting to produce, right? So the CB broadcast is just a necessary, sorry, give her that. So we had a question here, why do I CB broadcast? Why can't I call CB signal? And, oh man, in the two minutes I have left, it's a good question, right? And the reason is that, so let's say I have a situation where I have multiple consumers, right? Now, so especially now that I've added this condition, right, I'm only gonna, so let's say I have three, sorry, let's say I have three producers that are waiting because the buffer is full. I have one thread that comes through here and sees that the buffer went from full to not full. If he calls signal, right, what might happen is only one of these guys will wake up, right? But there's three of them waiting and they all need to wake up, right? Cause it's possible that there's several other calls to consume that are gonna change the count but are not going to broadcast, right? Because I've added this condition here to avoid having to CB broadcast, right? So I don't think that would ever happen, right? I don't know, I think that would violate one of our assumptions. Now I think, I haven't thought about it carefully but I think in this example, you could replace CB broadcast with CB signal and that would work, I think. But I have to think about it harder. But in this case, CB broadcast is the right thing to do simply because again, I could have, you know, three producers coming in and a bunch of consumers waiting. Only one producer is gonna call broadcast. I need all my consumers to wake up. Okay, yeah, yep. But the point is that there might be another thread right behind me who's putting more stuff in, right? So it- So multiple producer, multiple consumer? Well yeah, that's the example we have here, right? We always have multiple threads that could be calling these in any order.  It's possible by the time the first consumer runs, there could be three items in the buffer. No, no, no, but my point is that it's possible that by the time they wake up, several other producers would have put more stuff into the buffer, right? I don't know how the threads are scheduled. It's possible that I call broadcast and these guys wake up and they may not run right away, right? They may just be added to the ready queue and before they get a chance to run, several other producers come through and put more things. Okay, I will leave this in the examples, Robert. So right, this example doesn't treat the buffer at all. You're just assuming that put and get work, okay? Let me, I'm not gonna do the sample for example, but you can look at this. There's an example in your code base in the drivers of a case where you can use the sample before to do something useful, okay? But let me quickly just summarize what we did today because this is important, this will help you on assignment one and when you think about synchronization problems, right? So when you approach these problems, right, what's the approach that we took? First of all, you have to figure out what do you expect to happen, right? What are the constraints? Remember, a race condition is always defined in terms of unexpected dependence on timing. So you have to figure out what do you expect, okay? That was the first thing that we did. Second thing, identify shared state in the problem, right? It can be a good idea to build an implementation that's not thread safe, either in pseudo code or real code and then look at it and say, okay, here are pieces of shared state that I need to synchronize and I need to protect. Third thing, choose a primitive, right? Choose a primitive, this is really important and if we had done this with semaphores, we could have got it to work. It would have not been as nice and I actually can, I can send out an example using semaphores so you can see that. Fourth thing, remember to pair waking and sleeping, right? If you call a choir, you have to call release. If you call weight, you have to call, you have a call to signal or broadcast, right? Cause weight will potentially sleep and a choir will potentially sleep, right? And if you don't drop, I mean one of the best ways to deadlock a system is to just not drop a lock. I'm like, whoops, I forgot to release it, right? That no one else will ever wake up, right? Look out for multiple resource allocations, right? This could be tricky because the system could potentially deadlock. A good way to do it is to establish semantics that say this is the order in which I lock these resources and every thread that locks them has to lock in that order. You don't have to lock all of them. You could lock a subset, but as long as you follow an order and you cannot deadlock, right? And finally, it's a really nice thing to just convince yourself, because it's signalization can be tough, right? You can have race conditions that only occur in one out of a million different thread interleavings, right? And you may not see those. And like I said before, Murphy's Law dictates that we will see them when we test your assignment, right? So, especially the corner cases. So in our example, what are the corner cases? When the buffer goes from empty to not empty. When the buffer goes from full to not full, right?  So go through those examples and convince yourself that your system is doing the right thing, right? All right, so next week we're gonna keep going with our CPU unit. Last bit of it, we're gonna talk about scheduling, right? So scheduling, we've been talking about all these mechanisms, scheduling is policy. And then if we are really lucky, we'll get to my favorite topic, which is virtual memory. And I will see you on Monday. Have a great.


This is cool of the Putnam Hotel in DeLand, Florida. Oh lightning guys. Thought I'd get some shots of it for you. It was built in 1923 and there was the original one burnt down and I think it said 1921, 1922. The original one burnt down and they built this in 1923 and replaced it. But it's very well boarded up. We got here, there was a police car sitting right over there. I don't know what this was for. But as you can see it's raining. They're talking about restoring this old place so hope they do something with it. My camera keeps zooming on it saying well it's actually my phone and just in case anything. I didn't want to get my camera on wet so it's kind of cool. I don't really see any way to get in. Getting outside, outside shot over for you. Pretty neat place. It's supposedly haunted. Now the story goes that a guy got an argument with his wife and he killed her and then shot himself. But somebody on the internet did some research on it and said the closest thing they found was in 1984 that apparently is documented that in 1984 a guy did throw his wife off the third floor fire escape which would have been around back where we just came from but it's really freaking cool. I'd love to get in there guys. There's one on YouTube where somebody was in it where they got but that I think was 2015 a couple years ago. But now I really can't see a way I can get in without. See there's a sign there. No trespassing right there. All Dilan police officers are authorized agents to order any person to leave these premises. Failure to leave after being so ordered may result in arrest. Damn phone's acting up it's wet. Anyway it could be subjective. I could get arrested for trespassing under a Florida statute. But since I'm not in there I'm real concerned. So I'll upload this for you as an outside. Sorry it's only external but maybe someday I'll come back and get in there. Like I said when we rolled up there was a police officer sitting right around back. So there you go guys there's an external shot. Hopefully there'll be a part two to this where I can get inside. But who knows. Beautiful place though. Awesome. All right guys talk to you later. Bye. Shea bear I'm gone.


Our mandate is to oversee, to manage, to coordinate the government's response to human trafficking. In the context of victims of trafficking, we collaborate and we work with various partners, governmental and non-governmental partners, and international partners, to render services and to refer victims of trafficking for services. They need to feel secure. They need to have that comfort knowing that I know where my next meal is coming from. I have somewhere to stay. I have a shelter. I have a home. I have somewhere that is safe, right? And in order so they feed into each other, the physical will feed then into the mental support and make them feel more at ease and help them to open up to the process.


Hey, what's up guys so if you're getting a warning in your Range Rover to say that the smart battery is low in your key Then this is how you will be able to change that. So first of all you grab your key You basically push the silver part out so you can get the manual key from inside There you go, you just take that out and then what you'll see is there's a little slot here You just put your key in there because you'll have to split this open so you've put that into the slot Like so and then you pull it Carefully like this and then you will see the battery now This takes ACR2032 battery as well You might need to get a very tiny screwdriver to pull this out So be careful because you don't want to damage any of the parts, but you can also use Your fingernails to just slide that out and Then I bought a whole pack of these so I'm going to be taking one of these out Okay, so I have the battery now. I'm just going to slot this carefully back underneath push it in Then you just literally slot this back on How it was before there we go and then you slot the key back in like that Then you take the cover and then you push that back in Tighten it and there you have it now the batteries are replaced


After the ruling of the Supreme Court, people have continued to frown at the body language of the APC. It appears the party wants to continue to have Governor Maya Mila Buni as the chairman of its ketika and Extraordinary Convention Planning Committee. The party is warned of the implications of violating the ruling. Jacinta Obuco has more. The internal wrangling in APC appears to be festering. The bone of contention is Governor May Mila Buni leading the ketika committee. Analysts call to mind the recent APC court ruling that played out in Ondo State. The case between Governor Rotimi Akeredulu and Mr Enyitai Yorjegede is too fresh. And that raises the question of legality and functions of the National Ketika Committee. However, reactions have been triggered. A guest on plus-TV breakfast show, Oshinowo Ibrahim, stresses Buni's position as the chairman is voluntary. The judgment under Enyitai Yorjegede has no effect on Governor Buni being in office. The article 17 states clearly that the party can organize or inaugurate an annual committee. An annual committee has no salary, annual committee has no benefit. It's just a voluntary job. Again, here is the side of BDP. We believe this should be a lesson to them, but unfortunately they have started misinterpreting or turning upside down what the Supreme Court said, believing that there will not be any problem. I pray that they maintain this position, continue with their congresses, conduct a lesson for their gubernatorial primaries, and the Supreme Court will come back to give them the correct interpretation of what it said. A senior advocate of Nigeria, Paul Ananambad recommends a way forward for the party. It's difficult to prove that Governor Buni is not in an executive position as acting chairman of the largest political party in Nigeria and in Africa. I would advise the party not to give political solution or political interpretation to the Supreme Court decision because it was not a political matter, it was a legal decision. Meanwhile, the APC governors have passed a vote of confidence on the committee. They believe the committee has discharged its duties effectively so far. Invariably, they are satisfied with the leadership of their colleague, Governor May Malaboni. Justin Taubyuku for PLOS TV Africa.


Hello everyone thank you for taking time and watching this video. I would like to talk to you about this upcoming city of Fort Worth project. My name is Shweta Rao and I am one of the project managers in transportation and public works departments capital delivery team and I will be the construction project manager for the upcoming Colonial Parkway sidewalk project. This presentation was originally meant to be given at an in-person community meeting with all affected residents and other citizens who would utilize this location. However due to city's proactive response to the current coronavirus outbreak the meeting has been cancelled and this presentation has been recorded in lieu of actual meeting. This presentation is meant to provide you with some information about scope of this project and what is happening in your neighborhood and also provide you on details of the project and the schedule for construction. The design engineering firm on this project is Dunaway Associates. The limits of this project are on Colonial Parkway from Country Club Drive to Rogers Road. Here is the agenda of what I hope to cover in my brief presentation. I'll be talking about the project as a whole reviewing the scope of the project, some of the design considerations and schedule for construction. The limits of this project include Colonial Parkway from Country Club Drive to Rogers Road and on Rogers Road from Colonial Parkway to Trinity River Bridge. The proposed sidewalk will be installed on north side of Colonial Parkway and continuing to the west side of Rogers Road. This project will improve walkability by providing safe path for pedestrians to walk along the Colonial Parkway. It will provide a safer connectivity to the Colonial Country Club. The project includes 2500 linear feet of sidewalk and we will be reconstructing the driveway for Colonial Country Club to meet the ADA standards. The project is funded by 2018 Bond sidewalk fund and is one of the five locations included under our year two list for sidewalks. The construction cost estimate for this project is around 330,000. This slide shows the proposed location for sidewalks along Colonial Country Club. As we can see that the available parkway at this location is very limited. The sidewalk is designed to be back of curb for most of the park but to achieve the ADA requirement of at least four feet there might be a need to trim shrubs a bit. To maintain the aesthetics of the area we are not recommending removal of any shrubs. They just need to be trimmed a bit to provide proper walkable surface to the pedestrians. As we can see in this picture the right of way is very limited and has old mature trees very close to each other. The proposed design does not anticipate any removal of trees. To save the tree roots and to ensure the health of these trees cast iron grates have been proposed. The grates will provide safety to the tree roots and reduce the impact of construction around it. This picture also shows the grade drop towards the golf course. The current grade at this location leads all the storm water to flow towards the golf course instead of the roadway. To allow the storm water to flow towards the roadway a retaining wall with pedestrian railing back of sidewalk is proposed at this location. The picture in the slide shows how the sidewalk with pedestrian railing will look like. The sidewalk will be built to ADA standards to make it accessible for everyone. There will generally be five feet wide with the narrowed sections around the trees. The cross syrup will be maintained to two percent. The Colonial Country Club entrance driveway will also be reconstructed to meet ADA requirements of five feet sidewalk and two percent cross slope. The proposed railing is a text dot standard rail and will provide safety to pedestrians along the retaining wall sections. This project also includes some pavement marking modification at intersection of Rogers Road and Colonial Parkway. While our team was out on site to inspect the location we found that cars are merging at a high speed while coming from Rogers Road to the Colonial Parkway. And the reason for this is the lack of proper pavement marking to align the traffic flow to merge properly. So to improve the safety of merging traffic from Rogers Road to Colonial Parkway pavement markings will be installed around the splitter islands. This will help the traffic to merge into proper lanes. Also the new pavement marking will reduce the speed at the intersection which will increase safety for pedestrians walking along the corridor. Coming to the project schedule we are currently at preliminary design phase which means we are at 60 percent design for this project. We are anticipating start of construction by late summer 2020. We do not anticipate any changes to the schedule at this point and the duration of the construction would be around four months. I would like to finish the presentation by presenting some frequently asked questions regarding this project and providing answers. So the first one is will there be any roadway closures during construction? We do not anticipate any roadway closures for construction but there will be parts of roadway blocked for storing the construction material and machinery but it will not be impacting the movement of traffic in the neighborhood. Why is a new traffic pattern or pavement markings being installed? The new traffic pattern or pavement marking will improve the flow and direct the traffic into correct lane for travel. This will also increase safety for pedestrians by slowing down the speeds of merging traffic. Do we have minimum sidewalk ADA width in this location where trees are located? The usual ADA requirement for sidewalk is a minimum of four feet walkable surface. The only location that we will have width less than that is when we are traversing around the trees. The width of that section will be around 3.5 feet to four feet. The width was reduced to keep the trees intact and avoid tree removals. Coming to the next question, are we impacting driveways in this project? If so, will there be any access to the property during driveway construction? There will be only one driveway reconstruction in this project and it is the entry to the golf course. We will be replacing one panel at a time to provide continuous access to the property at all times. In this location, will the water drain towards the golf course with the proposed sidewalk? The proposed design of sidewalk will allow the water to drain towards the roadway instead of the golf course. Retaining walls have been provided where there is a great great difference between the curb and back of sidewalk. The next question is, will the construction materials be left on road during construction? The contractor has to clean the work site every day before they leave. So the contractor might leave the materials and machinery on site but will clean the dirt before leaving. Thank you very much for taking time to listen and watch this video. It is unfortunate that I was not able to meet you all in person due to public health concerns and also discuss any comments or questions that you may have but I would still like to hear from you. My phone number and email address are provided here. Please feel free to contact me if you choose. Thank you all again.


What's the chance of you making a million dollars this year legally in the next 12 months? And I said what's the percentage chance and people say oh? 0% 1% chance 2% chance and then I say well What's the percentage chance of you making a million dollars this year legally in the next 12 months?  And it's very extreme, but I say what's the percentage chance of you doing it and everyone says 100% 100% 100% And it's just the gold didn't change the time frame didn't change the only thing that changed was their why behind the goal They're strong emotional attachment to it If somebody's entire family's life depends on it, they're not gonna wake up and go I'm not motivated today Right it doesn't matter because their why is so strong. They're gonna get up They're gonna get it done. They're gonna wake up early than they ever have they're gonna work harder they're gonna be more efficient more productive and so Motivations very fleeting what people are looking for is discipline and the way to get discipline is to have your Goal and then have an extremely strong why behind that goal


and welcome back to the Okta Workforce Identity Developer podcast. Today, I'm joined by the co-founders of the Wellness Startup, facets.one. Natalie has a background in front-end engineering and design, robotics, and engineering management, and Caro brings expertise from physics, data science, and clean energy. Today, we'd like to share the story of how they won first place in last year's Okta AI and Identity Hapathon. So welcome, Caro and Natalie. Thank you so much for having us. Yeah, I'm glad you're here. So to begin at the beginning, how did you meet? How did you end up working together? Natalie and I met, I think we've met each other for four years, but initially, we were both volunteering at Girls in Tech, an on-profit organization that seeks to help more women bring more technical side to the space. And then I was the commanding director then. Natalie was in charge of the technical events, so we had to work very close together for over, I would say, like close to three years. And then, yeah, I think eventually, I left. I changed to a different organization, but the relationship stayed there, and we will always discuss about the project. Natalie started because she was very passionate about facets, and eventually she's like, well, we already worked together for a while, so why don't you join the company and let's work together on this? That's basically how we ended up here. Carolina is very detail-oriented, and I feel like I'm a generalist, so I felt like we had good skill sets, and I knew we worked really well together, and I love having her as a friend. Yeah, I'd say the networking goals of those organizations definitely paid off now that you're winning hackathons together. So, Natalie, I understand that facets.one is kind of your brainchild. Could you tell me about the history of the app? So, originally, I broke out of a relationship during COVID and I realized finding someone to be with for your life partner is extremely hard, and I felt like there was no wellness aspect with dating, and that's kind of originally how we started. We thought we were going to be a dating app with wellness, but as with most startups, your first idea is not necessarily the one you end up going with, but as we continued through that line, we realized being a dating app would be too hard to do, especially since there are so many dating apps who already have volume, so we decided to focus more on the aspect we really cared about, which was the wellness aspect, and so that's how we ended up working together and then, hence, finding that hackathon to help build out pieces of our app. So, you were already a pretty well-flashed-out idea around how to do wellness with facets. Before you overcame to our hackathon, how did you end up finding and choosing the octahackathon? It took us some time to start the exploration in the face of the different features we wanted to integrate into the app, and then there was a moment when Natalie and I had a discussion of, okay, we should maybe join a hackathon and specifically choose them for those hackathons that align with the features that we want to push or prioritize, and then at that time, I think there was a lot of discussions internally about the login, and we saw the octahackathon, and I don't know if you want to share maybe about the challenges, because I feel like Natalie was a warrior of this part. Yeah, I think a lot of it is like, even with the original app that we did, I noticed we had hired some consultants to do one login. They didn't do the full validation for it, and so it had me diving deeper to understand login and also learn about OpenID Connect. Hence, the tutorials you guys provided were amazing, really helped to get the concept across, really helped me make sure I had all my box hacked for programming the login for the hackathon. I happened to be on the judging panel for the hackathon, and one thing I noticed across all the different entries is that there were the explicit criteria about need to use AI, need to use octah, and then there were these implicit criteria about guess what's going to fit well with octah's values and priorities, guess what's going to really stand out to the judging team. You showed this excellent understanding of what would stand out, so how do you think you made those connections? I think that was partially luck, and on the fact that we are building something that we're super passionate about, and I think is extremely relevant to our times, mental health and wellness is a huge problem these days. And then the other aspects I think were both very technical, we were both very entrepreneurial, so combining all this together, I think helped us build a good product for the hackathon. Yeah, and having those well-rounded backgrounds in both business and product seems to have really helped you out. Another thing I've noticed as we've talked about the history of the app in a bit more detail when we were preparing is that you seem to be very flexible in your choice of tech step. How do you choose the right tools for the job? Well, I would say we think first, okay, what is the main goal of the feature we want to introduce? We are also constantly joining AI conferences to understand what's the current state of the art out there, and then we're also sort of wary because every day there are new apps coming up. There are also a lot that will maybe disappear in a few months later, so we want to make sure that the tools that we choose are going to be there in the long term, because it's not only that we're learning how to implement them, but also it would be a lot of wasted time if it doesn't lead anywhere, or if it doesn't provide the tools that we need maybe to scale it in the future, or if they just disappeared. So for us, when we were choosing Octa and we were facing the challenge with the login, we knew that, okay, this is a safe bet, and that's how we decided to participate, to learn and expand in that area, but also it will not be wasted time. And as a bonus, we ended up winning, which we did. We're very grateful for that, the whole experience, so that was even better. Yeah, absolutely. And that's, I think, key, especially with AI and the tech landscape changing so rapidly, just making sure you're not building on a foundation that's about to vanish. How was facet.one handling identity before you enhanced it with this hackathon project? We had done, actually, I think just login and password first, and then we ended up switching to one-click logins, which we had a consultant build out, and after I checked the code, realized it wasn't fully implemented. And so, for this hackathon, when we were focusing, we looked at Octa and then learned about OpenID Connect, and then that opened up other avenues of potential thoughts we had on how our product could work with organizations. What are your thoughts about leveraging the features that you get by implementing OIDC and SCIM? What does that open up for you as the product grows? We've discussed different ways, so, or in the future, we see, okay, how can we monetize our product essentially helps the user to become self-aware in different areas, and we're implementing the ACT, which is acceptance and commitment therapy through focused activities. But then these will have a certain limitation of, like, okay, what can we not provide needs to come from an expert therapist. So, if we give therapists the access to, you know, manage the patient's role of our app so they can either provide specific activities or see what they're doing, so their sessions are more fruitful, I think that is one route for the SCIM aspect. Then, I think Natalie had other ideas that incorporated maybe offering a service, say, a university or, like, work benefits that they could say, hey, here is the account because you're already part of organization, and then they just extend that benefit to the final user. Having the control over what you're sharing with these protocols could be really key saying not only does this person get an account, but are they using it without necessarily having to share how they're using it? Totally. One thing that I noticed when assessing the submission is that facets.one seems to really play for the strengths of AI. For instance, if it guesses wrong when it's summarizing a journal entry and says, are you saying you basically feel like this? And then you say, no, that's not at all how I'm feeling. It's actually like that. That kind of is a success in itself. So, what thought process went into scoping how AI fits and making sure that mistakes made by AI wouldn't be potentially really problematic?  And so we definitely wanted to take an approach of more of a support, a coaching, giving direction and helping the person just understand themselves better. And so I think in the process of using AI to leverage that and just having them validate their emotions, we know through studies that that in itself helps a person feel better. We just felt like it would work really well. There is also a term of like, are you using AI to enhance or replace? And I think we're trying to enhance the user to maybe do these activities or micro journaling that will help them become aware instead of, oh, we're trying to replace the therapist, which is not the case. So for our specific application, we are just like making sure that by having AI to say, hey, you can move very far away from this activity that you're trying to accomplish. And the goals are very clear. And through coaching, like Natalie is saying, having this question that will always pull you back to like, hey, focus and center on this. That is what we're trying to do here. Sounds like you're casting AI as more of an assistant than as a leader necessarily, or it's doing more coaching than therapy or instruction or even mentoring through this process. And with Facet.1, it's really the whole life cycle of starting out building an app through winning a hackathon, through what comes next. What have you learned about building apps? What advice would you give to people who are just starting out with their idea? Go with whatever is the simplest. We have asked product people and they were all like, go iOS. And that process takes way too long. There's so many restrictions with Apple. And at the beginning, you're just trying to test your idea. And so getting to that as quickly as possible is my recommendation. Don't do anything fancy and really stick with simple development first.  But also, you know, reality and like when you're doing investigation or serving people, et cetera, it's a continuous learning approach. So we've also pivoted multiple times because we have to integrate the learning and also keep our features minimal, because otherwise, it will be an endless journey. What do you think about deciding when it's time to pivot and which features it's most important to keep with you versus which ones it's time to let go of? I think that's always a hard, but I think with some of it is just like feedback by constantly talking to others, getting feedback, seeing if you're getting any traction on it. Doing the combination of that, I think a lot of it is also being realistic about the big picture and all the information you're getting, kind of trying to see where does this fit in that puzzle. We also, as startup entrepreneurs, you're wearing multiple hats. And one of them is, hey, we want to apply to accelerators or different programs like pre-seed, VC funding, et cetera, et cetera. So while you're doing all these applications, you're learning, okay, what are they looking for? And then a lot of times they give you feedback, other times not. Sometimes we're in a pitch competition and then we get people that come close to us and say, hey, I found this part very interesting. And that part might not be our main feature, right? So you need to be able to be open and say, oh, what are people reacting to? And then continue and focus on that. Because if one person say it's like, okay, it's always, every time you talk to someone, you might get a different answer. But if you're starting getting it twice or three times or more, then it's, okay, there's a clear signal here that maybe it's worth pursuing. One really exciting thing as a hackathon judge is looking at how far does this hackathon project have before it could potentially go to market. And you'll see somewhere it's like, oh, a core concept of this would need to change to get it secure. Or a core concept of this would need to change to get it safe with AI. We didn't see those glaring major changes because of how you implemented AI and identity in facets.one. But what do you think is standing between you and being ready to release so far with it? You know, as an MVP or just getting our product out to be able to test, I do think it is quite, you know, ready in the sense that if we make sure everything's secure, logging is working properly, we can probably put it out there for testing already. Fortune right now, nothing's hooked up to any database. So you will have to download your content. So I think that could be something we hook up next. So then there's longevity in the things you built within our hackathon. But the value that our features bring, like just by doing the activities are already there. So I also think that recognizing what is the stage we're at. So if we're saying, hey, this is our beta product, we're testing this specific feature, extend that knowledge to our beta testers. And then we're still learning. We're still in the product fit process. And then once we say, hey, from all this work we've done, this is the strongest signal, and we can put it out in a, you know, like, or for method conception, I think then we have to be 100% sure to to say, hey, it's going to be really safe in terms of the identity, in terms of encryption and all other data. But I think it's going through steps. And we are very serious about making sure it's safe, right? Yeah, absolutely. Anytime you're working with personal health information or even just private things, like once you're in it, it becomes so important. Can you share some examples of ways that you've made it safer already as you've been working with it? I know you've added identity and robust login through the hackathon. So that's a key one. But are there others? Our backend has, at least we had built out prior to this hackathon, had off guards and whatnot or encryption. So if you were dealing with passwords, it would actually in the hackathon, we did that, it would encrypt it and decrypt it to validate your passwords. So those were some, some safeguards we put in. And then also, I think just in general, we at least didn't, from what I remember when we were building, we tried to keep the identity and information separate from our data, like we have different tables and whatnot. There are other things we discuss incorporating. So right now, in terms of journaling, specifically, not only say like a lot of apps that do journaling, they can provide like a backup, for example, but then it's not usable. So by looking at other apps, for example, that say, hey, actually, we don't keep your data, either you use it on your own Google Drive, or you just, you just have the program in your own computer, and you can download your data and it's just there for you as locally. So those are like the two roads that we've been also discussing lately to make sure that maybe a part of the process is given to, for example, a larger company, or it's just like it just slips into your machine and no one will have access to it. I really personally appreciate the approach of letting people choose where it goes, or you kind of get this with using OIDC to do social login from a provider where someone already has all their identity to make the individual security posture no worse for having used their app than it would be if they didn't. Like if I would be keeping a journal in, let's say, Google Drive, or an app that backs up to Google Drive, it may not be perfect, but it's no worse. Exactly. And also, it gives us time to focus on how can we make your experience in journaling better? And then when it's time, we can focus on, okay, do we want to now take this new package into our whole like the software creation? Yeah, for sure. And that's a theme that shows up over and over. What is worth building ourselves? What can we really add value by building ourselves versus what is it better to have someone else an expert, a specialist handle? You also mentioned something interesting about MVPs. So how big do you think an MVP really needs to be? It probably needs to be a lot smaller than you think. That was definitely a learning for us. Even in trying to make things small, I think we realized we can always go smaller. Just to compliment Natalie is when you think of your MVP, you should like cut it off to the point where like what is the actual actual MVP like it's probably going to be like a quarter of what you initially thought was your MVP. Because I think like as humans, we have all these connections and patterns of how everything is working together. But sometimes what you need to test is just like this small part. I don't know, at least for me, my perception of what I thought the MVP was to now that we have this actual MVP like, okay, this is the first feature out that we want to test. It really changed a lot of your time. So if it's taking too long, and if we were saying like, oh, doing the hackathons, we've learned that sometimes doing it as a mock-up, maybe on a web development instead of for an app like Apple, etc. It just like changes drastically the time that you can get and see and test. So I would say if it's taking too long from what you initially thought it would take, then you're not doing the MVP. And you need to like step back maybe and think about, okay, what do I need to do to see this prototype running in two weeks from now, for example. That sounds almost like a mindset shift from an integration testing kind of mindset to a unit testing kind of mindset, but with product features instead of just with pieces of code. Yeah. And so after all this, what's next for facets? I mean, we would like to release the features that we've developed and start beta testing them. Cool. And what's the pitch for who might want to beta test? Who is the ideal user at this point? At the moment, we are still targeting singles in the dating space. But our wellness features can help with anyone. So if you're trying to gain more self-awareness, be happier. You can sign up for our beta. Amazing. And where can we go do that? Facets.one. Yeah. So if you'd like to hear more about the other winners, the other apps that placed in the hackathon, you can check out the blog post linked in the description below. And you can visit facets.one to join the waitlist. And as always, we would love to hear about you and hear about your thoughts in the comments below. So thank you for listening.


Hi, good morning and welcome to today's products and focus. So what a lot of traders looking at this morning is the moves in Japanese Nikai, which has certainly come off quite aggressively. It's now hitting almost new lows for the year. Double yen has begun to sell off as well as people are buying the yen in terms of uncertainty and people are thinking that the Japanese market is getting impacted by the stronger yen, which incidentally is maybe the same problem as impacting the daxity is the fact that the euro was actually just getting a little bit too strong and sterling euro for example is a 0.8 and that's up from 0.7 only about six months ago. So a decent move there and some people now are thinking that that stronger euro is beginning to hurt the eurozone economies. There are some analysts out there who are actually comparing the lost decades in Japan with zero growth as to something that could happen in the eurozone if they don't manage the dax rates in a more effective way. So there's not actually a huge amount of other things happening apart from it's all about FX at the moment. It's what the Japanese yen is doing next and it's about the strength in the euro and at this moment we're going to go ahead and have a look at things from a technical perspective where most global equity markets are just slightly grinding that a little bit lower this morning. So let's go ahead and have a look at things from a technical perspective. So as you can see there this is the US 30 and we had a negative day yesterday almost a slight version golfing pattern and moved to the downside this morning quite far away from the moving averages. We have got a ridiculously over extended upwards move right here and it's not surprising we're getting a little bit of a sell-off though it feels kind of transitory in nature. I can't really think there's going to be a dramatic sell-off right here but CMC clients are 74% sure and the other technicals are just beginning to turn down now so these other technicals are just getting negative now. So you would have the tip here as the next potential support and then you'd be looking at the tips of these candles here as the next potential support. Moving on to the UK 100 briefly we're still in the middle of this range 60-70 potential support 22-20 sorry 62-20 being potential resistance from the wrong side of that moving average and that is about an ugly looking candle to have had yesterday. 57% of CMC clients are currently short. So let's have a look at that Japan 225 and it's not actually the lowest for the year my apologies but you can see that it is going to fall off a cliff there ever so slightly you are looking at the next potential support being closer to 14671 94% of CMC clients are currently long anticipating and move back to the upside if there is a jump to the upside you could be looking at 16384 as potential resistance but as you can see it's quite aggressive and it's moving on to dollar yen. Dollar yen is just beginning to move that little bit lower at the moment actually it's at the law of the day with what 110 spot 08 being the next potential support then after that you're looking at 105 and that would be fairly that'd be quite a punchy move for dollar yen should that actually end up happening. 78% of CMC clients are currently long anticipating there might be a bounce but this is a very ugly looking chart if I'm completely honest so moving on to West Texas Crude it's continuing to come off even in the face of that week in US dollar smashing back below 35 dollars next potential support would be 31 spot 82 but you could be looking at 55 pure SMA as adding that extra level of support. 51% of CMC Marcus clients are currently short moving on to gold gold might be bouncing off this potential neckline of the head and shoulders formation we've got right here. As discussed gold is a little bit of a tough one to trade right now we're in the middle of two moving averages so you've got the 21 period right here and the 55 period right here decent move yesterday but it's kind of hard to kind of gauge the directional moves when you are looking at a less likely chance of a rate hike in the US you would have expected to have more upwards momentum on gold but this has not happened but nevertheless 87% of CMC Marcus clients are currently long obviously anticipating a move to the upside this does look a lot like a potential head and shoulders formation so any break of this potential trend line right here could open up 1191 and then 1131 should that materialize. Moving on to euro dollar we've just come in the holding pattern right now your dollar trying to decide its next potential move obviously Mario Draghi is thinking right now what he can do to take some of that strength out of the euro but he's limited in his options you don't want to have the euro too strong because that will stuff stifle growth in the euro zone but nevertheless the markets are waiting to see what happens so not much to report 84% of CMC Marcus clients are currently short one spot 1489 remains to be the potential resistance level moving on to GBP's USD it's really not doing huge amount the sterling is it's been in a free fall for some time I probably say it looks like it's going to continue to oscillate around this one spot 4228 at the moment until the MAC would date a picture for sterling changes obviously is massive layoffs in the steel industry the UK economy is like kind of chugging along but it's not really you're setting the world on fire 60% of CMC Marcus clients are currently short anticipating further downs downwards momentum so let's have a look at things on the market calendar front what is still to come well you can see with the housing index in the UK PMI in the eurozone trade balance and PMI for the US then it's cruel Wednesday so make sure you don't forget about the petroleum inventory stocks we've got industrial output as well and in Thursday unemployment claims and then Friday you've got current account industrial production there's not a huge amount of amazing macroeconomic data so it does look like the market is going to be heavily driven by the technical factors right now and people are looking at dollar yen and euro dollar well that's it for me very good look at the trading guys and join me again tomorrow to find out what happened next thank you very much and goodbye