All right, so our trader is welcome on back to close things out officially now for this week, for this Friday, April 22nd. Shortly after 2.30 PM Eastern time, great to see Norman, Leda, Bobby, and well, perhaps the rest of us, perhaps just waking on up here, heading into this afternoon meeting. Great to see Michael as well, loud and clear from Leda and Michael. I assume I got everybody else though, just as well. So great to see Nina, Will, Gene, Kathleen, Ron, all rejoining us as well right now.   You know, a couple of little opportunities here and there. I am in a couple of positions. You know, it's pretty interesting because I ended up wrapping up a couple of different coaching calls today and really the theme behind those two, in fact, were, you know, don't force trades, you know, obviously we say it on Mondays and Fridays here in the Cyber Group Room for students like Bobby and James. But, you know, it's to say, like, you know, you're not really supposed to be seeing as much of an active market heading into a Monday or Friday, not as much news that's out company-wise, you know, at least on those days and well, to be transparent behind it here on the East Coast, here specifically in New York. It's freaking gorgeous out again, right? So we're finally over the weather hump and a lot of us just really want to start off the weekend early. That's not just me saying that personally. That's just really the general theme over, you know, these warmer weather months or warmer weather days. So, you know, here in late April, a lot of people want to start their weekend early. They want to go out on their boats, you know, perhaps like Fausto.  You know, of course, there could be opportunities with the down market. You could follow a couple of good short trades or if there are a couple of interesting stocks that, you know, go against the grain, you know, maybe from, you know, pre-market this morning, one of our picks, you know, that could be possible. But listen, if you made your money early by 1030, 10 o'clock, a little bit later, whenever it was, you know, I would have taken my bull on my home, right? So with that, LGVN on the screen, right before we started this meeting, I just rescanned the market quickly. I just saw it. And the one thing behind this, it's just got really thin volume on the book, a lot thinner actually compared to what I've seen it normally do. Not just talking about the move, the order book that is, the liquidity. So, you know, we've seen the stock have, you know, bigger orders on the bid and the ask, collectively, that means more interest across the board. So without that, I'm not really too big of a fan of this.  But for right now, though, I just want to see if there's anything else just really even looking better. So, you know, what we'll do is, as always, go right from top to bottom. Got no water here, no energy drink, nothing on me here. That's pretty odd. All right, we'll try and be efficient with our time. So with that, let's go right from the top here, the VLON trade. You know, I always like to mention the trades that I'm in, if I am in any at this time. You know, I stepped away from my desk for like an hour or so. You know, Rich was commenting in the room. Ha, Ron. Love it, Ron. Ron says, I have no life. I'm sticking around. Hey, you got the time, by all means, right? We're here. We're open for business. The stock market, that is. So, you know, I'm sure there could be a good opportunity. And VLON, I am in right now. I ended up catching the bounce off of two. I scaled out three quarters of my position already, as it was testing a really significant resistance here off 220. 220, it was a big buying level from pre-market. So, that ended up leading the stock to make a nice pop shortly prior to the market opening up. And then, of course, afterwards, well, it ended up leading, it's like, you know, a couple of bounce opportunities, but nothing really too special. And then, just even here heading into the early afternoon, I was away here at this time. And I come back and I end up taking a two-cent loss. This thing ended up stopping me out initially here before it took off. So, hey, at that point, look what's happening right now. It's shaking down. Thank God, it took three quarters of my position out off 220. Being a responsible trader there. I have my stop set, actually, though, right at my entry price, right at 201. If this thing drops down a little bit more, then I'm going to get stopped out. That's fine by me. Like I'd said, though, you know, I didn't really have the greatest morning. Actually, I didn't say that up until now. I didn't have the greatest morning. I was actually down up until the early afternoon. So, you know, taking out three quarters of this position puts me, you know, at that cushion point a little bit. Not exactly where I want to be, but I'm a lot happier now than I was by the end of the early morning trading session. The VLON stock ended up making that big pop at first, but came crashing down. Well, here it ended up making a nice bounce, still in on my last leg of my position technically as of right now. It didn't stop me out yet. But, you know, hey, for right now for this afternoon, normally this type of stock trading 150 million shares when it normally trades like really next to nothing day-to-day basis. Normally it would be pretty exhausted at this point. So, you know, I don't know. I'll put this on our watch list right now, a little reluctant. You know, hey, just because I'm in a position doesn't mean I'm going to put it on the list. This was looking good just up until now. So, you know, this last shake here leads me to think it's only going to actually drop off more. So, you know, I hope that doesn't happen. I have it on our list for right now. Perhaps it'll be taken off our list if it ends up tanking lower. Let's see what else we got though. Otherwise, the BKEP, which I haven't really seen up until right now. Oh, you know what? Actually, I have this. I forgot. Yeah, that's right. It's a buyout. So, you know, these don't move. I took one look at it. Super early pre-market and walked away. The second trade that I am in right now, I told you I was in two. The second one, MITQ. I ended up missing the bounce from where I really wanted to get in. So, on this trade, I told you I stepped away around like 12 o'clock time or so, 12.30 and I wasn't really following the market at that point. So, I ended up missing this because I had my level prepped up and set up here. Even from the market open, I was saying on this MITQ, watch out because I think there's a good chance it's going to find support. You could see the two lines I have on my screen here. I ended up plotting this when I was on a call with one of our students in a coaching session and just to show them and well, here just to show everyone now, you know that 135-138 range, I had plotted on my main screen as a key bounce level and ended up making that exact move. I'm not in it from there. I ended up catching the bounce thankfully off the 150 level. I had my stop set super tight on this too just in case, you know, for a stock like this that's so exhausted normally or rather again catch myself. You know, for a stock that's so heavily traded when it's normally not trading, you know, 83 million shares day to day, it's more exhausted than anything. So I took this tradeoff 150 still in. You know, I had my stop set right at 150. So fortunately, I could say it didn't stop me out, didn't touch 150. And to me that's actually a pretty bullish sign. So how about this? For all this inside the live trading room, more so my students inside the phase one stock course that we finished up today, this past week, quick little pop quiz. How about this? For like Ron and Bobby and Kathleen, Gene, all their longtime students and our newer students like Nina and James, etc. But when an order on the bid, an iceberg order on the bid support gets broken through, what color comes up on the tape on the time in sales window? Hopefully it doesn't drop down here while we're doing this. Ron asks, is this a riddle? No, I'm not that creative. Leda has that at three o'clock. If you have a saying green, uh-oh, uh-oh, you got to go back in class folks. Uh-oh, and I think a couple of us may have tailed Nina's answer at first. But red, red on the tape, when an order on the bid gets filled, and it's okay Nina, I'm teasing that, but when an order on the bid gets filled, you see red on the tape, order on the bid. So when support gets broken through, you see a ton of red, right? Well, the fact that we didn't even see 150 get touched right there, well that means that as of right now, there's no major selling interest at 150. Again, that's subject to change. That's subject to change, but you know, hey, that to me is a pretty bullish sign as of now, especially off the slingshot that it had where it broke under 150. We saw the red come in on the tape, and then from there push the buck. Folks, for all of us that, uh, I may have answered green there, perhaps, but just to say go back, phase one stock course, we just did that this past week. If you didn't watch it live, the recording is up on the student dashboard, but you know, of course, we just did that here for the month of April. We did that back in the month of December. We did that back in the month of August in 2021 prior. So I guess that was a riddle, Ron. I guess that was my riddle, nonetheless. But, uh, you know, like I said, I'm not back creative. Lata has our weekly Friday riddle in our live trading lined up, you know, probably 330. All right. Well, hey, I like this for right now. I like this more than the V-lon. Hopefully this doesn't shake down like the V-lon, and uh, we'll put this on our list for right now. All right. No more pop quizzes. All right. Uh, FRGE, talk about disaster. I mean, pop and drop. I mean, you could have done really well if you caught this at the right time, but, you know, ended up running up, ended up dropping off basically as fast as it ran up. So pass on that. You know what? I actually, I wanted to jump to UVXY here because, oh, my trader's dyslexia. Geez. How about that on top? I skipped over the SkyH trade, and it means to. Let me click on this first. SkyH, uh, you know, hey, it's pulling back down now. It's actually tanking off the high there. I made a clear false breakout over, uh, what seems to be resistance off 820. Yeah, 820. Nasty drop. So at this point, more reluctant following this trade, SkyH. What's funny though on top was I clicked on this UVX, UVIX, thinking it was UVXY. Let me jump to UVXY here. Obviously, markets once again down today. I'm not going to make any predictions like I did 24 hours ago. I thought we would see a small dead cat bounce, if not a little exhaustion heading into the close yesterday and, well, I was wrong. Ended up seeing just continuous drop off as simple as that. So it certainly seems like we're going to, you know, see more of that heading into this close. But the thing is, is that, you know, with that in mind, you know, it's the end of the week. So at the weekly close, you may end up actually seeing that short covering at this point. So I'm not going to hold my breath waiting for that. Norman asks inside the live trading room, does it mean Bitcoin is dropping as well? Yeah, Bitcoin's been dropping back down and I wasn't really showing much Bitcoin the last week because to be transparent I didn't jump back in. So at first I was a little like, oh shoot, did I just miss the next bounce here? But I was pretty reluctant even jumping in. So I didn't want to even show it as much as it ran back up. I'm happy I stayed out, came right back down. So we've been talking forever about like 40,000, 40,500 namely as that main range that we need to see Bitcoin hold over. Well, it's back under it now. It's back under it by like a thousand points. So I'm even more pessimistic about the drop off now than ever. So it's not looking too good with this pullback in the market. I think long-term or not long-term, long-term are going to be great, but it's a matter of when, right? When are we going to get that ultimate bounce? Well, if it's going to stay under that 40,000, 40,500 Norman, I'll do a more extensive video on Bitcoin very shortly from now. If not over the weekend, then early next week post on our YouTube channel there for all of a sudden on our social media channel right now joining this live stream. But nonetheless though, not looking too good. All right, what's looking better right now is the VLON trade. VLON is actually pushing back up. VLON pushing back up to 218, 220. Let me jump to that really briefly. Kind of fell off on a tangent there. I wanted to jump to UVXY though and really just say with the market dropping off UVXY in particular, I'll put that on the watch list. It's more of an ETF, of course. So if you don't really trade ETFs with success or really at all, I wouldn't suggest following it. But for anyone like Johannes or namely anyone else in our live trading room that does follow the ETFs or UVXY in particular, then definitely I would follow it for you.  So this actually looks a hell of a lot better now than where we left off with it, thankfully. All right, the HCI trade, I didn't trade this one, ended up making a nice push from the market open, broke out from that 250 level, ran up pretty nicely, had dropped back down and really at that point, you know, it's kind of do or die. It's going to either hold that resistance as support or it's going to flounder under it and then just really just continue to pull back. So thankfully it led to the run after. I'm talking about it 10 o'clock in the morning Eastern time.  So it gave us that opportunity, right? From there though, well, you see what happened. So, you know, not much happening right now on this HCI, just to be transparent, as I always am, you know, I always like to say things like this, but the market dropping off as much as it is, not expecting to find, you know, really a whole lot on this gainer side here.  But, you know, we've seen this stock trade way more volume than what's, what it's doing right now. So meant to scan up here. So there's not really much else that's really on the gainer side at all right now. Aside from the inverse ETFs, I see drip, Fahs, you know, SQQQ, all the others. I'm not going to single them out really aside from UVXY. All right, let's hop on over to the losers list right now. Why did I not bring my water bottle with me here? I have no idea. Dogs ended up dropping off midday. This thing got crushed, right? Ended up leading to a nice dead cap bounce. Nice opportunity it took like forever.   So right now, not too particular about this right now at this point, the dogs trade, you know, but for as much down as this was, and it's still down a lot 50% yearly, but it was down like 65-70% from the initial gap downs and the drop-offs with the halt. So, you know, with that, that leads you to think for as much down as it is, you know, that could lead to a little squeeze, but man, that took a while. I mean, you really shouldn't be waiting that long as the volume tanks here like this, because more often than not, you're not going to get that squeeze. It's just going to be like kind of flat and even sometimes even pull back lower or pull back to the lows or break lower. You know, it's likely to do that here heading into this afternoon, I think.  At that point, ended up finally holding a key level I was calling out from the day. It was kind of dancing around it at first, but off the 11.75 level. That led to a pretty good short opportunity. I was following that with one of our traders and our coaching call as well. Ended up taking like a dinky 3-cent loss because it wasn't going anywhere at the time. I waited like five minutes on the trade.  So, you know, it just goes to show, at least if you're following the right levels, worst thing that happens is, you know, you end up getting stopped out as so long as you set your stop at a reasonable price. I even did that and I just didn't even follow my first instinct and I yanked the trade beforehand. And it ended up making the move that I wanted it to make. So, from there, Jim, I ended up jumping back in this trade as it ended up pushing above and then back under that 11.75 level. I could zoom in on the chart there. Right here, I ended up re-entering off the 11.75 and then from there dropped down. I ended up leaving money on the table on this trade, but man, it took forever. But at this point right now, it's just pretty inactive, not really doing much of anything. You know, for a stock reporting bad earnings shortable, easy to borrow trade, perhaps that could be a pretty nice opportunity to follow here at this point, but not really doing much of anything this GPS. There we go, Jim, more creative than me. He says GPS just doesn't know where it is. That's my drum sound. That actually was a pretty good one. CYH dropping off right now. Hey, shortable. The only issue on this stock is it's not trading really any volume. Like, you know, 3,000 shares a minute. That's not really what I want to see at this time of the day. The THC trade, I always joke with this one, not a pot stock, but THC, get it.  It's pretty damn expensive, so not really too particular about this trade. The UEC trade, this one we've been following for a little while, namely on the way up, you know, throughout the month of April, but dropping back down the last couple of days at the lows trading 22, you know, 23,000 shares a minute. You know, it's at the lows, which I do like. There is an iceberg support off 450. So, you know, reluctant, but I'll slip it on here. I'm reluctant because it's slow, more than anything. It's like extremely tradable, but like, it's like watching the grass grow, watching the paint dry here, kind of, you know, have this approach down towards that iceberg order. All right, folks, let me see, I don't think there's like really much else that looks like a familiar name on the loser's side here, AEO maybe. Is that American Eagle Outfitters? It is. It's at the lows. It's trending down nice. This looks better than UEC. So, if I put UEC on the watch list, I feel like AEO, you know, I don't know if this is earnings related or not, but I mean, hey, as far as just a tradable stock, shortable trade, you know, heading into the afternoon, we'll take it. Norman's saying CYN worth watching. So, I'm going to need a little help here, folks, for all of this on YouTube, Facebook Live, for Norman and all of us live inside the Cyber Group Room, if there's any other stocks that you want me to look at, just type it in the chat board. Obviously, the CYN for right now, squeezing back on up here, yeah, looking really nice, really from $2.30, as soon as we start this meeting, it ended up making a nice balance from $2.20, pushing up. You have about $106,000 share order on the ESC sitting there at $2.50. So, yeah, it definitely looks great, the CUI entry. The MITQs pushing back up, folks, that's at $1.60 now. It's grinding on up and the VLON trades, you know, it's holding under that really big level I'd reference $2.20, and even after $2.20, $2.30 is actually just as strong, I think. Not every 10 cents is going to be as strong, but in particular, I charted $2.20, $2.30, you know, for VLON this morning. All right, I don't have anything. I'm good to go. I know the sound's working this time.  I know yesterday I ended up botching the audio, so my bet on that. All right, folks, I'll tell you, we don't need to make a big watch list heading into this afternoon. Unfortunately, the VLON held $2.20, it's snapping back down right now. You know, not so particular about that, but it's still on our watch list. The GPS trades actually dropping back down right now, testing $1.50 support. So, you know what, that actually could be a decent short for the news coming out or that came out on it. I'll give it a look. Put that back on our list, the gap trade. All right, so in total, I got two, four, six stocks. I'm sure there could be some sideless stocks if the market, you know, makes any better move or, you know, quicker move down or up heading into the afternoon. You know, NEO is at the low today right now. I think the AMC trades, you know, kind of consolidating around the lows. You know, like the airlines are dropping back down to the lows right now. So, those could always be good opportunities. You know, they'll be on the side list for right now. And then otherwise, UVXY for any of our traders that follow the ETFs, you know, that obviously is and play with the market down. All right, for all of us on Facebook Live, YouTube, I appreciate you dealing with my dry mouth throughout this afternoon here. I appreciate you. If you have any questions, feel more than free to send it on over an email to Josh at C2Trading.com. I always like to, you know, cut it straight with you. I appreciate you dealing with my dry mouth this afternoon. Nonetheless, enjoy the weekend. Scott calling out T-Cat once again here at the end. We looked at T-Cat earlier, Scott. It just has no volume. You know, if you're a member of Cybertrading University and this doesn't just go to Scott, I just want to make this clear to everybody. If you're a member of Cybertrading University, then you got to follow the big volume. If there's no volume on a trade, then it doesn't make sense to follow it. And that's all right. We just have to identify these things. I mean, yeah, it's pushing up a little bit, but, you know, we got much better opportunities, much more volatile opportunities that V-Lon actually snapped right back on up. I mean, that could be due for a big push in either direction. You're heading into the close. It'll be interesting to see if this could break back over 220. All right, folks. So for again, for all of a sudden, Facebook Live, YouTube, if you have any questions, feel more than free to email me, Josh at C2Trading.com. Enjoy the weekend, and then we'll be back to be back up on Monday. All right. For all of us live inside the trading room, just give me a quick breather. Geez, I got to refill up my water here, and I'll be back on the sticks right at 330. All right, folks, take care.


Really on our side The storms we chase are leading us And love is all we'll ever trust Yeah No, I don't wanna waste what's left And I Slam through the highways To my shadow, through the sun rays And I And I We always Slam through the highways To my shadow, through the sun rays And through the highways


Greetings everyone. It's good to be able to speak to you as you connect with one another for your global village conference. Connecting with each other is one of the main advantages we enjoy as members of the Commonwealth Family of Nations. Whether we are from India or other member countries in Asia or from Africa, the Caribbean and the Americas, Europe or the Pacific, we share friendship and care about each other and work together to make life better for everyone. The 54 member countries of the Commonwealth are spread across every continent and ocean and together we account for one third of the world's population. Of the 2.4 billion people who live in the Commonwealth, 60% are under the age of 30, so although we are a long established family, we are still a young family. This means that we look to the future with great hope and with big plans for making our world a better place in which we can all live together in health, peace and prosperity. That seems to me also to be the purpose and idea which motivates Pangea and so in the same way that we draw encouragement and support from one another as individual women and girls, men and boys, we also draw strength and broader vision when we work together across communities and the boundaries of nations. The pandemic which has swept across the world with such devastating consequences over the past year has reminded us of how closely we are interconnected and independent wherever we live on this planet and that the well-being of any one of us affects the welfare of all. The consequences of COVID-19 go far beyond the tragic loss of life and impact on health services. Trade and travel have been drastically curtailed, resulting in sharp economic downturns and painful loss of jobs and income. Education has been affected very badly in many countries and the long-term consequences of closed schools and cancelled examinations will affect young people in many of our communities for years to come. Some are referring to this new generation as the COVID-19 generation. However, this should be seen as a positive and not a negative because it is a time of great innovation, collaboration and inspiration. Just as the post-war generation in 1945 was responsible for some of the most remarkable improvements in the world, so too, I believe will be the case for those of you of this generation who will craft the solutions of some of today's most entrenched and intractable problems, particularly those relating to climate change and the crisis which it has created. We have become far more conscious over recent years of the ways in which misusing natural resources or failing to care for our environment, the ocean and the living lands makes life more dangerous for everyone. Climate change brings some frequent incidents of disastrous weather events and life for people in some places becomes unsustainable. Many Commonwealth countries are already facing increased temperature, sea level rise, storm surges, drought, floods and hurricanes. The leaders of the Commonwealth nations have been expressing concern about this for many years since as long ago as 1989 when the leaders of the Commonwealth came together and expressed their deep concern about the existential threat posed by climate change in the Lankawi declaration in Malaysia. Since then, we have been joining together in practical action to change things for the better. We can only do this by deepening understanding of how our own action affects others, by changing attitudes and by working together towards a future that is safer and pays attention to the needs of everyone. And where the opportunities and progress offered by education and prosperity can be enjoyed by all. The values and principles we share are brought together in the Commonwealth Charter and I would encourage all of you to read it and study it. Especially as its opening words are, and I quote, we the people of the Commonwealth, which means you and me. The Charter and the commitments it makes were adopted in 2012 by the heads of government of all our member countries and it was signed at a ceremony on Commonwealth Day 2013 by Queen Elizabeth II, the head of the Commonwealth surrounded by young people representing many of our member countries. The same priorities of peace with mutual respect and gender equality, democracy and development through good government, access to health services and education, provision for safe housing and employment, respect for our planet and why stewardship of its resources were all brought together two years later in the United Nations agenda for sustainable development. I expect you know that the target date for the sustainable development goals of that agenda is now less than 10 years away. We all have much to do if we are to achieve those vitally important goals by 2030. As Secretary General of the Commonwealth, together with my teams at the Commonwealth Secretariat and in other partner organisations, it is my privilege to work alongside the governments and people of all 54 of our member countries so that together we can achieve progress towards those goals through democracy and development in which all can share. An important principle in all that we do and for those alongside whom we work towards our Commonwealth Charter commitments and the sustainable development goals is to leave no one behind. Respecting the dignity and human rights of every person, regardless of how rich or poor they may be, whether they are male or female, whatever their beliefs or cultural heritage lays the foundation on which we are able to build together towards achieving our full potential as members of the wonderfully diverse human family, which is so fully represented in our Commonwealth family. Through our Commonwealth initiatives, we work to transform the lives of children and young people so they can become responsible, educated and global citizens empowered to help make their communities stronger, safer and more inclusive places to live, learn, play and work. We are also concerned for the welfare and continuing development of disadvantaged people, whatever their age and for marginalised communities wherever they are located. This means making sure that the voices of all are heard and heed is given to their aspirations and expectations. Being able to participate freely in democratic processes, elections to local councils, to regional assemblies and to national parliaments is of immense importance. This means a person enjoying the freedom to assemble and to join with others in campaigning on matters which affect his or her life. It means having the resources, time and money to be able to continue with education, to be able to read and to have access to free and fair sources of information and challenge of communication. It also means being able to trust the authorities responsible for maintaining law and order, the police and court systems which uphold justice, as well as enjoying our own right to live free from fear. We have a responsibility to ensure that others enjoy that freedom too. This means refusing to allow those motivated by ill will or extremist views or beliefs to instill fear through violence or the threat of violence. It also means being alert to the possibility that people we know may be living in fear because of violence or abuse in their homes or from members of the family or wider community. It is distressing to see that violence in the home has risen very sharply during the coronavirus pandemic and as a result of many people having to spend more time confined at home and in cramped living conditions with a very limited chance of escaping harm or finding safe refuge. The social, human and economic crisis caused by the pandemic has exposed more starkly the inequalities and disparities in our societies. Even before COVID-19, our education systems were at risk of leaving millions of learners behind, particularly girls. Despite commendable progress, illiteracy remains a barrier for many. In sub-Saharan Africa and South Asia, literacy levels are only 64% and 71% respectively. Put another way, only two-thirds and three-quarters of people in those regions are able to read and write. Factors such as living in a remote location, being poor and being disadvantaged or marginalized socially immediately increase the risk of low educational attainment. So those of us who are fortunate enough to have access to good quality education must do all we can to remedy and change the long-lasting damage caused to so many people's lives through limited access to schools and teachers. The pandemic is making the situation even worse and it seems likely that because of its economic impact alone, as many as 24 million more children and young people globally may not have access to school or drop out of education next year at levels from pre-primary to tertiary. The nations of the Commonwealth are determined to work together to fight against the awful impact the pandemic is having on education and through mutual support and cooperation to emerge from this crisis stronger than ever. Through our work, we aim to support the most vulnerable children, youth and adults, especially those living in poorer districts or remote areas, girls, refugees, persons with disabilities, so that they can continue their learning and training to reach their full potential. The heads of government and education ministers of the Commonwealth countries are concerned particularly to make sure that the lack of access to ICT and the internet do not widen the divide in education between rich and poor, between privileged and disadvantaged. And this has become even more of a priority with distance and online learning becoming more necessary during the pandemic. I referred earlier on determination to ensure no one is left behind and that is why we are concerned particularly for marginalized communities and people who tend to exclude that such as vulnerable youth, refugees and women. Access to education for all irrespective of the ability to pay is an aspiration which the Commonwealth is ready to do everything it can to achieve. It is encouraging to know that you are alongside us in this through your involvement with Pangier Global Village and through other similar multilateral initiatives with which students and staff at Elpro International School are associated. I commend your commitment to becoming truly global citizens and your readiness to contribute to making our world a better place for all. Events such as the Accelerate programme plus and the student-led conference and sport and arts events help to form confident, active and creative individuals ready to achieve their learning targets and to attain their full potential in all aspects of life. The Elpro mission of providing a broad and balanced international curriculum and optimal learning environment for children and building a community of mindful, impactful and empathetic students aligns closely with the shared vision and values of the wider Commonwealth and our determination to deliver a brighter future for children and young people in all our member countries. In wishing you well for the Pangier Global Village conference, I would emphasise the importance of all schools being places of peace, hope and reconciliation. Working together in the Commonwealth and alongside governments and other multilateral organisations, let us spread that message and ensure that other children and young people in all parts of our wonderful world are able to join as fellow global villagers and classmates. Whatever we may wish our future to be, it is best served by granting all children and young people the right to live, learn and develop with dignity, in peace and security. Be strong and encourage one another. Together we can achieve great things.


Good afternoon, everybody. I'm Tommy O'Brien, company live from TFNN, 4 p.m. Eastern Time on Tuesday as we reach the closing bell and the market catches a little bit of a bid. Check out the acceleration there, right? This is a five-minute chart we're looking at. About 3.30. We're trading a 47.87. We close at 4,800, basically on the dot. In the futures, we're negative by 16 points right now. That's about a third of a percent. NASDAQ 100, on a day when chips and AI are accelerating higher, NASDAQ 100, we'll call it flat, 16,969. You get the Dow off 6-tenths percent, 37,557.  Bitcoin, off about 240 bucks, 43,540. You got crude with a 71 handle, pushing the session lows today, almost 71.88, down 80 pennies. Gold, just talking a little gold with our man, Tim Moore. Gold right now, down about $20 on the session. We got dollar strength, man. I'm going to get over to the dollar in a moment. Gold, down $20 at 2,031. You jumped 10 notes and bonds, lower price, higher yield. So what do we have? We have higher yield, dollar strength, market weakness, the theme at least to kick off this trading week, and there's your dollar, man. Up 97 pennies, we'll call it, to 103.73. But if gold's going to trade higher, what's going to happen? You're probably going to get a little bit of weakness in the dollar. Interesting to see how that's going to shake out, and check out. I mean, I was looking at this even as I was talking to Tim, finish up the program last hour. Absolutely remarkable when you look at gold longer term. That's your gold contract going back to when? 2004, 371. You accelerate up to highs in 2011 of 1923. We're within about $100. I mean, this consolidation area is totally right at all time highs from 2011. You get above that area in 2020. We've been shopping around since then. So interesting to see if that's where we go, and you take a look at the dollar index goes back to 2004 as well. Not outlandish to think. Where are we? We're at the strongest point we've been in in the dollar index outside of the last two years. 103.73. Yeah. Many times we've been sending them at lower prices, even when you go back to where we were taking COVID out of the scenario. 2018, we're down at 90, man. Spent a lot of time between 95 and 100. We're sitting at 103.37, so maybe there's your correlation. What are you looking for? If you're looking for a gold bull run, what are you looking for? Eventually, we're going to get there, folks, a weaker dollar, and that's probably going to come when we eventually start getting those cuts, which are coming maybe just a little bit later than the market was thinking. But right now they're talking June. That's going to be here before we know it. Thanks so much, folks. Have a great night. We'll see you tomorrow morning at 9 o'clock. Thanks so much.


Hey guys, what's up? It's Kinsey and welcome back to my channel. Today's video is pretty exciting for me. I'm going to be doing a kind of like I tried this product for a week. I have not done too many of these videos and I really actually want to try more videos like this. So if you guys have products and stuff that you guys would like me to test out, comment them down below. See how I start with my hair like this? It looks better and then I just like can't survive with my hair in front. We're gonna try our best in this video. If you guys are new here, subscribe. Today I'm going to be talking about High Smile. I'm sure you guys have seen High Smile everywhere because I've seen it everywhere. So anyways, I am working with High Smile on this video. I just want to be very honest with you guys. But like I am one very very very particular on who I work with and if this stuff didn't work I wouldn't have followed through with the video. But I am like so unbelievably impressed. My boyfriend had been talking about how he wanted to do like teeth whitening stuff for forever and he has recently done stuff and like oh like it just hurts your teeth. It's such a hassle. It's messy. Like and also I think my thing is that when I have it in my mouth all the time I feel like I can't do anything and I don't know. Like I just felt kind of like you know when you're at the nail salon and you can't use your hands and you almost feel kind of like really antsy. That's how I felt with other teeth whiteners in the past. So I'm excited to talk to you guys about High Smile because it genuinely has been a completely different experience for me. But if you guys are new here, subscribe. I love you guys and yeah we're gonna be doing our first. I tried this for a week and I want to do this with other videos like maybe workouts. I'll consider doing a workout since now I'm not gonna be in LA 24-7. So it's not hapollates every single second of the day or other products or anything like that as far as teeth whitener. I'm set on this. Again I've used the strips. I've used everything I possibly can use and it's always a hassle. It's always a mess. It's always just like, I don't know. I'm not someone who is going to fall through something and stick to it if it's not easy, practical and lets me kind of like almost multitask. So you guys will see why I love this. It's just the best thing ever. A lot of like celebrities like him Kardashian and Conor McGregor a lot of people use High Smile and have posted about it in the past which is bats really cool and then I know a lot of people like personally in my life like in the influencer like follower whatever realm and in like my normal life in Texas who use High Smile and like swear by it. So when they reach out to me that sounds like okay I actually do want to try that because we have been looking for a teeth whitener and I've heard good things so I'm going to test it out, you know? So High Smile recently announced the launch of their new and improved teeth whitening gel formula. This is the only teeth whitener I've ever used that didn't make my teeth really sensitive and hurt. Teeth whiteners in the past would hurt like not even like as I was doing them but later on throughout the week I'd be like oh my gosh my teeth are so sensitive and I'm kind of a baby so that just doesn't work for me. High Smile also listens to its customers which I think is so important and like from just a business model I'm in business school so that's something that I don't know. I think I love working with brands because of what they do but I also love working with like businesses that I see are actually like doing things that they should be doing and that are great, you know? So I think that's really important so anyways this new formula is a result of listening to the customers so obviously it's going to be much better because they're listening to people who actually use it. It's also vegan and cruelty-free, they've been working on it for the past year, it doesn't make your teeth sensitive. Okay sorry guys, my dumpster chart came for a solid 30 minutes. So anyways, okay so anyways all this to say I decided to give it a try. Again I would not be filming this video if I didn't love the products I promise you. Okay so the High Smile Teeth Whitening Kit one, the branding on this is beautiful. It is so cute, you guys are going to see it. I'm like love that. I just love, I really appreciate some good packaging and stuff. Anyways I'm going to show you guys what it comes with. Okay so it comes with instructions, a shade guide, a demonstration on how to apply. There's three gels and it's 10 minutes a day for six days. So I've tried it over the course of six days. I'm going to show you guys using it how it kind of like battered my teeth. You guys can definitely see they're a lot whiter. Like I feel like this is such a weird thing to do but like they are so freaking white. Like my teeth are never that white so I feel like really cool, you know? Alright so I'm someone who drinks a lot of coffee so I do not have the widest teeth. This is me on day one. I'm just applying the gel to the mouth tray and then you put the little LED light on. Then it will go on for 10 minutes. It times it for you so you don't have to set a timer yourself and you can just go about your business and continue on with your night routine. So this is day three. Again it's so easy because I would just use it as I was doing other things and it wasn't like just falling out of my teeth because it was like a weird strip. It's pretty and it stays in there. This is day six. So again I would just do this as I was editing videos or watching Scandal. My favorite thing to do right now. But yeah it takes 10 minutes. It's the easiest thing ever. Super super simple. You guys will see here that my teeth definitely got a lot wider. Here is a little before and after. Okay so I have a few things to say about the kit and besides the fact that it works really well. Okay I love how I don't have the time of myself. You press the button and it lasts for 10 minutes. I love that. I love that. You can just keep it in your mouth really easily and it's not like something that's going to fall out or anything like that.  I will always just put it in my mouth as I'm doing something else. So I don't just like sit there.  With this you can multitask which I really appreciate. I feel like that's just something that I personally can give up with because I'm not someone who's going to like go out of my way every single day to go spend time doing something. With using this kit I felt like it just really was easily incorporated into my routine into something super super easy to use. Also there's toothpaste for morning and night which I love because I felt like it was like I don't know I love my skincare routine and I felt like it was kind of like adding something to that if that makes any sense it's not skincare but that's like when I would do it you know morning and night. So I felt like that was really easy also to incorporate because I just switched some stuff out. I would already brush my teeth morning and night anyway so that was really easy. It wasn't something that I had to like really go out of my way to do and remember to do it and feel like it was just like another thing to add to my to-do list for the day. It was something that was like really easy to use really easy to incorporate into my routine wasn't super messy it wasn't messy literally at all which is so nice. I am going to keep using the kit and the gel refills to maintain this because I just cannot believe it made this big of a difference in six days too like that's kind of crazy to me.  So the kit is $60 it's only available on their website so I'll have all that linked down below. Also if you guys are still a little bit hesitant and skeptical I feel like this is something that people are I don't know what it is I think maybe because there's just so many teeth whiteners out there that are like not great in her. Anyways if you guys are unhappy with your purchase they do offer money back so really you can't lose. Anyways you guys can see how much better my teeth look. This is just a really good confidence booster for me too because my teeth are not looking the best and I'm really happy with this and I'm really glad that I actually gave them a shot because this is also something I normally wouldn't try out and I'm just a little more hesitant but I'm glad that I finally found one that I really like. Anyways I will have all that linked down below I hope you guys enjoyed this video and found it helpful in any way if you guys are purchasing the kit let me know. I have you guys as my friends so I would never tell you to buy something or recommend a product to you guys if I didn't try it first and love it and also if I didn't think it was genuinely worth it in such an amazing product. So while this video is sponsored like I'm just I'm being so honest with you guys like it is so freaking good so I am going to keep using it I freaking love High Smile I'm going to recommend it to all my friends and family but anyways that is it for today's video I will have High Smile linked down below you guys can check them out let me know what you guys think and let me know if you guys want me to do more videos where I test out a product for a week or a workout or anything like that oh my gosh no coffee for a week that would actually no promises on that one but I love you guys so much hope you guys enjoyed today's video and I will see you guys soon. Bye!


Hi everybody. I'm Yuri. I work as principal engineer for Apsa Group and let's chat about crossplane and how it helped us to scale our Kubernetes global load balancer. So quickly about the crossplane setup in Apsa. Apsa is a huge financial organization that serves multiple countries in an Africa continent and we have a pretty reasonable scale and we are operating over a hybrid setup part of the workload on-prem and part of the my AWS. Crossplane instances are currently deployed within our on-prem data centers and Kubernetes clusters. We are using a set of crossplane providers, main ones AWS and Helm, and we use our special summit operators that we developed to automatically propagate credentials as Kubernetes secrets in an automated way. We use crossplane composite resource model and associated composite resource definitions to create our very own platform and provide an abstracted resources to our technical customers. So main XRDs, composite resource definitions that we operate as a moment, are a three bucket to provide a specially configured data storage, object storage, PostgreSQL instance, ECS clusters and KAGB for global load balancing. So we mostly focus on a KAGB part today. Meanwhile the principles of crossplane-based compositions are shared between these resources. So what is KAGB? It is a open source project that we developed in Apsa. It is a cloud native global Kubernetes global balancer. It is a Kubernetes native and it enables global service load balancing function for workloads that are deployed on top of Kubernetes clusters, typically in geographically dispersed data centers or different cloud regions, like different AWS regions is a common reference setup. One of the distinction points of a KAGB project is the absence of a single point of failure. So we do not have any control clusters and no instance where traffic is going through. So there is no single bottleneck and the system is architected and the way to be really reliable at a global scale and it is all based on a DNS protocol that is battle tested by internet and is a good match for global load balancing traffic steering. We faced obvious KAGB deployment challenges because we operate on more than 120 Kubernetes clusters and this number continuously growing. And there is an obvious challenge of repetitive helm configuration where we, given we are packaging KAGB as a helm chart, we're providing flexible enough configuration parameters to enable customization of every part of a KAGB as a distributed system. Meanwhile, our special specific setup is relatively stable. So we need to parameterize not all of them but a minimum amount. And that's how cross-plane helps its abstracted resources. So here is an example of a cross-plane composite resource plane which provides an interface for end-users, a little technical customers or whatever services or human interfaces with a Kubernetes API. We're exposing just five configuration endpoints to drive the KAGB installation of multiple clusters. So it provides very effective abstraction, a very minimal configuration, only required params are getting exposed and you decide what kind of these params are with the help of cross-plane abstraction power. This setup is very good for GitOps. So we can easily automate the application of this XRC manifest with tools like Argo CD or Flux. And we don't need any client-site implanting like a Customized with K because the XRC yamls are very minimalistic and we can just drop them into GitOps repo and let Argo or Flux apply it to the target clusters. So let's perform a very quick demo and demonstration how it all works. So we already have a couple of clusters where cross-plane is already deployed. We have an empty KAGB name space which we will use to deploy KAGB installation. Let's quickly look how XRDs are composed. So we have a package that's a starter XRD definition. So it's a compositor research definition and that's how we expose the required parameters. It is an open IPA history schema and the heavy lifting is done in a composition where we actually provide the default parameters and then patching them from XRD down to the specific resource instantiation. We have examples, resource claims. So let's be the European one. So that's exactly this minimalistic abstraction that was demonstrated in the slides. So let's create a KAGB installation where it's tagged this EUS 1 and it's going to talk by configuration with Africa. So it is as easy as applied with KubeControl and we can check the status of abstracted resource with the standard KubeControl commands. It's not yet ready. Meanwhile, we can check and demonstrate that it is under the hood of the standard health facility thanks to cross-plane provider health. We can check abstracted resource again. It should be already ready and it's true and we can quickly check the ports of the service evaporate and let's quickly describe this port and double check that the environment variables were properly propagated down to the port configuration. And here we go, cluster geotech as expected, labeled as Europe. We can do the same same application of resource in another cluster in another data center. The only difference is in this specific instantiation is it's totally the same. It just the geotechs are flipped because this cluster resize is another geographic location. So we can quickly check the ports there. It should be already ready and let's make the same and double check as in another cluster. Here we go. So we have a properly configured system in both of clusters in both data centers and that's how we minimize the setup and make it very concise and declarative. To dive into this cross-plane composition concept, you can visit a very good official documentation which describes composition in a very practical way. There is a very nice video of a core cross-plane developer providing you ideas of cross-plane composition to be used to build your own cloud platform. That's pretty much what we do in Xenopsa. KGBI official website for Kubernetes global balancer in case you're interested in this topic, please visit it and visit our GitHub repo and provide feedback and you can grab these slides right in sketch so you can click all these links and follow through. So thank you so much. That was an example of how we using cross-plane and in-substruction power to scale a distributed system as an example KGB and you can use the same approach to scale and compose your own unique platform instructions on top of Kubernetes. Thank you so much for watching and have a great rest of the conference. Goodbye.


The study found that a virtual operating room tour, VORT, before surgery did not significantly reduce perioperative anxiety in patients undergoing general anesthesia, but it was perceived as useful and beneficial regardless of age. Therefore the general use of VORT can be recommended. This article was authored by Lena Voight, Martin Clayson, Ralph Rossaint and others.


I'm out to cover today, so I want to just get right started. Today, what I'm going to try to do is wrap up the content that you'll need to do assignment one, which is do two weeks from last Friday. And then on Wednesday, we'll go on and go back to our discussion of the system call interface and talk about the rest of the process life cycle. So today, we're going to talk about a couple of synchronization primitives and then try to use those synchronization primitives to solve a couple of classic synchronization problems. Then towards the very end of the class, we'll have a little bit of a discussion about how to choose the right primitive for approaching a particular problem. But this is something that will be covered in section and through your experience with assignment one this week in more detail and next week as well. So if you don't have a partner, you need a partner. I think, hope I explained with enough accuracy to partner protocol for this class. So you should be working on assignment one right now with your partner. If you're not doing that, you need to find a partner. If you are the one person in this class, we have an odd number of people who are enrolled. If you are that one person who does not have a partner, please contact us. We will probably get seven emails like that, and we're going to partner up six of you. But there will be one person left over. That's inevitable. We're an odd number this semester, at least so far. But please don't feel awkward about this. You really need to have a partner. And if you don't, you need to fix that as soon as possible. Because once you start submitting the assignments, you're going to need to be working with that person. OK. So I posted this on Discord. But just let me introduce the new protocol for discovering errors in the assignments and the website and other things. So this is quite simple. If you find, so all the sources for the website and the assignments and including the tool we're going to start using to grade your assignments are all up on GitHub. So it's very simple. If you find a typo, or if you think that you can add some clarification to the assignment that's useful, we will give you some amount of extra credit for the class, up to like 5% for the total for the semester. OK. The caveat here is that you cannot just email us and be like, there's something on the assignment that doesn't make sense. You actually have to fix the problem in most cases. If it's something really strange with one of our tools that you don't really understand, if you can identify it and you can show us how to reproduce it, then you'll get some credit. But particularly for things on the assignment, I've had a couple of people that have said, there's a typo here or there, whatever, fix it. Fix it. Send us a pull request on GitHub.  And that amount of credit is completely at the discretion of the core staff. So we will do our best to be consistent about this. But finally, please don't let this distract you from the actual assignments. This is just something to encourage you to, if you see something wrong, say something so that we can fix stuff and improve things for the future. Any questions about this? OK. Next thing. So we posted all the assignment deadlines. I'm in the process of working on getting assignment two out there. Assignment one was released last Friday. So here's how this is going to work. So you have two weeks for when we told you the assignments were due, which was last Friday. So you have two weeks to complete assignment zero and assignment one. Then you'll have three weeks for assignment two. That essentially ends up right before spring break. So assignment two is due to the Friday before spring break. If you have plans to go somewhere exciting and fun and you're going to leave on Wednesday, then your due date is different than the rest of the class. Then we'll have the spring break off. The next week, we'll have the midterm on Wednesday. So we won't count that as part of the time you guys spent on assignment three. And then we've divided assignment three into three pieces this year. This is an experiment. So every year I've taught the class, we've tried something different with deadlines. The first year, we had kind of normal deadlines. The second year, we had no deadlines. Then last, I think two years ago, we had one, two deadlines. Last year, we had more deadlines. And this year, I guess we're trying even more deadlines. So I don't really know. I mean, no matter how we do this, it seems that people do not start the assignments early enough and struggle to complete them. But this is our latest experiment. And regarding time management, so how many people have started on assignment one? OK, so that's good. There's a couple of hands up. At this point in the semester, you guys don't really have a handle for how difficult these assignments are. And maybe they won't be hard for you. I don't really know. They were hard for me back when I took the class. And students usually find them challenging. So my suggestion is, if you think the assignments are easy, then just start them now. I mean, don't wait till Thursday. Just do them now, and then they'll be done. No problem. So if you really think you're going to be able to complete assignment one in a couple of hours, then why don't you just set aside those couple of hours today, and then you'll be done. No problem. So this is what I encourage you to do. If you think the assignments are easy, start them a week before, and then you can just kind of hang out and relax and everything like that. That way, if you find out that they're more difficult than you anticipated, then you will have more time. I don't anticipate pushing any deadlines this year. You guys know them. The materials are up. We have plenty of time for you to do the assignments, so we're going to be pretty inflexible about things. And there will be heavy penalties for use of the solution sets as we've described in the past. All right. OK, any questions about administrative stuff? OK, happily, this is getting down to a dull roar. All right, so today, where we left off last time was we had essentially designed a spin lock using low-level hardware primitives, and that spin lock was providing us a starting point for fixing some of the synchronization problems, the race condition that we had discovered in that piece of bank balance code. So if you remember, I think we got to this right in the class. So locks are core synchronization primitive, and they're used to implement critical sections and generally to guard access to shared state and shared data structures. So in cases where you can have multiple threads accessing the same piece of state, and in cases where some of those operations need to be atomic or there's certain things that a thread can't be interrupted in the middle of or states that the data structure should not be seen in, the lock can make sure that this happens. The lock interface is quite simple. It has two commands. You guys could implement this for assignment one. It's acquire and release. It's kind of what you'd expect. You lock a resource while you are busy using it, and then you release the lock when you are done using it. The spin lock is what we discussed on Friday. So the spin lock is a form of a lock where, remember, there were two ways that I could wait for a lock to become free. So if I try to acquire a lock and the lock was busy, there were two ways to wait. What were those ways? One way was busy waiting, sort of repeatedly checking something about the system to see if it's changed. And in the case on Friday, what we talked about is repeatedly hammering this memory location using a test and set or some sort of low-level hardware primitive to see if it's been updated. And that will work, right? And a spin lock describes the process of acquiring this particular type of lock, which involves busy waiting. And spin locks are not used normally on their own to acquire resources, except in a couple of cases, which I'll describe in a second. But they're frequently used as a building lock for creating more complex and more useful synchronization permits, OK? So we went back to the, so now let's imagine that I've put this lock behind an interface. Last time, I was actually implementing a kind of a lock directly using this test and set operation. And now what I'm going to do is just wrap my lock behind an interface. It's nice. It's very similar. We give you guys to implement for assignment one. So at the top, remember, these three lines were in my critical section, the lines where I'm manipulating the shared variable, the balance. And so what I need to do is acquire the lock before I enter the critical section that ensures that nobody else can get in there. I know that I have exclusive access within that section to the shared variable. And then when I'm finished, I release it, OK? So what has to happen in order to meet the property of mutual exclusion, which is why we created this primitive? What has to happen if I call lock acquire while another thread is inside the critical section? So let's say there's 10 threads that are trying to modify the balance all at once. What happens to the first thread that calls lock acquire? What does it do? Keeps on running, right? It starts to modify the balance. What happens to the second, third, fourth, fifth thread while the first thread is inside of it? Yeah, average. So it has to wait somehow, right? The only way that we've talked about waiting so far is by spinning. But a more useful way, potentially, to wait for a resource to be available is to have some support within the operating system for a thread to identify an event that it's waiting for and to be restarted when that event takes place. And if you look at your kernel, you have support for this already. Yeah, question? Yeah, so interrupts play a role in this, right? We'll come back and talk in a few lectures about how interrupts play a role in this, right? So interrupts give the operating system a chance to retake control and to start and stop threads. That's the way that the operating system, that's the underlying hardware mechanism that allows the operating system to create this illusion of concurrency by starting and stopping threads rapidly. But in general, in order to sleep and wait for something, I mean, sleeping is not hard to think about. Just means that the thread is no longer executing instructions. But what it needs is a way, needs two things. It needs a way to identify the thing that it's waiting for. And then it needs a way for the operating system to restart it once some event happens. In this case, how would I event, how would this, how are these threads identifying the thing that they're waiting for? What identifies that? What's that? I mean, it's the gua wallet lock, lock variable. The OS doesn't really know what you called it in your C code. What would be a unique property that that would have across the entire system? Yeah. What's that? Oh, it's closed. It's not a function, right? The lock acquire function is going to be shared by a lot of things. But what address is unique here? The address of this lock data structure, that has to live in memory somewhere. And that address should not be shared by any other structure. So that becomes a unique key that the threads use to identify the thing they're waiting for. So what we write here is we write lock acquire, the address of this data structure, what the kernel eventually sees is I would like to wait for this variable is this hex string that identifies a memory address. You guys will see how this is done in OS 161 because this is sort of based on the primitives you guys will need to use to implement locks and condition variables, which we're going to talk about in a second. OK, so I just pointed out there are two ways to wait. So one way is to wait actively, rechecking the thing where the thread is doing the checking. And the second one is what I just described. I wait passively. I need to tell the kernel what I'm waiting for. And the kernel needs to sort of be able to identify when that thing changes. And then when that happens, the kernel is going to wake me up and say, you know, you told me that you wanted to wait for this hexadecimal memory address. Well, this hexadecimal memory address just changed. Or actually, I shouldn't put this way. Somebody just notified me that this has changed using another part of the API. And now you get to run again. So this is sort of explicit sleeping. Now there are cases where spinning can actually be the right thing to do. Can anyone think of any of them? Sort of, it's maybe a difficult question for you guys to answer right now, because we haven't really talked about threading and context switching. Yeah, way up in the top. Yeah, OK, somebody looked at the slides. I like that. So OK, so first of all, let me point out something. Again, back to this weird world where there are actually single core systems. On a single core system, it never makes sense to spin waiting for a resource. Why not? Yeah. Yeah, right. And what's required for that thing that I'm waiting for to happen? Think about the bank example. Some guys outside the critical section waiting to get in the critical section. What is he waiting for? Another thread to get out of there. So if I'm sitting there burning cycles, all that is just time that the other thread cannot run. Does that make sense? So on a single core system, again, of which there are like two left in the world, this is never a good idea, because spinning always prevents the thread, some other thread, from making progress. And that's what I need to happen. That's the only way that the decision is actually going to change. But there's an interesting trade-off here between the length of the critical section and the overhead of a context switch. And again, we haven't talked about a context switch yet, because we actually haven't talked about threading, which we will when we talk about how the CPU is multiplexed. But it turns out that there's an overhead required for the operating system to stop one thread and to start another thread. You might have anticipated this. In order to stop a thread in the middle of doing something, I have to save a lot of information about what that thread was doing. So when I restart it, it can't tell. So if you think about the C programs that you write, when they run on a computer system, each one of those threads is being constantly stopped and started over and over again. And yet you can think about it as if it's executing line by line in some sort of sequential way. And the reason is that the operating system is very carefully when it stops your thread, saving everything about the state of the world that thread might be able to observe, and when it restarts it, it has to restore all that. So that creates overhead. So there's overhead for switching back and forth between two threads. Now, if I sleep waiting for something, I'm forcing the context switch to happen, because when I go to sleep, the operating system is going to schedule something else. So if I think that the critical section is short, and if you write the code, then you know this. So if the critical section is quite short, then it's possible on a multi-core system that it's actually going to be more efficient to spin just for a couple of cycles, right? Let's say my critical section only has a couple of instructions in it. So I have a diagram here, right? So imagine if the critical section is short, then thread one was inside the critical section, and thread two tried to get in, and thread two went to sleep. So now there's all this context switch overhead that the kernel has to perform. And actually, by the time the context switch is over, thread one is long gone. So it would have been smarter for me to just wait, bang on that critical section for just a minute, and get in as soon as he was done right here, right? However, if the critical section is long, then it wastes a lot of resources to wait actively. So this is the trade-off. The critical section is very short, and this is why spin locks are frequently used to implement other primitives, including locks that sleep, because there's a small part of that sleep-alk implementation where it's just executing a couple of instructions, just reading and writing a few, from few locations in memory, and that can be protected with the spin lock because it's very fast. It doesn't sleep, it doesn't do any I.O., you know, it's just, you know, you can almost look at it and convince yourself that this is only gonna take a couple of, you know, cycles to execute. Maybe a little bit of delay for the memory reads and writes to happen. Okay, so I think I already, I think I got ahead of myself today. So the kernel, in order to sleep, the kernel has to provide this functionality that allows the thread to sleep and be awakened based on some key, where the key is normally the address of some data structure or some unique value that threads agree on. And this is what you can imagine, the, you know, the interface here is to this particular piece of kernel functionality. Again, you guys will see this again when you do assignment one, because you will have to understand how this is done in OS 161. This is not the name of, this is the interface, this is essentially the interface provided by OS 161, but these are not the right names. It was, okay. And it turns out you can actually do the same thing in user space. So they're user space libraries that implement things that are quite similar to this function. Okay, any questions about locks at this point? I'm gonna go on and talk about a different synchronization permitted. Yeah. For the user space libraries, are they just kind of like, almost like an API boundary where they're like implementing their own kind of like, to make the kernel what else to be implementing? Yeah, so we'll come back to this when we talk about threading. So it turns out that a lot of the kernel threading abstractions can be easily be implemented in user space. And for a long time, there were a lot of kernels that actually didn't provide any support for having multiple kernel threads within a single user process. So from the perspective of the kernel, every user process only looked like it had one thread. Now, in order to achieve multi-threading on a system like that, you have to use a threading library. There's something called pthreads. It's been around for decades. The go runtime provides support for really lightweight threads. There's so much ways to do this. What big change that I keep alluding to, do you think caused a lot of kernels to start providing kernel support for multiple user threads within the same process? It's a big technological shift that's been going on over the past 10 years, yeah. The web. No, good guess though. I can do web really well using user threads and sometimes better. So if the kernel only thinks that a user process has one thread, what inherent limitation does that create that would be very problematic on a modern system? Yeah. You can only use one core. So if my kernel thinks every process on the system only has one core, one thread, then it's only gonna get scheduled on one core at a time. It might be that that process has a threading library internally that's created like 100 threads, but if the kernel doesn't know about them, it can't schedule them on multiple cores. And so when multi-cores started to take over, this became untenable. Yeah, yeah. Python has some serious problems with multi-processing. Yeah, anyway. Yeah, that's one of the reasons that you get frustrated with Python very fast, especially when you're doing IO. Okay, any other questions about locks? You guys will have a chance to implement locks. You guys will have a chance to use locks for assignment one. Okay, so locks are, on some level, you could argue one of the simplest synchronization primitives. The interface has two calls to it and you can really kind of understand what they're designed to do, which is to serialize access to sort of shared data structures to protect critical sections. Now on some level, you can imagine that locks sort of permit a very limited form of communication between two threads. So when a thread that's inside the critical section calls lock release, it's a sign to a thread outside the critical section that's trying to get in that there is now the critical section is now available.  Locks are used to protect parts of code and provide guarantees about how different parts of your code will interleave when they're being used by multiple threads. Okay, but there's a lot of other types of information about shared state that threads might want to communicate to each other. So you can imagine cases where a thread in a program wants to be notified when somebody clicks on a button, when there's some data in a buffer that needs to be processed. So there's a much, in order to get multi-threaded programming to work well, there's a much richer variety of types of communication that we might want to enable. And one of the ways we do that is through something called a condition variable. Now condition variables are kind of interesting. When I started teaching this class, I guess I could admit this now because I think everybody I had in class a couple years ago was gone, except for some of my RAs. I'm not even really sure I understood condition variables completely. But it turns out they're actually super simple, okay?  So by thread safe, it means that a condition variable provides some guarantees about how signals are delivered from one thread to another. We'll come back to that in a second. So the CV interface is CV weight. So when I CV weight on a particular condition variable, what I'm saying is I'm waiting for something to happen, typically for that condition variable to change, but frequently CV weight is used in a loop where it's checking some other condition, right? So I'm checking how many objects are in this buffer. I'm checking whether or not a particular thing is true or is changed. CV notify is used by the thread that changes something to notify other threads that that thing has been changed. So this gives me a way to wait for something to happen and for the thread that actually causes that thing to happen to tell other threads that it did happen, yeah. So that's a great question and the answer is not much, right? So there is a very close relationship between this interface for condition variables and the thread sleep and thread wake interface that we just described. So when you guys finish your condition variables for assignment one, don't expect to have written a lot of code. If they're only like three or four lines for each one of the calls, you're probably doing something right because a lot of the functionality is already there. There's really not much to do. Does that answer your question? So the condition, so what am I waiting for, right? So condition variables are really just a signaling mechanism. The condition is represented outside of the condition variable and this kind of makes sense because otherwise you can imagine like these really complicated condition variables that we're expected to handle in every case. So what threads do, and I'll show you some code in a minute, we'll go through an example, is they typically check the condition and then if the condition is not, does not allow them to proceed, they call CV weight and wait for it to change and then when they wake up, they check the condition again and we'll see why that happens, okay? So the condition variable, because it's combined with observing some state about the world, can convey a lot more information than a lock. Again, it's really just a signaling mechanism that allows me to communicate arbitrary things between two threads and to do that in a way that's thread safe. So let's go through an example here. Am I getting right into the example? Okay, yeah, okay, yeah. So we're gonna do an example in class today. The example is a bounded buffer, producer, consumer problem. So imagine that I have threads that are producers of items into the buffer, threads that are consumers of items out of the buffer and those threads want to coordinate so that a couple of things are true. I wanna make sure that when there's data in the buffer, there's an active thread that's trying to consume it and when there's space in the buffer, any thread that's trying to put stuff into the buffer can proceed. The buffer is fixed size. So this creates conditions because of a fixed size buffer where the producers have to wait because there's no space in the buffer and of course if the buffer is empty, then the consumer threads have to wait as well because there's nothing to consume. When you're using a condition variable, it's usually really helpful to identify the conditions. So in this case, the buffer has three states. It can either be full, in which case the producers have to wait, it can be empty, in which case the consumers have to wait, or it can be in neither, it can be in between, in which case nobody has to wait. Right, so three different states, two different types of threads. So you might be thinking up until this point, why are we talking, there's no synchronization. I keep saying, so this can happen in a thread safe way, but that's just like professor mumbo jumbo, right? Like what does that actually mean? So what it means, so why are condition variables a synchronization mechanism? Well, I have multi-threading here, right?  I also have shared state. What's the shared state? The buffer, right? That's what everybody's trying to access. It's shared by all the threads that are contributing or removing items from this buffer. So the reason why condition variables are considered a synchronization mechanism is they're frequently raised conditions that are introduced when multiple threads are trying to access the same state, okay? So let me show you an example. So let's say that thread A comes along and for some reason on this slide I realized today, I switched to Python pseudo code, I don't know why. Anyway, I'm sorry, I think that ends soon. So if the buffer is empty, and let's say that, remember, we have to relax all of our assumptions about how threads are run. Threads can be started and stopped at any time. So at this point, let's say that thread A is trying to consume from the buffer. If the buffer is empty, what does thread A need to do? It needs to wait. It needs to wait until there's data in the buffer, right? Okay, so it checks the buffer, and let's say the buffer is empty. Unfortunately, right at this moment, thread B comes along and puts stuff into the buffer. Unfortunately, the next thing that thread A is going to do is call sleep. So now, and you guys, I'm sure this will happen to you when you do some of the assignment one synchronization problems, you have, this is essentially a deadlock because thread A is sleeping, and let's say that thread A and thread B are the only threads, they're the two lonely threads in the world who are gonna use this bounded buffer. So all, like thread A's whole goal in life was just to receive that item from thread B, that's it, and thread B's only goal in life was to get that item to thread A. So thread B accomplished its job, it put the item in the buffer, and it tried to notify thread A, but the problem was thread A wasn't actually sleeping yet when it did this, and by the time thread A gets to sleep, thread B is long gone. So when is thread A going to wake up? Never. So this is where synchronization comes in with using a condition variable, which is that, remember, the condition can be arbitrarily complicated, it's just arbitrary C code, and I need to make sure the condition doesn't change between the time I check it and the time I sleep on the condition variable. If it changes in between those two times, then I may sleep forever. Or in other cases, I may miss some event that I needed to. Yeah, check that out. All right. Okay, so I'm gonna go through an example with condition variables. I just wanna point out that I took the semaphore stuff out of today's slides because we're just a little bit behind on time. So those will be covered, you'll see those in assignment one, and I'll ask Jerry and Ali to cover them in recitation this week. Semaphores are not always that useful, okay. So let me talk, I'm gonna do two examples now for the remainder of class. So the first one is gonna point out a problem with locks, and then we're gonna come back and actually do the bounded buffer producer-consumer using semaphores, okay? So locks are super useful, but locks have a problem that you will likely encounter. If not, during this assignment, probably for assignment two or assignment three. So locks predicts access to shared resources, and frequently threads are in a case where they actually need multiple shared resources at once. So in order to do something safely, I need to use this resource and that resource. Both of those resources are protected by a lock to make sure that they're consistent across shared modifications, and I need both, okay, project. Yeah, so this is a good point. It's not, so when you decide to use locks, I mean, look, the safest thing to do with a lock is when you have some state that shared, lock it. Create a lock for it, and make sure that everybody who accesses that state acquires and releases the lock. Now, I have a sad, what's that? Oh, sorry, I have something sad to share with you, which is that unlike some other languages that are better than C, C provides absolutely no help with this, okay? So, I've had people come in for help officers and say, well, I have a lock, and I'm about my code, I'm still having this problem that's crashing or whatever. Just having a lock does not automatically protect a shared resource. In some languages, it's like Java, you can just say, synchronize, and Java, I guess, will figure out what to do for you, probably badly, but whatever. So, the C, not so much, okay? So if you declare a lock and don't use it, it has no impact.  So you, and then you ask them, well, show me all the places where you modify this data structure, and it's like got one, got one, got one, whoops, right? And all it takes is one place. Now, when you go on and you start contributing to Linux or something like that, there are certainly cases where you can get away with not locking state if you are absolutely certain that what you are doing is safe. That frequently happens when you are only reading the data structure. So let's say I'm just reading from a data structure and I know that my reads are safe, depending on the operations that are going on. Now, in certain cases, this doesn't work either. If I'm trying to walk a linked list that's being modified by multiple threads, that will just go terribly wrong, even if I'm just trying to walk it and somebody else is trying to modify it. So it doesn't always work, right? But yeah, I mean, the safest thing to do is to lock when you access a shared resource, whether that access is read only or whether you're modifying it. Does that answer your question? Okay, so, but threads again, may need to view or edit or modify multiple shared resources. Oops, so let's go through this example. So let's say I have two resources and here's sort of a canonical example. Thread A runs, thread A and thread B are both trying to gain access to resources one and two. Maybe I'll come up with cuter names for these in the future, but anyways. I have two animals now, so that would work. Okay, so thread A runs and it grabs the lock for resource one. Now I have a context switch, thread B runs, it grabs the lock for resource two. Does anyone see how this is going to end? Yeah, so now at this point it doesn't really matter what happens next. I'm in trouble because someone is going to try to get the lock for resource two and sleep and someone's going to try to get the lock for resource one and sleep and now when will these pair of threads wake up? Never, they are both, we have a cycle in our waiting graph. I have thread one waiting for thread two, thread two waiting for thread one. Okay, so this is not good. This is something that's referred to as deadlock and deadlock can be a function of use of synchronization primitives and especially sort of over-aggressive use of synchronization primitives, but usually just incorrect use. So deadlock occurs when due to trying to acquire some sleep lock, I have a cycle in my dependency graph and a bunch of threads will never make progress. Now you actually don't even need more than one thread to deadlock. How can a single thread deadlock try to acquire the same lock? Now this isn't as weird as you might think it is. So you might think, well this is just dumb, why would I try to acquire the same lock twice in the same thread? How does this happen usually? Now a lot of locks will protect against us and they'll just blow up or panic or something if you try to do this, but it still happens. Why does this happen? I mean isn't it like, can't you read your code? You've got four lines there. Line one is acquire lock foolock and then line four is acquire lock foolock? Yeah. Oh that would be awesome. That's maybe even worse. So don't acquire a lock in a loop. Now how would this happen? You write your function and it acquires a lock once and then it's still, you see some self deadlock or a panic because it's trying to acquire the same lock. Yeah, you don't release it. That's true, so that could happen. Let's say you pair your acquires and releases the way you're supposed to. Exactly, so you're working on assignment three and you call your partner's function and your partner's function acquires that same lock. So this frequently happens when the code is factored in a way multiple threads need the same lock. Now there's ways around this. There are nice synchronization primitives that will do the right thing here, which is you can have a recursive lock. I would encourage you guys to implement a recursive lock if you want to. Actually they're not that complicated to build. Recursive lock just keeps track of the number of times that it's been locked by the same thread and then make sure it's like a push and pop, right? So you just keep a counter. You say, okay, you've locked me 10 times. When you unlock me 10 times I'll actually unlock. And that can actually be pretty useful in cases particularly where you have lots of modularity in your code and you need to have two functions that can lock the same resource regardless of who runs first, right? So if foo calls bar it works and if bar calls foo it works and if you call foo and bar separately it works. So this can be potentially useful. It's not something that we give you. Okay, I just said all this. It's amazing. Wish the slides would just like keep up with me. They should be listening. All right, so conditions for deadlock. So there are a series of conditions. Now when you encounter a deadlock in your code this is a good way to figure out what's going wrong. Because there's a series of conditions that have to be satisfied for a deadlock to take place. The first is you need to have shared resources. So in some cases you can fix deadlocks by just refactoring resources so you don't need to lock them. And that's pretty awesome in general because locks introduce overhead. Locks can make things sleep and wait for something else to happen. So if you have a shared resource that doesn't actually need to be accessed in a shared way you can break it up into multiple pieces, you're gold. And this is something that kernels have done for years to try to improve performance. It's to say, you know what? We don't need this big table. Let's just break it up into a bunch of smaller tables and that'll work just as well or better because I don't have to synchronize it. No resource preemption, meaning that the system can't go over to thread A and say, I need that lock back. Sorry, I know I said you could have it. And you can imagine why this is the case because this gets terrible. I mean, yeah, okay, maybe I create some way so that when I lock the lock I provide a function that gets called if the lock has to be taken away from me but it's very hard to get that right. I mean, the idea of calling lock a choir and then proceeding when that lock is acquired is very natural. It's very simple and providing support for being able to actually remove locks from threads is not very good. If I could do this though, how do I use it? Let's say I have this feature and I have a cycle of locks. What do I use it to do? Let's say I go back to the example before I have thread A waiting on thread B, thread B waiting on thread A. They're both holding a lock that the other one needs. Let's say I have some mechanism where I can forcibly take the lock away. How do I apply it to that situation in order to eliminate the deadlock? What's that? Oh, no, well, okay, so I have to be able to identify the cycle, so that's a good point. And so I need some sort of deadlock detection that where the kernel can see, oh, I have a cycle in my graph, I have a problem. But once I do that, I just break the cycle. I just take the lock away from one of the threads, do whatever I need to do to notify it that that happened, and now the other thread can acquire the other lock and everything's good. This is not in general a very workable solution. Another way I can try to hack my way out of this is to disallow multiple independent requests. So imagine I just don't let you hold a lock if you're holding another lock. Again, I mean, this is something that will sort of by definition prevent these cycles from occurring because the cycles require that I need more than one thing, but this makes it potentially very hard to program in certain cases because it's natural to have a lock that protects a certain resource and a lock that protects another resource. I could create another lock that I get if I need both resources at once or something like that, but that's, again, just making things very hard for programmers to get right. This is usually the best exit out of this situation is to exploit the fact that I need a circular dependency graph for this to work. So if I can establish some sort of ordering on my locks, then you can convince yourself that this can never happen. So going back to this example, well, I won't go backwards. Going back to the example of the two threads that we're both trying to acquire the same two locks, part of what created the problem is they tried to acquire them in the opposite order. If they had both tried to acquire them in the same order, there'd be no problem. And then I would encourage you to go back to that example and convince yourself that if I acquire, it doesn't matter what the order is. If I acquire them in the same order, I cannot get one. Okay, so I'm just gonna go through this really fast. I feel like some lightning bolt would come down and strike me if I don't discuss the dining philosophers problem when you talk about deadlock. It just seems like it's, I don't know, like passed on and like the laws that they give you. It's like, you can pretty much do anything as a professor, except not talk about this problem when you talk about locks, okay? So I'm not gonna get in trouble. I'm just gonna do it quickly. Okay, so I've got these dining philosophers. I have no idea who these philosophers are, but I do know that they're all philosophers. Maybe you know who some of them are. I think one of them is Discard and another one's Newton or something, whatever. I mean, none of them invented computers. Okay, so let's imagine that these guys are sitting around a table for some reason and being geniuses, there are five of them and they've brought five chopsticks that they are trying to use to eat a meal. Obviously five chopsticks is not enough for five philosophers, but they didn't think about that. They're philosophers, not engineers, so. And let's say this is how they acquire them, right? So this guy takes that one. Everybody starts by taking the one on their left. And then what you can see is that I'm stuck. I had this, this is another, you know, just a longer example of a cycle where because I have now, no matter who tries to get the next chopstick, I'm stuck. So all of them need a chopstick that is held by one of the other ones. And if you look at, you know, we go back to breaking this, right? So if I don't wait, for example, if I can't grab the second chopstick, I put down my first chopstick. I don't sleep waiting for that resource. I say, okay, can't get it and drop it. So if any one of these guys drops his chopstick, it's fine, then the whole cycle will break. But this is usually a better way to do this, right? So let's say I break the cycle here. So the problem is, and again, you can certainly convince yourself if you order these around the table, if you number them and everybody grabs the lowest numbered chopstick, then four out of five will grab the chopstick on their left or their right, depending on how you order them. One out of five will go the opposite direction because he's the guy who's got zero on one side and four on the other. And that philosopher is the one that allows the cycle to not fall. So if you establish an ordering, you're good. Okay. So Denlock is, just one more note before we go to the final example for today. So Denlock is different, but similar to another case that can result that you can cause using synchronization for something called starvation. So in Denlock, everybody's sleeping, nobody makes progress. In starvation, there are threads that are making progress, but there's another category of threads that are not making progress. And starvation is important because it allows one category of threads to prevent another category of threads from making any progress. This is something you guys will have to think about when you implement your reader-writer locks because it is very easy for naive reader-writer lock implementations to starve writers. What does that mean? It means that if I have enough readers that are accessing that resource, those writers will never make progress, ever. And that is a problem. That's clearly not desirable. Okay, so here's a trivia question. What do you guys think would be better? Denlock? I mean, obviously neither is better, but if you had to pick one, Denlock or a race condition? Who picks a race condition? Okay, interesting, who picks Denlock? Why a race condition? I like that, something keeps happening, that's good. Why Denlock? Because it's super easy to detect, right? Race conditions, so again, go back to the bank example. That bank example, Denlocks, you're gonna notice pretty quickly because someone is gonna say, hey, my deposit thing just stalled, right? Like the whole system will deadlock.  Anyway, so race conditions produce unpredictable behavior, that's very difficult to debug. A deadlock produces predictable behavior, which is everything stops and that is awesome. The nice thing about deadlocks too is the system tends to freeze in the exact state that you want it to be in, which is the state that's the problem, okay? All right. Okay, so I don't think I'm gonna be able to get through this today, but let me at least set it up and then on Wednesday we'll come back to it and then we'll go on, okay? So this is kind of what we described before. Two types of threads share a fixed size buffer. Imagine I can have arbitrary numbers of either thread, I obviously need one, at least one of each kind. The rules are that if the buffer is full, producers have to wait, if the buffer is empty, consumers have to wait, otherwise everybody should be busy. So if there's an item in the buffer and there's a consumer that's available to consume it and do whatever processing we're pretending is happening, that should happen. And also if there's a slot in the buffer and there's a producer with an object that's supposed to go in there, that should also happen. So we wanna make sure that everything is kept busy, but also that there's no spinning on either side of the buffer. So I shouldn't be banging the buffer waiting for items or I shouldn't be banging the buffer waiting for space, okay? So these are the invariance that we just set up, right? So we wanna make sure that the producer waits if the buffer is full, the consumer waits if it's empty. And the producers and consumers should not be sleeping if they have work to do. And these are the things that are sort of tough to get right. Okay, so here's our two functions. These are kind of like the starter code. It's not a terrible idea when you're approaching problems like this to kind of try to write the code the way you think it should work in a serial setting. So if there was no multi-threading, this code works fine except for this. Actually, you can take this out, right? So if you remove these two conditions, this code will work fine in a serial setting, right? The producer puts an item in the buffer and increases this count. The count stores the number of items that are in the buffer and the consumer gets an item from the buffer and decrements the count, okay? All right, so on Wednesday, we'll come back and we'll finish this example. Please get working on assignment one. We have office hours all week. I'll see you guys on Wednesday.


This systematic review evaluated the effectiveness of various public health interventions to reduce the spread of COVID-19. The results suggest that travel restrictions, border measures, quarantining of travelers arriving from affected countries, city lockdown, restrictions on mass gatherings, isolation, and quarantine of confirmed cases and close contacts, social distancing measures, mandatory mask wearing, contact tracing and testing, school closures and personal protective equipment use among health care workers were all effective in reducing the spread of the virus. This article was offered by I'm in a uni, Jehan Martuk, Wa Fodduip, and others.