# linux2021: reggiehsu111
contributed by < [`reggiehsu111`](https://github.com/reggiehsu111) >
###### tags: `linux2021`
## Problem $\alpha - 1$
## Problem $\alpha - 2$
## Problem $\beta - 1$
Source code for `alignment.c`:
```cpp
static inline uintptr_t align_up(uintptr_t sz, size_t alignment) {
uintptr_t mask = alignment - 1;
if ((alignment & mask) == 0) { /* power of two? */
return (sz + mask) & ~mask;
}
return (((sz + mask) / alignment) * alignment);
}
```
### Explanation
- The function returns the smallest aligned address (divisible by alignment) that is larger or equal to sz.
- First notice that the function takes in a `uintptr_t` type sz and a `size_t` type alignment. The two types can be different as suggested in [this post](https://stackoverflow.com/questions/1464174/size-t-vs-uintptr-t). `size_t` is bounded by `SIZE_MAX`, which is 2^64-1 in my computer. Therefore, the size of `uintptr_t` and `size_t` are both 8 bytes in my computer.
- If the alignment is a power of two:
- The bit representations are:
- alignment: `0...010..0`
- mask: `0...001..1`
- If sz is a multiple of `alignment`, `sz + mask` doesn't carry to the `log2(alignment) + 1` bit, so when performing `& ~mask`, the right most `log2(alignment)` bits will become 0s. Otherwise, `(sz + mask) & ~mask` will increment the `log2(alignment) + 1` bit, giving the desired output.
- If the `alignment` is not a power of two:
- `(sz + mask) / alignment` will discard the fraction part of the result, so when multiplied back with `* alignment`, only when sz is a multiple of `alignment` will the result be the same as sz (because the fraction of `sz + mask / alignment` is 0).
## Problem $\beta - 2$
- Not sure right now how to correctly search the linux source code, but found this: https://github.com/torvalds/linux/blob/f40ddce8/arch/arm/mm/alignment.c#L1 and will check this later
## Problem $\gamma - 1$
```cpp=
int main(void)
{
for (int i = 0; i < 12; i++) {
fork();
printf("-");
}
fflush(stdout);
return 0;
}
```
### Explanation
- As suggested in [this post](https://unix.stackexchange.com/questions/447898/why-does-a-program-with-fork-sometimes-print-its-output-multiple-times/447904), when a child process is forked, the unflushed buffer is inherited by the child process. Because `stdout` is line-buffered ([meaning](https://www.ibm.com/docs/en/zos/2.3.0?topic=output-buffering-c-streams)) by default, the buffer isn't flushed until a newline character is reached, or manually flushed by `fflush`.
```graphviz
digraph {
rankdir=TB;
node [shape=record];
example [label="{ <p_num> process appearing # | <iter> nth iteration|<-s> # of '-'s in buffer}"]
subgraph {
p_1B [label="{ <p_num> P1 | <iter> Before loop | <-s> 0}"];
p_10 [label="{ <p_num> P1 | <iter> iter 0 | <-s> 1}"];
p_20 [label="{ <p_num> P2 | <iter> iter 0 | <-s> 1}"];
p_11 [label="{ <p_num> P1 | <iter> iter 1 | <-s> 2}"];
p_21 [label="{ <p_num> P2 | <iter> iter 1 | <-s> 2}"];
p_31 [label="{ <p_num> P3 | <iter> iter 1 | <-s> 2}"];
p_41 [label="{ <p_num> P4 | <iter> iter 1 | <-s> 2}"];
p_1B->p_10;
p_1B->p_20;
p_10->p_11;
p_10->p_31;
p_20->p_21;
p_20->p_41;
}
}
```
- From the graph above, we see that for each iteration, the number of `-` in the buffer will increment by 1 in each process, so the total number of `-` in all processes' buffers on ith iteration will be: $i*2^i$. For i = 12, we get a total number of 49152 `-` to be flushed at the end.