Now procedures have a special functionality and therefore they need to be treated slightly different. And there are two parts in the procedure. One is the header path which normally has to be done path and all the arguments that we pass in. And the second part is more important where for each procedure we need to generate additional code which will get executed at runtime when the procedure is involved. Now when I am compiling my program I do not know whether the procedure will be involved or not. So if procedure gets involved we need to do a few things and then we need to make sure that I have sufficient code to do those things. So let us look at both the parts together. So first part is that when we are talking about procedure, so what we have is, so what we have is that if I look at the syntax of the procedure called what we are saying is that there is an identification associated with argument list. So at some point of time I am saying calls and procedures with argument list and what is my argument list? Argument list can be recursively defined as a list of arguments where we say that argument list is nothing but p list followed by e and then this is the base value. So this way I can, so I am not worried about whether my arguments are expressions or not because it could be a single variable or an expression depending upon how do we know and when we look at kind of passing mechanisms that will immediately come out. But at this point of time let us assume that I am talking about general expression but most of the time you actually have as an identity part but identity part also is a general expression. Now what are the things we need to do when I look at a sequence like this, when I look at something like this in my grammar loop? Several things. One that I need to create is something known as activation record. At this point of time I will not go into details of activation record that will come when I start in between one time four point procedure but basically what activation record is saying that corresponding to each procedure certain data has to be created on stack and what is the data? I need to have the values of local variables. I need to have values for all the arguments which are being passed. I need to have space for the return value and sometimes there may be resources which are associated with the procedure which invoke this particular procedure and therefore I need to save the machine shakers before I can start completing the procedure and therefore I need to have some space where all this information will be stored and that is always an activation record but we will look at the complete structure of activation record. Then we also have to evaluate all the arguments because some of these arguments would be expressions so I could be passing something like saying all a function with x plus y. So x plus y needs to be evaluated and then copied into the formal parameter. So I need to evaluate all the arguments then I must establish all the environment pointers. Now what are environment pointers? So basically environment pointers are the ones which are going to capture the scope information. So if I have for example nested procedures and functions, if I have a function f1 at this level and within this I have an f2, within this I have f3 and so on, some deep level of my screen and at some point of time I say that I want to invoke this particular procedure. Then I must know that what are the variables of f3 which are going to be fetched from within the scope of f3 and from within the scope of f2 and from within the scope of f1 and so on. And that is going to be some variables which are going to be global. So I must know for each of the variables within f3 that what is the environment from which I need to fetch and therefore I must add pointers to all those environments. And I must save status and return addresses. So I must know what are the values which are available with the registers. I must save them so that the registers can be then used for this procedure invocation and what my return addresses are and then after doing all this I then jump to building of the procedure and start executing the code of the procedure. So before I start executing code of the procedure I need to do a lot of things to set up the environment for calling the procedure and basically these things are the ones which need to be then which is what is known as the runtime system and generate code so that runtime system can effectively start utilizing this input. So procedure calls now as far as 3 address code is concerned what was the 3 address code I had for the procedure functions. So just to remind you what we have were two instructions one was a parameter where I said that t is a parameter and then another was etc. called id with some n where I said that I am invoking a procedure id with n arguments. So these are the only two things I had and rest of the things are going to be part of. So this part is the part of all the evaluation and this is really the part where I say that I need to create all these parameters and then I need to jump. So this is really the fourth part. So these are the things we do that we look at parameters we need to know whether parameters are being passed by reference or are being passed by value. There are many other mechanisms and we will look at what are the parameter passing mechanisms. So when I invoke the procedure I need to know what are the parameter passing mechanisms I have and pass by reference is going to be little more complex than all by value and therefore we need to go into details of more details of all by reference. Storage then I need to worry about whether I am going to statically allocate the storage or I am going to dynamically allocate the storage. Now some language is required that storage will be allocated statically and some language is required that it will be dynamically. You know of some examples of languages where I have dynamic allocation and static allocation. So for example in C is procedure allocation is static or dynamic. So if it is static what is going to happen is that if I have procedure p suppose I have function f1. So this is the allocation I allocate f1 on the stack. Now suppose f1 calls itself, f1 recursively calls itself what happens to all the local variables. Do I need to be initialize local variables in recursion? Yes, no. We do that how we do it in static allocation because this is the fixed storage for f1 and how many instances of f1 can be there on the stack? Potentially infinite depends on the recursion and therefore actually in C the storage is not static it is dynamic. So whenever so if you look at any language any modern language if you look at all class of languages this allocation for procedure is always dynamic. If you look at languages like portal, a portal started in static allocation that you can have a local variable you can exit out of the procedure that you can come back and you find that value of local variable is still available but then recursion is not possible. So these are the kind of questions we have to ask when we are dealing with procedure calls that whether parameters are passed by difference or not whether storage is statically allocated or dynamically allocated then I use all these arguments like then it says that what are the placeholders for the arguments I have? So these are really the placeholders for actual parameters then I call a procedure and we say that we are going to pass pointer to the first argument and saying that I have an argument being passed this particular procedure and pointer to any argument can be obtained by just using the proper offsets because if I just pass the argument to the first, pointer to the first argument then pointer to the arguments we calculated by number of bytes it takes. So when I start doing code generation and this is code generation only for this part and not for the things which is initialization of the static. So this part is actually fairly straightforward that I want to generate free address code and free address code means that first if I have an invocation like this first I will say that have code for evaluation of X plus Y and if once this code is generated there will be some location which is associated with this expression and then I will say that I have parameter T where what is T? T stores value of X plus Y. So this way I will have all the spaces for all the arguments and then I am going to generate a list of parameter which is three address statement and then store arguments in the list okay. So basically all these parameters are the arguments and then when I pass this particular instruction which says all ID list okay that time what will I do that I will say that for each item which is in the queue I am going to emit this instruction okay which is parameter instruction and then finally I am going to emit which will say that all ID which is this and I have now an argument to the list of parameters okay. So this is actually the much simpler part okay. So there is nothing more complex than this whenever I pass this I am saying that every time you have an expression here then you just append it to E place okay at the end of the queue and this one when I see the first argument I am just saying that I initialize okay. So this part as I said is pretty straightforward all I am going to do at end of these activities that I have code for expression evaluation okay and this will then after this I will create a list and then I will generate from the list these instructions sequence of these instructions and finally I will take the code with this function okay. So that really is not a complex problem okay. So for example now so let's take an example suppose I say that I want to invoke F1 where say X plus Y A plus BC okay this is what I want to invoke what is the kind of code I will generate for this I will say that T1 is X plus Y T2 is A plus B for C I don't require a temporary variable that is going to be right there and then I will say instructions like parameter T1 parameter T2 parameter C okay. So these are the three instructions I will generate from this particular Q which has been created of arguments and then I will say after this all F1 okay and what will I pass here either I can say that pointer to this and three arguments or if this list is there then I just pass this pointer to the list and I am done okay. So this is really the code generation for as far as this part is concerned but if you recall I said there were five six steps and this actually corresponds to the last step the first two steps I have not even looked at okay so what are those first few steps okay first few steps are actually part of what is known as runtime environment. So what is going to happen is let's understand what is happening in procedure invocation why procedures are treated slightly differently and our special cases okay one that I do not know whether a procedure or function is going to get invoked second thing I do not know whether it is required space so normally what is done is that no space is allocated third thing that happens is that for all the variables if you look at local variables I do space allocation once okay but for all the local variables of procedure I may have to do multiple allocations depending upon how many times they are invoked and in which environment they are invoked. So suppose a procedure is invoked recursively and n times regression goes deep n times then I have to do n coefficients of all those variables okay and therefore I do all that activity at runtime and not at the time okay but I generate sufficient code so that that code gets executed whenever the program is getting executed okay so that is what my runtime environment is so runtime environment basically is code generation strategy for the co-serious function and the second issue which will come as part of runtime environment is that at some point of time I will also do dynamic allocation of variables now many languages do not support dynamic allocation of memory but many languages do so when you have dynamic allocation of memory how do I allocate space at compile time I cannot so when you do a malloc for example you see and you say that allocate 512 bytes okay somebody has to then allocate that space to you okay it must be in your process space if it is not in your process space you cannot even access it okay so two things have to be managed by runtime environment one procedure function calls space for procedure function at runtime and second dynamic allocation of memory at runtime okay so that is the kind of code generation strategy we have so this gives me runtime environment is basically giving me a relationship between name and date of date of the target machine what does that mean this is now saying that suppose I say this variable X okay now where is this variable X this variable X will be somewhere in memory and different executions of this program will put this variable at different places so runtime environment will give me this mapping saying that every time I want to access X I should go through symbol table and symbol table will only give me an offset but not the base address and then I actually go through my page tables and access this every time I load this data into memory this mapping will keep changing okay so runtime environment is the one that is going to give me this relationship between the name and the data object of the target but runtime support package so when you do a manner and when you free the space okay that time this all this code will come into picture okay and then what we say now is that whenever I execute a program we say that or whenever I execute a function of procedure we say that I am actually putting an activation on the stack or I am saying that a new activation corresponding to that particular procedure is being created okay so what that means is that if procedure is recursive then a procedure may have several activations which are like so for example I just gave you this example that suppose I have a situation where I have inside f I again have all at one okay now depending upon how deep this procedure is called that will depend upon the conditions and the argument but what can happen is at the first time some activation of f1 is going to be on the stack and then next time it is called another activations and I keep on creating these activations of f1 on the stack okay and also the space for local variables every time will have to be replicated and then depending upon again which activation is currently being executed values of the local variables will keep changing in different stacks so if I am suppose this is a current execution and there is some local variable x whose value is changing or let us not confuse with arguments suppose there is some local variables that here whose value is changing in this particular invocation it will not change here right it will only change in this particular activation okay so this needs to be then managed by some time support okay so what we say is that if procedure is recursive there are several activations which may be alive at the same time so this is one sets of local variables and set of arguments and the set of machine statements and now we say that if there are two activations a and b two activations are different of the same procedure okay so a and b could be activations of the same procedure or they could be activations of two different procedures does not matter so beyond this point when I start looking at stack I do not really distinguish between the procedure name what I say is that each time a procedure is invoked and activation is created and I am only looking at now activations okay so now we say that if a and b are two activations then either their lifetime is going to be non-overlapping or it is going to be nested what does that mean what that means is that either a will start here some lifetime so if I just go around the timeline and my program is going to be I will say that lifetime of a starts here and ends here and then b starts here and ends here or it could be nested that means lifetime of a starts and then lifetime of b starts here and ends and a continues I will not have a situation where I say that a starts here and then b starts somewhere and then a finishes and b is continued what that means is that b was invoked by a but b is continuing and a finishes that's not possible okay so only two situations can occur either you have non-overlapping lifetime or you have nested lifetime these kind of lifetimes are not possible for the activations here okay so a and b are activations of two procedures and the lifetime is either non-overlapping or is nested a procedure is recursive if you can have multiple activations of the same procedure at the same okay these are the only two things we need to be concerned with nothing okay so again now coming to the definition of the procedure once again okay our abstraction for procedure is going to be now slightly different for the old generation purposes what we are saying is procedure is nothing but a declaration okay so procedure is declaration of the name which returns the value of certain type and which takes a list of arguments what about the body of the procedure that is a statement which is associated with the procedure that needs to be executed okay so header has to be treated differently than the body now we have already seen how to do coordination for the body part okay so that is really of no issue anymore the only issue is of the header okay and that has to be treated carefully so procedure definition is a declaration that is meant to associate and identify with the statement which is the procedure body so when I look at this FXY I am only really interested in this type what is the return type of F1 what is the procedure name what is the argument list and what is the type of each argument okay what about the body part body part we know is just going to report and we know how to handle that okay we have already done coordination for that part okay and whenever a procedure name appears in an executable statement then we say that it is going to be called at that time so when I say that all F1 this is where I am calling it and this is really the declaration okay and I also have what I know what we know as arguments or formal and actual parameters so whenever I have definition like this I will take that these are my in definition these are called formal parameters and when I invoke so when I am invoking it for example with this so this definition I cannot have X plus 5 kind of situation here but suppose I say I am invoking it with 2 plus 3 okay so this is my formal parameter and my actual parameter is this expression 2 plus 3 okay so I am formal parameter and actual parameter these are standard definitions you will find it any text one programming language is in compliance so actual parameters are the ones which appear in when procedure is going to be called okay now I want to keep this information saying that in which order these activations are to be created okay so I am going to create few data structures we need and the first data structure we look at is activation piece so activation piece basically saying that how control is going in my program when procedures are getting invoked okay now whenever you think of a tree you immediately can see that what are the sub parts of a tree you have to have roots root nodes you have to have the leaf nodes and you have to have the inner nodes okay and then like if I have definition of each of these then I know what tree is okay so the root corresponds to the invocation of the main program and then each internal node corresponds to invocation of a function of procedure and what is the leaf node leaf node is the one which does not invoke any other function just execute something and returns control but internal node is the one that is corresponding to invocation of another procedure of function okay now what about edges okay edges are telling you that which function of procedure is invoking something else okay now that is a standard part of this tree definition okay in activation when we talk of activation we will also talk about left and right systems okay so we will say that in this order okay if I have two activations so execution of procedure starts at the beginning of the body and it returns control at a place where procedure was called okay and a tree is the one which is used to depict this situation so root represents activation of the main tree each node represents activation of a procedure and if node A is parent of node B then we say that control closed A to B okay but now I put another condition which says that if node A is to the left of B then the lifetime of A occurs before lifetime okay so if I have a situation like this what this means is that corresponding to this suppose this is where my invocation of main and then this is lifetime of A and this is lifetime of B this is how the tree is going to look corresponding to this particular procedure okay so left and right sibling relationship is telling me that what happened earlier and what is currently active okay so this way I can capture the full information about the control flow in my program in which order my procedure will go okay so I am not going into the body of the procedure but I am interested in looking at the call graphs and the headers okay of the procedures this is what I am capturing the activation tree information okay so let us take an example and try to create an activation tree for this so here is some code where we say that I have this sort program and then this program we have seen earlier like quick sort we also looked at when we are creating symbol table for this okay so we have this procedure read array then I have a function which is partitioning which is taking two arguments y and z of type integer returning the type integer value which has its own local variable and then again I have quick sort and within quick sort I call partition which returns the value then I interstitially call quick sort and in the main program I first initialize my array and then call quick sort okay now can we create an activation tree for this program okay so let us try to create an activation tree tell me how we will activation tree for this so let me erase this part and let us start drawing the activation tree so it is clear that the first thing will be the sort okay and sort is calling the read array and after read array finishes then I am calling quick sort one nine okay and when I go to quick sort then what do I do I call partition so this calls partition with one nine and now what what is the next thing that happens what is the next node I draw what is the next node I draw quick sort with so first question can I get an activation tree for this program just looking at does it have a unique activation tree if I do not have a unique activation tree what is it that I am drawing so that will be the first thing you should object to if I actually do not know what activation tree for this will be it will depend upon the data I have right so there is nothing unique activation tree it will depend upon the data you supply so activation tree really does not belong to the program I cannot really create it to compile that only when my program is executed at that point of time I will create an activation tree and for different data sets the same program will give me different activation trees right so activation tree is not just the property of the program it is property of then this program gets executed with certain data sets so that is the first thing you have to remember we are talking about now how long we are talking about just with the pipeline so assuming few things that some data is being returned this is how the activation tree may look but this is only one of the instances of activation tree for different data set activation tree could be different that I will first call need array and then I will call quick sort which is going to call partition and now assuming that partition returns value 4 but that is the property of the data so assuming that partition returns value 4 then I am going to call quick sort 1 and then quick sort 1 is going to call partition 1 3 which again lets assume that it returns value 1 I do not know what it will return for a different data set I am going to call quick sort 1 9 and then I am going to call quick sort 2 3 and so on which will again call partition and so on so this is how the control may flow in this particular tree so first thing you have to remember here is that this activation tree is corresponding to that program for a data set and it could be different second thing is that at some point of time you will realize that I do not have to remember the whole this tree now lets look at some random node in this suppose I say that this is the current active procedure that I am executing partition 5 9 if I say that this is the current activation procedure then from this definition when I created I said that left signaling and right signaling what are the procedures which have already been executed and what are the procedures which are which have not been executed and what are the procedures which are currently executed by looking at this tree in this particular data set if I say this is the currently executing procedure what are the procedures which have been which have finished execution so actually all this has finished execution this part is get to execute but these are the current active procedures so if I just take the path from root to this particular procedure that gives me all the procedures which are active everything on left of that path is already inactive they have finished execution and everything on right of that is get to be created so I will only be interested therefore in knowing my current path and knowing therefore which are the current procedures which are active procedures which have finished execution are of no consequence beyond that part and therefore I do not now need to remember the full tree I only need to remember that current is what is active it is what 1 9 is active 5 9 is active at partition 5 9 is active this is the only thing I need to remember and for this obvious data structure we use this stack so what we can do is and every time an activation is called and activation is created I push it on the stack every time it finishes I pop it from the stack so if I then therefore look at this activation tree and say that this is on top of stack then I know immediately that below this this is on the stack below that this is on the stack below this this is on the stack and nothing else like this on the stack this point is clear so what we are using is control stack it says that flow of control in the program corresponds to really this that first traversal of the activation tree and we use this stack called control stack to keep track of only the line procedures not all the procedures so we are only interested in the procedures which are currently lying and I keep them on the stack and then we say that whenever a node is an activation begins you push the nodes on the stack and after it finishes node is at the top after it finishes then I pop it from the stack and if node n is at top of stack then stack contains the nodes which are along the path from n to the root right okay so these are the only activations I will be interested in and not everything else okay so continuing on this information okay now let's look at that how do I capture scope information now scope is something which will keep changing because of front-end bindings so if I say that this is there is some current procedure which is active and I am looking at variables within that then binding of those variables will be determined by the scope rules are now if I look at scope rules okay there is something called lexical scoping or syntactic scoping which says that I can determine all my scoping rules by looking at the program listing I don't have to worry about execution of the program and then their languages will say that scope is going to be so we look at both static scoping or lexical scoping as well as dynamic scoping so let's start this discussion with assuming that I have lexical or static scoping so declaration is syntactic construct which associates information to the name okay so first thing that happens is you have to take every class of languages all these are going to have an explicit declaration of a name and therefore a type associated with this okay so you will have something like a variable which will be a keyword in this language okay and followed by a name of an identifier and a type name or you have languages like Fortress okay where you may have explicit declarations but you may also have implicit declarations okay now I am not dealing with languages which are interpreted so their languages which are interpreted and which again have implicit type names okay but since you are not dealing with interpreted languages we are only interested in compiled languages at this point of time therefore I have picked up this example if you look at languages like basic and Python and so on okay there also declarations are implicit but then they are interpreted okay so we will leave that for the time okay because then that includes something else okay so there what happens is that although declaration is implicit but there is some assumption which is made okay so assumption for example Fortress makes is I, J, K, M and O are or any variable starting with these letters they are integers and any variable starting with any other letter than these six is real unless you explicitly declare it okay and in fact most of the time you will notice that when people write programs this tradition for some reason continues because when the initial Fortress programs are written I was the first integer variable or first letter which was associated with an integer variable and therefore if you see everywhere everyone writes for I1 to N okay because it was very simple thing to do important and therefore other languages other programmers of other languages have picked up this tradition so even now when you write something in C or in basket you still say for I1 to N where I may be a totally meaningless variable okay most of the time people will those who are in software engineering and are worried about quality testing of program they will say that your counter name should be meaningful name okay but people continue to use I there I will be totally non-descript name just associating an integer with it okay so I is assumed to be an integer in languages like Fortress and there may be independent declarations of the same name in a program so what may happen is that same variable X can occur at multiple places in the same program but in different schools will differentize this okay so I need to worry about as compiler writer that how do I associate this variable with the right scope because if I just say X is meaningless unless I say that X occurs in a particular scope okay so there may be independent declarations of the same name in a program that is because of the scope rules and scope rules are the ones which determine which declaration is going to apply to a particular name okay so we need to know this and how does name binding happen at some pie time and run time okay that you have something like a name and a scope range association okay how do I find out which name associates with the scope range that is provided by the environment that means this is provided by the scope okay but what is the value associated with that particular scope range that is provided by the state of the program and the program is executing at that point of time the value in this particular location will be changed okay so this finally comes from the environment and we are only interested in this finally okay so we need to see how to deal with the environment how to deal basically scoping rules to make sure that I am always able to find the right binding once I have allocated a space to this then I can always actually go to this particular symbol table find out what is the address and then determine what is the value in that particular location okay so this is very important that we are able to for each name we are able to bind environments with it so that I can go to the right scope okay this here I mean what is this figure is kind of definite yes okay so let us look at now when I say that I am now creating space for a program okay so when I say that I compile a program some space gets allocated to my process okay now what are the things what are the kind of parts I have in my program okay so I obviously have a target code okay then I have data object so this is the machine code and the data object and then I need two more parts okay where one where I can grow my stack I can have information about the procedures and then I need one part where I can keep all my time in data structures okay which is the heap okay and if this is a total space which is available to me normally you will say that my code and static data I am doing here at the beginning of this allocation and then stack and heap will start going towards each other from two different types okay and this obviously data structure has an obvious advantage okay that if I if I change this data structure for example and rather than fix space for stack and heap what may happen is that I may say that I divide this as code my data stack and heap okay and I say that stack and heap grow in this direction I can end up facing this space possible that my stack will not be full but heap becomes full or heap will not be full and stack becomes full okay but this data structure gives me an advantage because as long as there is some space available either stack or heap can grow okay and now this should also give you a hint now that if you write a program now many times you must have seen these messages that the program is getting executed and then suddenly you say stack overflow what that means is potentially you have gone into an infinite recursion and beyond this stack is not going to grow and say that I have run out of stack space or it says heap overflow that means you are allocating too many dynamic data structures and you are not freeing it and at some point of time you go and get this boundary and say that beyond this your heap is not able to grow okay and this is always a finite state okay it depends upon the model what does it depend upon so most machines today we will say that whatever is the address space you can use all of that okay if you have a 32 bit machine then I can use this total of 4 gigabytes of space for this okay it depends on the address space okay but there are some machines which will restrict saying that each process can have only limited space okay so it is determined by really the operating system okay so that is how we are going to lay out so now we have seen part of this how do we generate code we have seen part of this how do we allocate space for static data we haven't seen this and we haven't seen this so basically in my runtime system we need to deal with how to manage stack and how to manage these are the 2 things we need to deal because if I can deal with this then I know how to manage all the space which has been allocated to okay so what we are dealing with is that this part static data was allocated and all this information was kept in the symbol table code generation we have already seen how to do code generation but this is the part we have not yet seen and therefore we are now getting into this part so first thing we will start with stack and then we will look at the need part to start with stack the first thing I need to know is that for stack management what are the things which are getting allocated there we need activation records so I first must know how my activation record looks and then only I will be able to manage my stack part so how does my activation record look what is the kind of information it contains so first let me give you a layout of my activation record and then we will discuss each of these so this is how a typical activation record in a program may look what are the spaces you put in this activation this is not in any particular order we will discuss order slightly later but this is the information you are going to put in each activation so I have space for temporary release so basically what will happen is that if I look at some port in the procedure I need certain temporary locations to evaluate all those expressions and I put some space for all those temporary locations then each procedure and function is going to have certain local data and I need to put all the information about all the space for local data in this activation record also I need to return certain values so I need location where I can put the return values and I need location where I can copy all the arguments so these are really the parameters now what about this I have these machine status then I have access link and I have control link so if you look at this so this part and this part actually relates to the body of the function and procedure but if you look at this part machine status what it means is that each machine is going to have certain resources so for example suppose you say that I have 16 registers now registers are also going to be used for temporary locations so some registers are like PC value and status registers and so on they correspond to the program but when you now say that I have registers for temporary locations and procedure goes B and A is keeping certain variables in that case now as soon as control comes to B you know that code for A will not get executed and therefore if you keep a register still bound to variables of A you are actually wasting a resource so what I can do is before I start executing B I can say say values of all the registers which can be free and after I finish execution of B I can go and copy those values back into the registers and continue execution of that case so I need to save information about the machine status I need to save all those resources I need to have some space where I can save all those resources so this really is the space for saving all the machine status and what are these links access link is the one which tells me that from where do I get scope of a particular variable so when I say that use a variable X access link is going to tell me that this particular value of X can be found so it could either be in the static data or it could be activation of one of the procedures which invoke and the control links tell me that which procedure invoke me and where the control has to load I so typically this is the information I am going to have on activation interface and every time I create a procedure I invoke a procedure I need to create this data structure initialize it and push it on the stack and every time a procedure returns control I need to copy these values back into the parent activation and then DLP so now I mean if you recall we started with by saying that procedure corresponds to an activation so you can see that what this activation is also it does not have any code it is only dealing with the headers and the data okay procedure code is going to be where is the code of procedures code and I go back to in this where do I store the code for procedures is it in the stack or in the code area procedure has a body corresponding to that I will have a machine code where do I store that in this particular code area or the stack area that code is in the code area stack area only contains the data so stack area basically corresponds to the data which will be active by my procedure is executed so all the variables corresponding to the procedures are going to be here but all the code corresponding to the code is the main program as well as all the procedures that is going to be here so code will all execute or in this case so that is what you have to remember that we are code is and we are data so this is how my activation record and now what are the issues I need to worry about when I am designing my activations and when I am designing my activations access link at this point of time only thing I can explain at this point of time is without going into details so look at a situation like this so suppose I say I have a main program and within main I have let's say I have in tie here then I have in tie here and then within this so let me deal with first the language is not like C but which have deep nesting of two series of functions so within this suppose I have now a declaration of a function let's say float F with its own argument list then the body of this float and here I say X is the sign I plus 5 okay and I not declare it in F suppose I have a program now when I am trying to access I from where do I get this value of I I need to know the location where I is I is obviously not in my local scope it is not in local variable so it will not be in my activation but it will be in some other activation it will either be in this activation or it will be the static activation okay how do I access this now I don't know how many times F has given you okay so my stack will look something like this I will have some so let's say code and static data is here okay and after that somewhere I have activation of F and when I am in this activation that time I say I want to modify this I want to assign to X whatever is value of 5 plus 5 how do I access I okay so activation record is basically saying that I now have enough code to say that I must have when I created this activation of that I must have created a link saying that because of my scope rules this I is coming either from this or from this okay so suppose this was not I this was J then I am saying that this I is actually a global variable and therefore I must have a pointer to that this pointer basically is nothing but access so whenever I am pushing my activations okay I need to have these accesses that's the only thing okay but it is off saying that how do we create accesses okay but this is the basic definition of access which tells me that using the scope information which variable can be accessed and which variable cannot be accessed so how do I have language that has been nesting you mean a language like JavaScript any language you say is nested procedure I will go in fact even C C NCC does not have nested procedures and right actually nested procedures in C and use GCC to compile with him but I mean we should not be writing those kind of programs because those are not standard programs but GCC works for that all the algorithm class of languages will have this okay including modular over on Pascal objected in object C and so on they will all work nested deep level of nesting deep level of nesting is basically saying that nested procedure inside a procedure in C you can in Java you can right okay so I think so before I will take up the next topic I think we will have to wait for the next class so let's stay here today and next class we will start this system


The cellular prion protein, PRPC, consists of a natively unstructured N-terminal domain, which includes an optorepeat region, OR, and a linker, followed by a C-terminal domain that misforms into PRPSC in Kreutzfeldt-Jakob disease. PRPC beta endoproteolysis to the C2 fragment allows for PRPSC formation, while alpha endoproteolysis prevents its formation. To examine the OR, researchers design new alleles, S1 and S3, which were locked in extended or compact conformations, respectively. These alterations resulted in PRP that resembles wild-type PRP in supporting peripheral nerve myelination. However, prion-infected S1 and S3 transgenic mice both accumulate low levels of PRPSC and infectious prions, but with different clinical presentations. Surprisingly, S3-PRP overproduces C2 fragments in the brain through a mechanism distinct from metal-catalyzed hydrolysis reported previously. It was concluded that OR flexibility influences various biological outcomes, and can either decouple or engage. This article was authored by Agnes Lau, Alex McDonald, Natalie Dawd, and others. We are article.tv, links in the description below.


Let me give you a tease of my reaction. Oh man, I'm so funny. They call me funny man Logan for no reason. I don't know why they just call me funny man Logan. Okay, come on, give me a break. Where's my cap? Okay, gonna find my cap, but will this be good? Should I do my reaction video with this on? Oh, you actually can't. I mean, like, the colors are pretty cool. But I'm just not sure if it's good for the video, you know? What about this? Nah, it's not St. Patrick's Day. Where is my cap? Huh? I was so tempted. See that? Right, right there. That's my cowboy hat. I was tempted to grab that, but that is made out of genuine kangaroo leather. So I just, I can't. But I did. So we're going to do our video with this. Should we wear our goggles as well? No, no, no, no. We'll just, oh. Anyways, today we're going to be reacting to Harla Harla MV.  Can we just talk about how great ATEEZ is? Holy moly guacamole.  They are insane. Okay? Like, they are insane. I'm not sure if emphasizing pulling on the string doesn't anymore work, but it's like the anime zooming lines, you know? But it's with some string. And I also got some steampunk goggles. Don't ask why. Well, maybe I did a steampunk. Cowboy reaction video one day. And just for the memes because people were doing random titles in their videos, you know, and I don't worry about it. Anyways, ATEEZ.  Okay, I already knew it from the KQ Fudders from music video. When, like from the first show, I reacted to that. I was like the first person to freaking react to that. I didn't react to the performance videos because I wasn't too sure about American music, what the copyright thing would be like. So I didn't react to those. But I did watch them as soon as they came out. Okay, so I've been knowing these guys for so long. Don't know their names. Actually, I want to learn their names. Actually, I know too. Mingi and Hong Hong. No, I just know Mingi. The leader's name has gone out of my mind now. So I just know Mingi. But anyways, these guys are insane. Hala Hala is insane. I have been listening to ATEEZ's music so much. When I'm driving to work, I don't care what people think. I'd be blasting freaking. I was about to say cakey photos. But I've been blasting ATEEZ so much on my way to work. You know, we freaking say my name, desire, Hala Hala. Even their freaking first mini album debut mini album. We've been listening to that a lot.   I want to learn the members. I want to react to a lot of videos from these guys. So if you guys have got anything from them that you want me to react to, What's your thoughts on a cowboy drinking frappe from McDonald's? No, I want to try a cowboy voice. Yeah, you know what we're going to be doing today. But yeah, guys, I think that's been straight into this. I'm pretty excited. I hope you guys are too. Let's do this. ATEEZ. Yeah. Oh. Oh, my ssss. I would let them destroy me whenever I want. Oh. That's what Mingi was like. Split singing that Mingi was there. Oh. Why do I feel like I'm just watching the teaser? Wait, did I just watch the teaser? Okay, I didn't.  I'm excited. Oh, they just look so badass. Like, this is mafia level 10 million, man. I wish I could sing. Deep inside. Oh. That's when you're learning how to hold up. This is freaking lit. Dude, even when they're like walking like that, they're awesomely, awesomely awesome. I love the song. Oh, my God. Them legs. It's me up there. Mingi. This is my Mingi. I know my Mingi. I need to learn the rest of the members, though. I'm a fan of them. I want to be a stan of them. Thank you, man. Dude, this guy's voice, though. That choreo. That walk is like the coolest thing. Just like that walk in Samo name. That walk. I can fall in love with their walks. I already have fallen in love with their walks. Oh, man. Don't spray me. Oh, my God. That was so cool. Oh, that was actually so sick. That transition of just spray painting it and then putting a red overlay onto the... Oh, dude, that is lit. That is lit. Wait, no. Don't be fit. We get it. You slay. Oh, my God, sis. He slays. Oh, my God. Can you feel that? Can you feel that? That's the feeling of the feels of the feels. That was so legitimate. Awesomely awesome. Okay? That was legit. Like... It can make you just go like, Nani? That was... That was... Yes. So, I got to upload my straight to the reaction after this. But tomorrow should we do... No, tomorrow is an IU reaction. The day after, should we do a tease reaction. So, everyone, comment down below what a tease video you want me to react to next. Okay? And also, if any of you guys like League of Legends, go check out my gaming channel. There'll also be a link in the description down below. So, click on that. And yeah, I'm in that. I hope you, my doofies, have a great day and just keep on smiling. And I'll see you, my doofies.


So, uh, I ordered some air tags on Friday. I really raced off to my chiropractor.  I didn't order air tags because I saw it like on Facebook, somebody posted their order thing. So I ordered them and I ordered a four pack and got lucky because I was able to get in like, I don't mind. Don't arrive on the 30th. They arrive on May 3rd. So not too bad for, you know, snoozing. Did you order some air tags, John? Yes, I did. It's kind of a weird experience. I'll just describe what happened here. So I just want to hear your experience. But when when do yours arrive? Do you get yours on the 30th? Oh, I can check. Yeah, I think the 30th is when they're coming. OK, so you got you got your order in before me. Did you order a four pack? Yes. Cool. Awesome. All right, yeah, same. Yeah, four pack of them get things rolling.


So I joined the Air Force because I couldn't afford school and then I was in a rough time of my life where I needed an escape I guess maybe, but it turned out the Air Force to me wasn't just going to be about the school, it turned out to be much more and now I really enjoy it. So I just hit my two year mark, entered August 1st, 2017 and I am an Airman 1st class. The title for my job is Maintenance Management Production, if AFC is 2R1X1. I entered in with an open contract and picked it out in basic training. Honestly I had no idea what this job was but after getting a little more into it and going to my first space and seeing what I do I'm like wow that's a pretty big job so yeah now it's something I really wanted to do. I'll be honest I really wanted a medical job like dental assistant or surgeon assistant I was like dang I could probably get a really good job right after the Air Force if I really wanted to get out. I signed a four year contract because in my mind I was like oh I'll just do school, get out but I really wish I signed a six year contract but it's all good. My tech school for the job was at Shepherd Air Force Base in Texas I think it was Wichita Falls, yeah. Tech school for me was only about 33 days but they cut it short at 29 I believe because it was around the time they were trying to send us home for Thanksgiving so ended up being only about 29 days so we got kind of lucky. I at first tech school was a little awkward you had one half of you that had some freedom the other half was still tied down because of the MTLs but honestly I really enjoyed tech school the school part I mean you fell asleep less sometimes but it was just the friends that I made they were really cool I met so many different people from different places learned so many new things and like I would honestly go back to that just to like see the friends again because they're really people that I'll remember for a long time. So with my job since we handle all aircraft we can be stationed anywhere. So as a maintenance management productionist or a scheduler they might call us PSND we are required to create schedules flying schedules for the aircraft that we're stationed with will be required to make a weekly schedule a monthly schedule and a quarterly schedule obviously a weekly is every week a monthly is every month and accordingly is every three months so much with computers again it's gonna depend on like where you're at like with me I'm at the 855th rescue squadron at Nellis Air Force Base so since we're a rescue squadron obviously our helicopters deploy a lot and that case we deploy with them very often probably twice a year I believe but again it just depends on your base it depends on your aircraft where they go and so on. I'll be honest when I first joined it was just the four years and that's it right now it's like I'm planning on re-enlisting but I can whenever I think about 20 I'm like damn but right now I think if I were like on a scale 1 to 10 I'll probably be on a 6 towards the 20 year retirement so yeah honestly like I said I was trying to go for something medical I wouldn't mind doing that now but now that I know this job and understand it a lot more I really enjoy the job now and I really don't mind doing this for the next who knows how long so you can probably hear the basic answer from everyone like oh volunteer go to school go do this go do that but honestly like with me what was important to me first was learning my job and then I wanted to volunteer and then do the other stuff because if you're pushing for people to like volunteer and do other stuff besides your job first it's gonna be hard for them to be juggling everything at the same time because you're trying to learn your job you're trying to volunteer you're trying to do everything so and honestly just take your time like learning your job first and once you get that down then go for it go go volunteer go do ace try to get that btz package you know just stuff like that my Instagram name is horde.via98 that's j-o-r-g-e dot v-i-l-l-a 98 thanks


I guess I would like to thank you all for coming. My name is John. I'm here to talk about the kernel and I will start kind of as I often do just by talking about what the kernel community has done recently and then get into the more interesting stuff after that. This is what the release history looks like over the course of the last year. You can see that we have put out six major kernel releases since October of last year. Each one of these is a major release incorporating all kinds of new significant features.  It's really the same old chart that I put up every time I do this talk. It doesn't change a whole lot. In fact, I could putting up high tide times or something like that and be imparting about the same amount of information. But it is worth pointing out that 6.2 released back in February set a new record for the number of developers participating in a single development cycle. We had almost 2100 developers adding code to the kernel over the course of about 9 or 10 weeks. That's a lot of people working with our community. And although the number of developers has subsided a little bit since then, it tends to go up and down. I don't really doubt that we will set another record sometime in the near future. That last column that I've added there is the number of first-time developers participating in each development cycle. So we see that we're getting somewhere between 200 and 300 first-time developers in each development cycle. We have that many people coming into our community and adding their first patch to the kernel. So we still have a healthy flow of developers coming into our community, which is a good thing. As long as that continues, I believe the kernel community itself will remain reasonably healthy. So one other thing to add on to this chart, of course, is the 6.6 kernel, which is currently under development. These are numbers from a few days ago as of the RC1 release. This kernel can be expected around the end of October. Has already merged over 12,000 change sets. We'll see that probably approaching the same 15,000 number by the time it's done and all the bug fixes go in. There's a lot of interesting work in this kernel as well, including some major changes to the CPU scheduler, which we haven't seen for quite a while, and an awful lot of other stuff. So there's still a lot going on in the kernel community, really kind of business as usual, though. These, of course, are our mainline releases. These are the releases that Linus Torvalds puts out before he leaves the building and goes on to bigger and better things. But these are not the kernels that most of us are actually running, right? Some of us run mainline kernels, but most people are smarter than that and try to run something else. So they're usually running something based off the stable kernel updates. So this is the current status of the long-term stable kernel updates. There are six of these updates under long-term maintenance going all the way back to 4.14, which was released almost six years ago. You can see that we get a lot of updates, over 300 of them for 4.14, and many, many thousands of fixes going into these kernels after they are released as a mainline release. So the volume of these fixes is an interesting concern in its own right, and I'm going to get onto that in just a moment, but I want to use that sort of as the transition to the main part of the talk, which I am focusing this time on key questions that the development community has to answer over the course of the next year or so. I think there's a lot of things that we need to talk about, a lot of things that we need to figure out, and so that's what I'm focusing my talk on now. So with regard to stable updates and things related to it, the first question that I want to put out there is, what should our users actually be running? Because I've just said that we aren't running the mainline kernels that Linus is putting out there, right, that we're running something that is further developed, at least further refined after that. So one answer to this is, if you're going to tell somebody what should you run, tell them to run the latest stable kernel update, because that is the most stable, the most secure, the best kernel that we in the kernel community know how to create at this time. It's the very best we can do. So you should run that. This is a position that is becoming increasing in the common within the kernel development community itself, that those are the kernels that people are running. This is a quote from Greg Kohartman, who is the manager of the stable kernels, saying that you really have to take everything that comes into these updates, all 20,000 or so fixes, because otherwise you will not get all of the known fixes. You will have known bugs. You will have known and unknown security bugs. The only way to avoid that, the only way to get the most secure and the most stable kernel is to run these updates that the community is putting out there for you. So you can do this, but this raises some interesting questions, because if you look at this, right, the number of fixes here is not small. 4.14 has, at this point, these numbers are actually about two weeks old when I made this slide. So 4.14, I think, is probably approaching about 28,000 commits to it at this point. That is two full development cycles, full of changes added to an ostensibly stable release after it was released. So there is an awful lot of development, in a sense, going on after our stable kernel has already been released. That is an awful lot of changes and that raises some eyebrows somewhere. I did some looking to see where these bugs are being fixed are coming from. This is a little bit small, I am sorry, because it covers the entire Git history, but way up there at the top is a line saying that of all of those 28,000 fixes that went into 4.14, about 1,400 of them were fixing bugs that were introduced in the 4.14 development cycle itself. Everything else came from a different development cycle, mostly previously. So you see this long, long tail of releases here. Essentially, every kernel release we have ever made during the course of the Git history has introduced bugs that were only found and fixed sometime after the 4.14 release. So a lot of these bugs stay around for a long time. This bottom line here, that says 2612, really covers everything that was introduced into the kernel prior to the Git history beginning at the beginning of 2005. So those over 200 bugs were introduced in the kernel at least 18 years ago and took that long to be fixed. So there is an awful lot of bugs that work in the kernel for a long time before finally turning up somewhere and needing to be fixed. All of this stuff gets scooped up and put into all of the stable releases when those come around. So if you are running a stable release, you are getting all these fixes for all these bugs that have been introduced over the course of the kernel development history. And there is value to this. Android has been pushing very hard towards its generic kernel image and has been basing those on the stable updates and has been trying to increasingly aggressively track the stable updates over time. The people who are interested in Android security at Google are pretty good at their job and they are pretty serious and they spend a lot of time looking into this. And they have looked at the security problems that have been found in the kernel and how they affected the Android kernels. And what they have found is the vast majority of security problems that are disclosed in the kernel have already been fixed in the Android kernels before they are disclosed because the fixes found their way into the stable updates and were already incorporated before anybody knew that they were actually security related bugs. This is one of the interesting aspects of kernel development is that almost any bug can be a security bug and you don't really know that it is until somebody finds a way to exploit it somehow. So an awful lot of fixes go in and they are not marked as security fixes not because the kernel community is trying to hide its security fixes. I mean sometimes there is a little bit of sneakiness that goes on there that I personally don't like but most of the time it really is just that nobody knows that this bug is a security bug. It is only later that somebody figures this out and so the only way to protect yourself against these sorts of bugs is to put in all of the fixes. So this is what is happening here. This is how Android has benefited from it. But there is another side to this that you really cannot gloss over although some people perhaps do. And that is shown in the second chart here. This is a chart of the bugs fixed in 4.14 that were introduced in kernels after 4.14. So that bottom line there is bugs introduced in 4.15. The 4.14 stable updates that fixed over 200 bugs introduced in 4.15. And it goes on all the way up to 6.4 there. Now one might wonder how a kernel could be affected by bugs introduced later after it was released. And of course the answer is that these are bugs that were introduced by the fixes that were applied to later kernels and then back ported into the 4.14 stable releases. So another way to look at this is to say that if you are going to take a kernel and you are going to back port 28,000 fixes into it there is just no way possibly that some of those fixes will not contain bugs. You are going to introduce bugs. There is no way around it and then you are going to have to fix those as well. That is just the way of it. So we see this. We see that the older releases have more bugs. The newer releases have fewer of them. Now it is possible that we are doing better now at not introducing bugs. Our testing story in the kernel has improved considerably. All that we are finding more bugs sooner before release and so on. But there is nobody I think who wouldn't tell you that the reason that these lines are shorter for the newer releases is simply because those bugs haven't been found yet. This other chart tells you it takes a while. So that chart will surely flatten out over time. So we are introducing bugs as well as fixes when we put a lot of fixes into our stable kernel updates. And this really makes some people nervous. There are people who want to deploy a kernel somewhere, see that it works, and want to be able to apply updates to it without the fear that it is going to break. They fear that quite a bit and rightly so. And so this leads to the other approach that you see, which is to instead take an old kernel, stick with it, and only apply very carefully selected updates that you know fix specific bugs that you were worried about and ignore the rest of them. This is the enterprise kernel model, of course. This model too has some downsides to it. Here too, you end up with kernels that have thousands and thousands of patches applied to them, including usually the back ports of major features as well as bugs because even though you are running an old kernel, people want it to work on new hardware and things like that. So you get something that looks very far removed from any kernel that the community has released. You are getting something that is unique to this vendor and what they are putting out that completely isolates you from any kind of community support because the community has very little visibility in what is into these kernels, cannot and will not support them, and leaves you dependent on whoever it is who has done all of this work, whoever you are paying a support contract to fix problems in it. And this of course leads to problems because people want to run these kernels and not pay for those fixes. We have seen an awful lot of fuss recently about what certain enterprise vendors are doing with regard to access to their code and their distributions, right? And the fuss around right at Enterprise Linux in general. This here is what that fuss is about, right? I mean, this applies across the entire distribution, but a huge amount of that work is at the kernel level and the work that they do to make their special kernels, right? This is what a lot of that fighting is being driven by. So it is a model that works for people, but it is a model that has some real problems and is a model that is creating stress within our community. So just to conclude this section, I think that this disagreement is likely to go on for a while that we have not really adequately answered the question of what is it that is best for our users? What should our users actually be running? In the end, the users of course themselves have to make that decision. I think we are seeing a bit of a shift towards stable kernels, but it is far from a stampede at this point. So expect to see this going on for a while. And I wanted to make just one last note about the stable kernel updates. I put this list of six kernels here that have been maintained back about six years. That is what the stable kernel update, the stable kernel team have been doing for a while is maintaining kernels that far back. But they have come to the conclusion there is really no point in maintaining them for that long because people are not using them. So the six-year update policy on these kernels is going away. When 4.14 goes out of support, which is likely to happen early next year sometime, there will not be another six-year kernel name to replace it. So these older kernels are going to go away and we are going to likely go back to a world where the long term stable kernels are maintained for about two years and then after that people will simply be expected to update to a newer kernel, which we really hope to be something that is safe for them to do. It will be a jump for some folks, but that is really the way it is going to be because the usage of the older ones was just not being seen. And as the kernels get older, it just gets harder and harder to backport, fixes to them in any kind of safe and stable sort of way. So that is the change that is coming and we will see that start to manifest itself next year. So for something completely different. Can't do a kernel talk without talking about BPF these days. BPF, of course, is an internal virtual machine that allows code written for this virtual machine to be loaded into the kernel by user space and run in the kernel context in a safe sort of way. There's an awful lot of checks that are applied to this code to ensure that it cannot harm the kernel. These set is the hope. It is being presented in a lot of ways as a safer form of C. There's a lot of interesting makings that have been added to allow, for example, BPF code to acquire a lock and simply not and it must release that lock at some point and the verifier will ensure that it happens and if it cannot prove for itself that lock will be released, it will not allow the code to be loaded and run. So it applies an awful lot of safety features that makes it a safer programming environment than programming in straight C in the kernel. So there are other downsides as well. It can be a hard environment to work in. You're limited in what you can do and so on. But for certain kinds of things, you can do a lot. So there's a lot of things you can do in BPF now. Starting with packet filtering, BPF originally stood for Berkeley packet filter after all. So that's for you can load programs to select packets or reject them, that sort of thing. You can write TCP congestion control algorithms and traffic control algorithms, kinds of advanced routing using the express data path, a lot of networking stuff which is kind of the roots of BPF. But beyond that, you can do things like you can write drivers for infrared controllers in BPF. And once you have one of those, if you get a new controller, you just load a new driver, you don't have to build a new kernel or anything like that and that controller works. Similarly with input drivers, if you've got a keyboard with weird quirks or a mouse with weird quirks, which evidently the vendors of these things are fond of weird quirks, you can load a little BPF program that makes it work like every other one. That sort of thing.  It's a sandboxing mechanism that's increasingly widely used where you load BPF programs to the side, which system calls a particular process can use and which ones are denied to it. Or you can write entire Linux security modules now using the BPF mechanism, which is a very flexible mechanism for the creation of security policies within the kernel. And of course the whole use of BPF for tracing and analysis is quite extensive in the kernel at this point. We have a lot of observability mechanisms all based on BPF. So you may be thinking that you don't use BPF yourself. I was sort of thinking so and then I asked my laptop right here whether it was running any BPF programs at the moment. They didn't fit on the slide. There's something over 20 of them that were loaded in there mostly by system D, which has become a pretty active user of BPF programs. So for example this one that I've highlighted is a security module written in BPF that is there to restrict the types of file systems that the particular processes can access. There are some file system types, really old ancient un-maintained file systems that are seen as being insecure. And so there's a desire to simply not let people use them even though the support for them is still there in the kernel. So it's an example of how BPF is being used to change the interface that the kernel is offering to user space and to make the kernel something that's a little bit different than what it is now. So this is all stuff that's being done now. This is in production kernels. There's a whole lot of stuff being done out there that could be in production kernels. So the extensible scheduler class is a framework that allows the creation of complete CPU schedulers, the whole thing from CPU scheduling in BPF. You can write the entire algorithm for deciding which processes should run for how long they should run, when one process should preempt another one, which CPU they should be running on. You can do the whole thing in BPF. It's an extensive and capable mechanism that was done by people at Meta and Google, that sort of thing. It's quite complete. There's a lot of reasons why you might want to do this. It allows for easy experimentation with scheduler algorithms. If you're trying to write a scheduler now or tweak the existing scheduler, you have to do your C code, then you have to build a new kernel and boot it and then watch the thing crash and then start all over again. That takes a while.  So it speeds scheduler development quite a bit. It also allows for the creation of special purpose schedulers. If you have a weird workload that needs different scheduling policies than what's normally available, you can write a scheduler to do it. Beyond that, the kernel over the last year or so adopted a thing called the multi-generational LRU. It's part of the memory management subsystem that is used for page aging for deciding when certain pages, certain parts of a processes memory are not being used and can be taken away and used for other purposes. It sorts pages into generations where the newest generation is the most actively used memory. The oldest generation is the least used memory. So when memory has to be reclaimed from a process, it is taken from that oldest generation. So needless to say, if you have an algorithm like this, that aging of the pages is key to it because that's how you make your decisions about which pages you take out and which ones you don't. And if you make that decision wrong, then you hurt the performance of the system as a whole. So there is talk of allowing the addition of BPF programs to do this page aging, to look at what a process is doing, and decide where pages should be placed in these generations. So this is again the insertion of BPF and do a deep core subsystem of the kernel, sort of thing that normally you would not affect in user space. But if this goes in, then you will be able to. IOU ring is a subsystem for asynchronous IO at its core, but it's rapidly becoming an alternative programming interface for the kernel where you can load a whole sequence of operations into the kernel, have them run asynchronously and just hear back from the kernel when they're all done. So you can load a sequence of operations, for example, tell it, open this file, read that file's contents, write them out to that network socket over there, close the file, and just tell me when it's all done. And the kernel will handle it all asynchronously. You can get some pretty amazing IO rates and such out of this. It's a way to speed up IO intensive programs. But the sequencing you have in IOU ring now is pretty simplistic. If you could put BPF programs into there as well, then of course you have a whole new level of control. So there have been patches out there to add BPF to IOU ring. They haven't been merged. I haven't seen a lot of pressure to merge them recently, but I doubt they're going to go away. But once again, this is pretty deep stuff in the kernel. In this context, it's worth pointing out that recently, the extensible scheduler class was rejected by the scheduler maintainer, said, no, we cannot merge this. We are not going to put this into the kernel. Sorry. We're not going to do it. So you might ask why this was done. This looks like a pretty useful capability. And there's a whole lot of reasons that were cited for doing this. Some of which make some real sense. Starting simply with the added maintenance burden on the scheduling maintainers themselves who didn't want to deal with yet another scheduling class and all the sort of stuff that goes with it. There was a whole lot of fear that vendors would use this for benchmark gaming.  And seeing what vendors have done over many, many, many years, this seems like a legitimate fear to me. Right? Of course, they're going to do that if they can do that. Along with that, vendors might say that if you're going to run our fancy enterprise software system, you also need to run our special scheduler that goes with it and we're not going to support it. There's a whole lot of fear that that would happen. And again, it wouldn't surprise me at all. ABI concerns, in theory, anything that is used by a BPF program is considered internal to the kernel. So if a kernel change breaks it, then it's the problem of the BPF program and their maintainers to fix their side of things to match that. In practice, if somebody had a scheduler they depended on and then a scheduler changed within the kernel broke it and they screamed, I think there would be an awful lot of pressure to revert that change. That in turn puts a really strong restriction on how you can involve the internal Linux CPU scheduler going forward. And the scheduler developer is really, really disliked this idea. Developers in general like this idea. This puts you into a straight jacket that really restricts what you can do in the future. And people don't want to see that happen. So this is another fear that kept the extensible scheduler class out. And finally, the scheduler developers were worried. This would simply take developers away from the core scheduler. They would make their own little fixes and run it in their own little BPF modules and not contribute their work back into the core scheduler where it would benefit everybody. And so for all of these reasons, this particular work was rejected from the kernel. But this was a decision made by one developer and not by the kernel community as a whole. As a whole within the community, we have not yet decided what is it that we are willing to export via BPF? And what is it that is off limits and that you must do in C within the kernel itself? Where do we draw that line? And so I think at some point we're going to have to articulate that a whole lot better. Or we're going to frustrate our users and we're going to frustrate people who are trying to develop these advanced capabilities in BPF only to be told that they cannot actually get it into the kernel. I think it's not fair to them. I think it's really not fair to anybody to not know where that division is. So expect some discussions on this over the course of the year or two as we try to figure out some sort of policy that says what can we do in BPF and what is it that we should not be doing? Another area that I think we're going to see things talking about is the Rust programming language. Rust has an awful lot to offer. It offers a much stronger type system. It offers a freedom from undefined behavior which of course is one of the real joys that C brings to you. It allows the development of a much safer code where there are whole classes of bugs that are endemic to C code that simply cannot happen in a Rust program that gets past the compiler. So if we wrote a lot of our kernel code in Rust rather than C, we would demonstrably have a safer kernel. There are lots of bugs that we simply wouldn't have to worry about. There are others of course that are going to happen. Nothing is perfect. But we would do a whole lot better. And the other aspect of this that really should not be overlooked is that Rust is far more attractive to newer developers than C is. The number of people coming out of the university who are just jumping up and down and wanting to start writing C code is smaller than it used to be, shall we say. And I don't expect that to change. Now as we saw back at the beginning of the talk, we were doing pretty well at bringing developers into the kernel community. But this is something that we want to continue just not this next year, but the next 30 years and more. We want to continue to have a healthy influx of developers. And allowing them to work in a language they want to work in I think is an important aspect of that. We are already seeing interest from new people, people we've never heard of who would like to work on the Rust side of things. So that is actually an important part of this as well. But I mean there are reasons to not do it as well. Adding a new language to the kernel adds a whole bunch of complexity. You've got a whole new set of dependencies that you need to have to build the kernel, changes the build system, all that sort of stuff. It makes it more complicated and the kernel build system is already a complex thing. The Rust language itself is still evolving quite quickly. Rust in the kernel has to use some incredible number. I believe it's over 100 unstable Rust features right now. Not all of those features will be stabilized in the form they're being used now. So any kernel code in Rust will have to change as the language itself changes. And that is something that worries people. We go very far out of our way to allow the kernel to build with a range of C-compilers, including fairly old C-compilers, so that we don't impose a specific version of the C-compiler on people trying to build the kernel. With Rust, that's not possible. You really have to use the current Rust compiler to build anything in Rust. Maintainers will have to learn Rust. And this is not a small thing. We have people who have been working in C for decades sometimes who are now going to have to learn a new language. And a language that's not the easiest language to learn at that. If you're a maintainer, and people are going to start putting Rust code into your subsystem, you have to be able to understand that code. You have to be able to make changes to that code. You have to be able to fix it before you can accept it. So as a maintainer, you simply have to understand the language. You have to understand it well. So this is a big, big thing to ask of our already overburdened maintainers in the kernel. Rust brings with it a lot of glue code to make it work with existing kernel facilities. And there are some things that are simply hard to do in Rust. If you want to create a simple embedded linked list of which there are thousands in the kernel, you really can't do that in Rust just because the pointers in two directions run afoul of the ownership rules that the Rust language imposes. And this is very hard to do. And there are various other things that have worked around in the Rust language. So it's not perfect either. But there's a whole lot of interesting things even so. And then I have to say it because it's true. The kernel community is somewhat conservative at times. And often rightly so, right? The things that we do have consequences for, I believe at this point, billions of machines out there. So you don't do things lightly. You have to be very careful about changes that you introduce into the kernel.  But if you take a kernel developer who's been working in C for 20 or 30 years and you throw something at them that looks like this, this is the Rust version of what is a one-line macro in C that just gets a pointer to the task structure for the current process. And it's rather more complex. And it looks like line noise if you don't understand the Rust language. That sort of thing. And then that tends to lead to responses like this, where there's a long-time kernel developer who I've chosen to leave nameless for his own sake, who simply said that saying we need Rust is really an insult to the developers who have worked for years and years and years to build a safe code in C. And we really just don't need this. We don't want it. So that's where that stands at the moment. In terms of Rust, the initial support for Rust was merged in 6.1, right? It's enough to write a hello world module and really nothing else. We've seen the addition of support code going in in subsequent kernels, that sort of thing. But as of now, there is nothing in a production kernel, nothing that anybody is actually using that is written in Rust, right? It's all just experimental stuff in support code. But there's an awful lot of stuff going on out there. There's an awful lot of support code and some interesting developments, perhaps the highest profile of which is being the Apple Silicon GPU driver that's being written by Asahi Lina that is coming along. Asahi has been very, very explicit about how doing this driver in Rust has made the whole thing much easier than doing it in C. So there's a lot of images in that people want that. PuzzleFS is a read-only file system aimed at the creation of container images, that sort of thing, trying to do things in a secure sort of way. There's a read-write plan nine file system server. The kernel has a read-only plan nine file system server in it now, but it does not have the right capability, but the one written in Rust does. And a whole lot of other stuff that's going on in this area. Useful stuff that people actually want, that when it's merged into a kernel people will actually use. And that leads to the question, which is the merging of Rust support was explicitly an experiment. It was done to see how it would work out and Linus Torvald said at the outset we're going to put it in, we're going to see how it goes. If it doesn't work we will take it all out again. But that leads to the question, when do you decide this experiment was a success? When you say that okay it works and we're going to keep it. And the answer is actually quite clear. That decision is made the first time we merged something that users actually want to depend on. We have a strong no regressions rule in the kernel. If something works with a given kernel we cannot break it with a subsequent kernel. That's just the rule that we live by. So if we put in say an Apple GPU driver and then we say some few releases later, oh actually this Rust thing doesn't work we're taking it out. And so the GPU driver goes away. We're going to have some pretty unhappy users and we can't do that. We will not be able to do that. So this is the decision point and I think it's coming soon. I think it's coming in this next year because there's going to be increasing pressure to merge this code that has been written in Rust. And at that point I think we will see whatever remaining pushback there is from the people who don't want to see Rust. And there's going to be some interesting discussions I think over the course of the next year. I personally think that this stuff will go in and I think we'll go forward with it. But I don't think there are any guarantees of that. So my last topic when I talk about something that I call the Maintainership Crisis in the kernel. We're seeing maintainers complaining about the job of being a maintainer with the XFS maintainer, the now XFS maintainer, saying that it feels like punishment from people bringing out. So what's going on here? Why are people complaining? Well, there's a lot of problems. The demands on kernel maintainers have been increasing over time as the complexity of the code grows up, as the rate of patches goes up, as there's more to review, more to do. And then people start talking about, say, introducing Rust and making them learn Rust and so on. There's a lot going up at the same time. There's a lot of understaffing both at the maintainer level and at the kernel developer level. So even though we have some 2,000 developers participating in every release, it's not enough. And so, again, you see things like this where Derek Wong is saying that he has friends who work for small companies and so on, and they're used to seeing the sorts of pathologies we see in the kernel community due to the stress of being understaffed and overworked. But he doesn't understand why this is happening when everybody is involved, is working for these 100 billion dollar companies. That sort of thing. It doesn't make a whole lot of sense to him. It doesn't make a lot of sense to a lot of people. But that's what's happening. We see a lot of lack of employer support for the maintainer role in particular. So here's a quote from one of the key kernel maintainers who's saying that he's being a full-time maintainer, but he has a full-time job and the full-time job is not for his maintainership. He's doing that on the side. Many kernel maintainers are doing their maintainer work on the side. I do my maintainer work on the side, right? Nobody pays me to do that. And that is true of many of the others as well. We've been pushing to try to change that. We actually added a document to the kernel tree a little while back where people can evaluate how well their company is doing it at supporting maintainers and then maybe take that to their boss and try to make it better. We're having trouble with kernel fuzzers. That sort of thing. Fuzz testing is a great way of finding bugs. It is a very valuable tool for the kernel. It's found a lot of bugs that we have fixed. But fuzz testers are also generating thousands and thousands of bug reports, many of which are not seen as being particularly high quality bug reports, but people have to look at these and triage them and so on. This adds to the demands of all that sort of stuff and so on. So there's a lot going on there. What it really comes down to is that really like every other part of the open source community, there are a lot of dark areas in the kernel development community. Even though we have hundreds of companies supporting every kernel release out there, they're just, they're big areas of the kernel that no company says, this is our problem, we need to put resources into supporting it. It happens all the time. So I must of course mention documentation is one of those. We have 2,000 developers participating in every kernel release of something 4,000 to 5,000 developers over the course of a year. There is not one developer whose job is to create documentation. And our documentation reflects that. It really does, I hate to say it. The build system, the kernel build system is a complex thing, is maintained by one person who's doing that. If that person gets fed up and leaves, I don't know what we're going to do. A whole lot of areas of the core kernel itself are under maintained as a result of this driver's role or hardware. A lot of companies are happy to support their current hardware, but a couple years on when they're selling their new big thing, they don't really care much about supporting that older stuff that they really wish people would just throw away and buy new things for anymore. So somebody else has to maintain that at some point. And then of course the maintenance role in general, which is a separate job from development, is undersupported in the kernel community, as it is, again, anywhere else in the open source community to tell the truth. And so this is a problem that we have. Scott McNeely, for all his faults, actually said something useful a while back, which is that the open source is free like a puppy is free. You can certainly get it into the house very quickly, but if you then say, okay, I'm done, you're going to find messes on the floor and all your shoes are chewed up. The same thing is true with free software. You can get it for free, but you have to pay attention to it, or you're going to find some messes where you really want to find them. So I leave with the final question, which is, how can we take better care of this particular puppy? Because we have a real lack of support for a lot of areas that we need to support within the kernel, the maintenance role and beyond. And with that, it looks like I have about exactly one minute for questions if people would like to ask questions. And I thank you very much for your attention. Question being that since I was showing 200-300 developers entering the kernel community every release, while the number of developers growing much more slowly than that. It isn't growing, but it's much more slowly than that. That implies that a lot of developers leave. And the answer is yes. Obviously, people leave. Of those 200 or so first-time developers, probably about half of them, I haven't done this analysis for a bit, but probably about half of them are one-time people.  That sort of thing. Others stick around and then people come and go over time. It's a big community, and so there will be some attrition as well. We are growing, but certainly not at that rate. Does that answer your question? Anybody else? So how much BPF is used by? Are there stories of attackers using BPF? You know, I don't personally know of them. I'm sure they must exist, right? They will use every tool they can get. BPF-2, of course, has had a vulnerability or two of its own. Systems of system that complex is going to, that sort of thing. I don't know that they're using it, but I'm sure that that is happening. Yeah, you give people a tool and another entry point in the system. Of course, to load a BPF program in general, you already have to have some sort of root access for almost everything. Not everything, but almost. So usually at that point, you've already won the game, but there may be situations where they're using BPF as well. All right, at this point, I think I am out of time. I'm still next speaker set up, but I thank you all very much for your attention.