OSTEP Chapterr 28
This commit is contained in:
parent
e698da3c30
commit
36d188acfa
@ -486,5 +486,692 @@
|
||||
:height 1296}),
|
||||
:page 344},
|
||||
:content {:text "test-and-set (or atomic exchange1) instruction"},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "6434edd3-2a7b-4e11-af18-29854e628bc6",
|
||||
:page 345,
|
||||
:position {:bounding {:x1 491.1250305175781,
|
||||
:y1 377.0089416503906,
|
||||
:x2 658.8576049804688,
|
||||
:y2 400.4375305175781,
|
||||
:width 864,
|
||||
:height 1296},
|
||||
:rects ({:x1 491.1250305175781,
|
||||
:y1 377.0089416503906,
|
||||
:x2 658.8576049804688,
|
||||
:y2 400.4375305175781,
|
||||
:width 864,
|
||||
:height 1296}),
|
||||
:page 345},
|
||||
:content {:text "Peterson’s algorithm"},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "6434f523-44b7-40ab-8fea-528969c5acfd",
|
||||
:page 347,
|
||||
:position {:bounding {:x1 402.9370536804199,
|
||||
:y1 274.72320556640625,
|
||||
:x2 440.68061447143555,
|
||||
:y2 292.4375,
|
||||
:width 864,
|
||||
:height 1296},
|
||||
:rects ({:x1 402.9370536804199,
|
||||
:y1 274.72320556640625,
|
||||
:x2 440.68061447143555,
|
||||
:y2 292.4375,
|
||||
:width 864,
|
||||
:height 1296}),
|
||||
:page 347},
|
||||
:content {:text "foil "},
|
||||
:properties {:color "green"}}
|
||||
{:id #uuid "6434f8ac-d762-40a4-abb0-2955c2c8b396",
|
||||
:page 348,
|
||||
:position {:bounding {:x1 203.03572463989258,
|
||||
:y1 550.3303833007812,
|
||||
:x2 358.456729888916,
|
||||
:y2 573.7589569091797,
|
||||
:width 864,
|
||||
:height 1296},
|
||||
:rects ({:x1 203.03572463989258,
|
||||
:y1 550.3303833007812,
|
||||
:x2 358.456729888916,
|
||||
:y2 573.7589569091797,
|
||||
:width 864,
|
||||
:height 1296}),
|
||||
:page 348},
|
||||
:content {:text "compare-and-swap"},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "6434fab0-08de-4f28-8d8e-f48f7e04aaaa",
|
||||
:page 348,
|
||||
:position {:bounding {:x1 0,
|
||||
:y1 301.1428756713867,
|
||||
:x2 746.9776916503906,
|
||||
:y2 669.5536117553711,
|
||||
:width 864,
|
||||
:height 1296},
|
||||
:rects ({:x1 0,
|
||||
:y1 301.1428756713867,
|
||||
:x2 0,
|
||||
:y2 322.28572845458984,
|
||||
:width 864,
|
||||
:height 1296}
|
||||
{:x1 0,
|
||||
:y1 317.1428756713867,
|
||||
:x2 0,
|
||||
:y2 338.28572845458984,
|
||||
:width 864,
|
||||
:height 1296}
|
||||
{:x1 528.7957763671875,
|
||||
:y1 611.7679061889648,
|
||||
:x2 745.6440734863281,
|
||||
:y2 629.4822006225586,
|
||||
:width 864,
|
||||
:height 1296}
|
||||
{:x1 171.89286422729492,
|
||||
:y1 631.6964340209961,
|
||||
:x2 746.9776916503906,
|
||||
:y2 649.6250228881836,
|
||||
:width 864,
|
||||
:height 1296}
|
||||
{:x1 171.89286422729492,
|
||||
:y1 651.6250228881836,
|
||||
:x2 731.2063903808594,
|
||||
:y2 669.5536117553711,
|
||||
:width 864,
|
||||
:height 1296}),
|
||||
:page 348},
|
||||
:content {:text "est whether the value at the address specified by ptr is equal to expected; if so, update the memory location pointed to by ptr with the new value. If not, do nothing. "},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "6434fb8c-2b3b-4d80-83fb-3b34da4dcd28",
|
||||
:page 349,
|
||||
:position {:bounding {:x1 333.7612075805664,
|
||||
:y1 182.38393259048462,
|
||||
:x2 382.13965606689453,
|
||||
:y2 200.09822702407837,
|
||||
:width 864,
|
||||
:height 1296},
|
||||
:rects ({:x1 333.7612075805664,
|
||||
:y1 182.38393259048462,
|
||||
:x2 382.13965606689453,
|
||||
:y2 200.09822702407837,
|
||||
:width 864,
|
||||
:height 1296}),
|
||||
:page 349},
|
||||
:content {:text "delve "},
|
||||
:properties {:color "green"}}
|
||||
{:id #uuid "6434fde1-9d19-4381-805e-f2a972875dc2",
|
||||
:page 349,
|
||||
:position {:bounding {:x1 140.9732208251953,
|
||||
:y1 353.53572845458984,
|
||||
:x2 417.0097427368164,
|
||||
:y2 376.9642868041992,
|
||||
:width 864,
|
||||
:height 1296},
|
||||
:rects ({:x1 144.50000762939453,
|
||||
:y1 353.53572845458984,
|
||||
:x2 245.45536041259766,
|
||||
:y2 376.9642868041992,
|
||||
:width 864,
|
||||
:height 1296}
|
||||
{:x1 277.5178756713867,
|
||||
:y1 353.53572845458984,
|
||||
:x2 417.0097427368164,
|
||||
:y2 376.9642868041992,
|
||||
:width 864,
|
||||
:height 1296}
|
||||
{:x1 140.9732208251953,
|
||||
:y1 355.1964340209961,
|
||||
:x2 417.0097427368164,
|
||||
:y2 373.1250228881836,
|
||||
:width 864,
|
||||
:height 1296}),
|
||||
:page 349},
|
||||
:content {:text " load-linked and store-conditional"},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "6434fe1c-47f3-422c-a317-be72f08d6aef",
|
||||
:page 349,
|
||||
:position {:bounding {:x1 0,
|
||||
:y1 173.14286613464355,
|
||||
:x2 689.8495903015137,
|
||||
:y2 474.5625305175781,
|
||||
:width 864,
|
||||
:height 1296},
|
||||
:rects ({:x1 0,
|
||||
:y1 173.14286613464355,
|
||||
:x2 0,
|
||||
:y2 194.28572463989258,
|
||||
:width 864,
|
||||
:height 1296}
|
||||
{:x1 140.01786422729492,
|
||||
:y1 436.919677734375,
|
||||
:x2 689.8495903015137,
|
||||
:y2 454.6339416503906,
|
||||
:width 864,
|
||||
:height 1296}
|
||||
{:x1 116.09821891784668,
|
||||
:y1 456.8482360839844,
|
||||
:x2 576.551923751831,
|
||||
:y2 474.5625305175781,
|
||||
:width 864,
|
||||
:height 1296}),
|
||||
:page 349},
|
||||
:content {:text "The load-linked operates much like a typical load instruction, and simply fetches a value from memory and places it in a register. "},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "6434fe62-0e92-4414-86cc-b0c37fcf51ec",
|
||||
:page 349,
|
||||
:position {:bounding {:x1 0,
|
||||
:y1 205.1428680419922,
|
||||
:x2 691.6227188110352,
|
||||
:y2 574.4018249511719,
|
||||
:width 864,
|
||||
:height 1296},
|
||||
:rects ({:x1 0,
|
||||
:y1 205.1428680419922,
|
||||
:x2 0,
|
||||
:y2 226.28572845458984,
|
||||
:width 864,
|
||||
:height 1296}
|
||||
{:x1 0,
|
||||
:y1 221.1428680419922,
|
||||
:x2 0,
|
||||
:y2 242.28572845458984,
|
||||
:width 864,
|
||||
:height 1296}
|
||||
{:x1 0,
|
||||
:y1 237.1428680419922,
|
||||
:x2 0,
|
||||
:y2 258.28572845458984,
|
||||
:width 864,
|
||||
:height 1296}
|
||||
{:x1 0,
|
||||
:y1 253.1428680419922,
|
||||
:x2 0,
|
||||
:y2 274.28572845458984,
|
||||
:width 864,
|
||||
:height 1296}
|
||||
{:x1 277.6942825317383,
|
||||
:y1 476.76788330078125,
|
||||
:x2 689.7750625610352,
|
||||
:y2 494.482177734375,
|
||||
:width 864,
|
||||
:height 1296}
|
||||
{:x1 116.09821891784668,
|
||||
:y1 496.6964416503906,
|
||||
:x2 689.7808971405029,
|
||||
:y2 514.6250305175781,
|
||||
:width 864,
|
||||
:height 1296}
|
||||
{:x1 116.09821891784668,
|
||||
:y1 516.6250305175781,
|
||||
:x2 690.9502334594727,
|
||||
:y2 534.5535888671875,
|
||||
:width 864,
|
||||
:height 1296}
|
||||
{:x1 116.09821891784668,
|
||||
:y1 536.5535888671875,
|
||||
:x2 691.6227188110352,
|
||||
:y2 554.482177734375,
|
||||
:width 864,
|
||||
:height 1296}
|
||||
{:x1 116.09821891784668,
|
||||
:y1 556.4732360839844,
|
||||
:x2 505.1802444458008,
|
||||
:y2 574.4018249511719,
|
||||
:width 864,
|
||||
:height 1296}),
|
||||
:page 349},
|
||||
:content {:text "store-conditional, which only succeeds (and updates the value stored at the address just load-linked from) if no intervening store to the address has taken place. In the case of success, the storeconditional returns 1 and updates the value at ptr to value; if it fails, the value at ptr is not updated and 0 is returned."},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "64350170-c853-4080-9ed1-2777ea3a18c8",
|
||||
:page 350,
|
||||
:position {:bounding {:x1 171.88932037353516,
|
||||
:y1 863.3928833007812,
|
||||
:x2 325.20848846435547,
|
||||
:y2 885.1071624755859,
|
||||
:width 864,
|
||||
:height 1296},
|
||||
:rects ({:x1 171.88932037353516,
|
||||
:y1 863.3928833007812,
|
||||
:x2 325.20848846435547,
|
||||
:y2 885.1071624755859,
|
||||
:width 864,
|
||||
:height 1296}),
|
||||
:page 350},
|
||||
:content {:text "Fetch-And-Add"},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "643501c1-f11b-4e85-8125-d2a5a31f69b0",
|
||||
:page 351,
|
||||
:position {:bounding {:x1 287.3301315307617,
|
||||
:y1 215.3393006324768,
|
||||
:x2 330.14022064208984,
|
||||
:y2 233.0535798072815,
|
||||
:width 864,
|
||||
:height 1296},
|
||||
:rects ({:x1 287.3301315307617,
|
||||
:y1 215.3393006324768,
|
||||
:x2 330.14022064208984,
|
||||
:y2 233.0535798072815,
|
||||
:width 864,
|
||||
:height 1296}),
|
||||
:page 351},
|
||||
:content {:text "brag "},
|
||||
:properties {:color "green"}}
|
||||
{:id #uuid "64350331-8fbb-4c41-9ac1-1a4ba852f772",
|
||||
:page 351,
|
||||
:position {:bounding {:x1 116.09821701049805,
|
||||
:y1 483.9285888671875,
|
||||
:x2 203.6010856628418,
|
||||
:y2 507.3571472167969,
|
||||
:width 864,
|
||||
:height 1296},
|
||||
:rects ({:x1 116.09821701049805,
|
||||
:y1 483.9285888671875,
|
||||
:x2 203.6010856628418,
|
||||
:y2 507.3571472167969,
|
||||
:width 864,
|
||||
:height 1296}),
|
||||
:page 351},
|
||||
:content {:text "ticket lock"},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "64350420-ca8a-4cac-af2f-f4e7deb5d1be",
|
||||
:page 351,
|
||||
:position {:bounding {:x1 0,
|
||||
:y1 413.1428680419922,
|
||||
:x2 738.2561340332031,
|
||||
:y2 816.4464416503906,
|
||||
:width 921.6,
|
||||
:height 1382.4},
|
||||
:rects ({:x1 0,
|
||||
:y1 413.1428680419922,
|
||||
:x2 0,
|
||||
:y2 434.2857208251953,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 204.68063354492188,
|
||||
:y1 775.7679138183594,
|
||||
:x2 738.2561340332031,
|
||||
:y2 795.1964416503906,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 123.83928871154785,
|
||||
:y1 797.0179138183594,
|
||||
:x2 618.5764713287354,
|
||||
:y2 816.4464416503906,
|
||||
:width 921.6,
|
||||
:height 1382.4}),
|
||||
:page 351},
|
||||
:content {:text "it ensures progress for all threads. Once a thread is assigned its ticket value, it will be scheduled at some point in the future"},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "64350781-6995-41db-8b8e-2de0eb84136a",
|
||||
:page 353,
|
||||
:position {:bounding {:x1 336.0178756713867,
|
||||
:y1 439.3214416503906,
|
||||
:x2 629.7097702026367,
|
||||
:y2 464.46429443359375,
|
||||
:width 921.6,
|
||||
:height 1382.4},
|
||||
:rects ({:x1 336.0178756713867,
|
||||
:y1 439.3214416503906,
|
||||
:x2 629.7097702026367,
|
||||
:y2 464.46429443359375,
|
||||
:width 921.6,
|
||||
:height 1382.4}),
|
||||
:page 353},
|
||||
:content {:text "Lock With Test-and-set And Yield"},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "643507af-1153-46c1-b232-31a9a203e5df",
|
||||
:page 353,
|
||||
:position {:bounding {:x1 0,
|
||||
:y1 269.1428756713867,
|
||||
:x2 738.272834777832,
|
||||
:y2 606.2500381469727,
|
||||
:width 921.6,
|
||||
:height 1382.4},
|
||||
:rects ({:x1 0,
|
||||
:y1 269.1428756713867,
|
||||
:x2 0,
|
||||
:y2 290.28572845458984,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 0,
|
||||
:y1 285.1428756713867,
|
||||
:x2 0,
|
||||
:y2 306.28572845458984,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 233.25476837158203,
|
||||
:y1 544.3125381469727,
|
||||
:x2 738.272834777832,
|
||||
:y2 563.741096496582,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 123.83929443359375,
|
||||
:y1 563.9821853637695,
|
||||
:x2 202.37335205078125,
|
||||
:y2 589.1250381469727,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 306.8750228881836,
|
||||
:y1 563.9821853637695,
|
||||
:x2 363.09754180908203,
|
||||
:y2 589.1250381469727,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 123.83929443359375,
|
||||
:y1 567.4107437133789,
|
||||
:x2 738.1959915161133,
|
||||
:y2 586.8393020629883,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 123.83929443359375,
|
||||
:y1 586.8214492797852,
|
||||
:x2 199.30642700195312,
|
||||
:y2 606.2500381469727,
|
||||
:width 921.6,
|
||||
:height 1382.4}),
|
||||
:page 353},
|
||||
:content {:text "yield is simply a system call that moves the caller from the running state to the ready state, and thus promotes another thread to running. "},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "6435099b-0834-483e-9ef2-98a0b795cf00",
|
||||
:page 355,
|
||||
:position {:bounding {:x1 381.2857208251953,
|
||||
:y1 336.4643096923828,
|
||||
:x2 535.9663848876953,
|
||||
:y2 361.6071319580078,
|
||||
:width 921.6,
|
||||
:height 1382.4},
|
||||
:rects ({:x1 381.2857208251953,
|
||||
:y1 336.4643096923828,
|
||||
:x2 535.9663848876953,
|
||||
:y2 361.6071319580078,
|
||||
:width 921.6,
|
||||
:height 1382.4}),
|
||||
:page 355},
|
||||
:content {:text "priority inversion"},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "643509b5-12a0-4ed9-8a96-f70b3fc0e373",
|
||||
:page 355,
|
||||
:position {:bounding {:x1 149.39746856689453,
|
||||
:y1 359.30358123779297,
|
||||
:x2 268.7185363769531,
|
||||
:y2 378.73217010498047,
|
||||
:width 921.6,
|
||||
:height 1382.4},
|
||||
:rects ({:x1 149.39746856689453,
|
||||
:y1 359.30358123779297,
|
||||
:x2 268.7185363769531,
|
||||
:y2 378.73217010498047,
|
||||
:width 921.6,
|
||||
:height 1382.4}),
|
||||
:page 355},
|
||||
:content {:text "intergalactic "},
|
||||
:properties {:color "green"}}
|
||||
{:id #uuid "643509ba-662e-4d0a-906a-fd0987e24574",
|
||||
:page 355,
|
||||
:position {:bounding {:x1 268.71058654785156,
|
||||
:y1 359.30358123779297,
|
||||
:x2 328.3750915527344,
|
||||
:y2 378.73217010498047,
|
||||
:width 921.6,
|
||||
:height 1382.4},
|
||||
:rects ({:x1 268.71058654785156,
|
||||
:y1 359.30358123779297,
|
||||
:x2 328.3750915527344,
|
||||
:y2 378.73217010498047,
|
||||
:width 921.6,
|
||||
:height 1382.4}),
|
||||
:page 355},
|
||||
:content {:text "scourge"},
|
||||
:properties {:color "green"}}
|
||||
{:id #uuid "64350b44-dfae-4544-93f9-ff2b343fefd4",
|
||||
:page 354,
|
||||
:position {:bounding {:x1 314.14287185668945,
|
||||
:y1 927.5714721679688,
|
||||
:x2 770.6213264465332,
|
||||
:y2 952.7143249511719,
|
||||
:width 921.6,
|
||||
:height 1382.4},
|
||||
:rects ({:x1 314.14287185668945,
|
||||
:y1 927.5714721679688,
|
||||
:x2 770.6213264465332,
|
||||
:y2 952.7143249511719,
|
||||
:width 921.6,
|
||||
:height 1382.4}),
|
||||
:page 354},
|
||||
:content {:text "Lock With Queues, Test-and-set, Yield, And Wakeup"},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "64350b4e-9559-49d9-aa37-eda9fe425b7f",
|
||||
:page 353,
|
||||
:position {:bounding {:x1 0,
|
||||
:y1 621.1428756713867,
|
||||
:x2 738.2636413574219,
|
||||
:y2 1106.0625305175781,
|
||||
:width 921.6,
|
||||
:height 1382.4},
|
||||
:rects ({:x1 0,
|
||||
:y1 621.1428756713867,
|
||||
:x2 0,
|
||||
:y2 642.2857360839844,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 149.35714721679688,
|
||||
:y1 1065.3839721679688,
|
||||
:x2 738.2636413574219,
|
||||
:y2 1084.8125305175781,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 123.83929443359375,
|
||||
:y1 1086.6339721679688,
|
||||
:x2 265.7547607421875,
|
||||
:y2 1106.0625305175781,
|
||||
:width 921.6,
|
||||
:height 1382.4}),
|
||||
:page 353},
|
||||
:content {:text "The real problem with our previous approaches is that they leave too much to chance."},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "64350bfb-64f7-4d41-8cc2-260dbec3372d",
|
||||
:page 354,
|
||||
:position {:bounding {:x1 267.0446472167969,
|
||||
:y1 1086.6339721679688,
|
||||
:x2 590.4763793945312,
|
||||
:y2 1106.0625610351562,
|
||||
:width 921.6,
|
||||
:height 1382.4},
|
||||
:rects ({:x1 267.0446472167969,
|
||||
:y1 1086.6339721679688,
|
||||
:x2 590.4763793945312,
|
||||
:y2 1106.0625610351562,
|
||||
:width 921.6,
|
||||
:height 1382.4}),
|
||||
:page 354},
|
||||
:content {:text "park() to put a calling thread to sleep"},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "64350c01-39bb-4d15-b554-0287b13806ee",
|
||||
:page 354,
|
||||
:position {:bounding {:x1 0,
|
||||
:y1 669.1428909301758,
|
||||
:x2 816.99169921875,
|
||||
:y2 1127.3214721679688,
|
||||
:width 921.6,
|
||||
:height 1382.4},
|
||||
:rects ({:x1 0,
|
||||
:y1 669.1428909301758,
|
||||
:x2 0,
|
||||
:y2 690.2857475280762,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 633.232177734375,
|
||||
:y1 1086.6339721679688,
|
||||
:x2 816.99169921875,
|
||||
:y2 1106.0625610351562,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 183.3571434020996,
|
||||
:y1 1107.8929138183594,
|
||||
:x2 415.88805770874023,
|
||||
:y2 1127.3214721679688,
|
||||
:width 921.6,
|
||||
:height 1382.4}),
|
||||
:page 354},
|
||||
:content {:text "unpark(threadID) to wake a particular thread"},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "64351ba3-d4b5-4999-bc61-7733d5e0a061",
|
||||
:page 356,
|
||||
:position {:bounding {:x1 569.2232360839844,
|
||||
:y1 702.4732360839844,
|
||||
:x2 751.833984375,
|
||||
:y2 727.6161193847656,
|
||||
:width 921.6,
|
||||
:height 1382.4},
|
||||
:rects ({:x1 569.2232360839844,
|
||||
:y1 702.4732360839844,
|
||||
:x2 751.833984375,
|
||||
:y2 727.6161193847656,
|
||||
:width 921.6,
|
||||
:height 1382.4}),
|
||||
:page 356},
|
||||
:content {:text "wakeup/waiting race"},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "64351e9a-6505-4176-a6fb-ddf63f3245a8",
|
||||
:page 356,
|
||||
:position {:bounding {:x1 471.6607360839844,
|
||||
:y1 1127.5625610351562,
|
||||
:x2 516.3173828125,
|
||||
:y2 1152.7054138183594,
|
||||
:width 921.6,
|
||||
:height 1382.4},
|
||||
:rects ({:x1 471.6607360839844,
|
||||
:y1 1127.5625610351562,
|
||||
:x2 516.3173828125,
|
||||
:y2 1152.7054138183594,
|
||||
:width 921.6,
|
||||
:height 1382.4}),
|
||||
:page 356},
|
||||
:content {:text "futex"},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "64352221-d590-4371-a5f0-29e9cfa75ccb",
|
||||
:page 357,
|
||||
:position {:bounding {:x1 265.9553680419922,
|
||||
:y1 829.5625305175781,
|
||||
:x2 596.0395202636719,
|
||||
:y2 854.7054138183594,
|
||||
:width 921.6,
|
||||
:height 1382.4},
|
||||
:rects ({:x1 379.21429443359375,
|
||||
:y1 829.5625305175781,
|
||||
:x2 596.0395202636719,
|
||||
:y2 854.7054138183594,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 265.9553680419922,
|
||||
:y1 831.1429138183594,
|
||||
:x2 379.2243347167969,
|
||||
:y2 850.5714721679688,
|
||||
:width 921.6,
|
||||
:height 1382.4}),
|
||||
:page 357},
|
||||
:content {:text "Figure 28.10: Linux-based Futex Locks"},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "643522a7-4b16-4998-9b2f-47a852681a16",
|
||||
:page 358,
|
||||
:position {:bounding {:x1 0,
|
||||
:y1 157.14286422729492,
|
||||
:x2 797.6362762451172,
|
||||
:y2 485.67858505249023,
|
||||
:width 921.6,
|
||||
:height 1382.4},
|
||||
:rects ({:x1 0,
|
||||
:y1 157.14286422729492,
|
||||
:x2 0,
|
||||
:y2 178.28571701049805,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 707.2857513427734,
|
||||
:y1 439.2767906188965,
|
||||
:x2 797.6362762451172,
|
||||
:y2 464.41967391967773,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 183.3571548461914,
|
||||
:y1 460.5357322692871,
|
||||
:x2 220.56002044677734,
|
||||
:y2 485.67858505249023,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 183.3571548461914,
|
||||
:y1 463.9643211364746,
|
||||
:x2 220.56002044677734,
|
||||
:y2 483.0893211364746,
|
||||
:width 921.6,
|
||||
:height 1382.4}),
|
||||
:page 358},
|
||||
:content {:text "two-phase lock"},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "6435230e-d84a-4c91-8329-b7608b0d543a",
|
||||
:page 358,
|
||||
:position {:bounding {:x1 0,
|
||||
:y1 189.14286422729492,
|
||||
:x2 797.7836151123047,
|
||||
:y2 524.0535850524902,
|
||||
:width 921.6,
|
||||
:height 1382.4},
|
||||
:rects ({:x1 0,
|
||||
:y1 189.14286422729492,
|
||||
:x2 0,
|
||||
:y2 210.28571701049805,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 498.4398956298828,
|
||||
:y1 483.37502670288086,
|
||||
:x2 797.7836151123047,
|
||||
:y2 502.80358505249023,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 183.3571548461914,
|
||||
:y1 504.62502670288086,
|
||||
:x2 546.6940078735352,
|
||||
:y2 524.0535850524902,
|
||||
:width 921.6,
|
||||
:height 1382.4}),
|
||||
:page 358},
|
||||
:content {:text "in the first phase, the lock spins for a while, hoping that it can acquire the lock."},
|
||||
:properties {:color "yellow"}}
|
||||
{:id #uuid "64352344-d140-468c-987c-e8afa05c2171",
|
||||
:page 358,
|
||||
:position {:bounding {:x1 0,
|
||||
:y1 221.14286422729492,
|
||||
:x2 797.7610244750977,
|
||||
:y2 587.8214378356934,
|
||||
:width 921.6,
|
||||
:height 1382.4},
|
||||
:rects ({:x1 0,
|
||||
:y1 221.14286422729492,
|
||||
:x2 0,
|
||||
:y2 242.2857322692871,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 0,
|
||||
:y1 237.14286422729492,
|
||||
:x2 0,
|
||||
:y2 258.2857322692871,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 298.8221740722656,
|
||||
:y1 525.8750267028809,
|
||||
:x2 797.7419738769531,
|
||||
:y2 545.3036155700684,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 183.3571548461914,
|
||||
:y1 547.1339378356934,
|
||||
:x2 797.7610244750977,
|
||||
:y2 566.5625267028809,
|
||||
:width 921.6,
|
||||
:height 1382.4}
|
||||
{:x1 183.3571548461914,
|
||||
:y1 568.3929100036621,
|
||||
:x2 464.9660415649414,
|
||||
:y2 587.8214378356934,
|
||||
:width 921.6,
|
||||
:height 1382.4}),
|
||||
:page 358},
|
||||
:content {:text " the lock is not acquired during the first spin phase, a second phase is entered, where the caller is put to sleep, and only woken up when the lock becomes free later."},
|
||||
:properties {:color "yellow"}}],
|
||||
:extra {:page 345}}
|
||||
:extra {:page 361}}
|
||||
|
||||
@ -7,6 +7,7 @@ file-path:: ../assets/ostep_1681115599584_0.pdf
|
||||
hl-page:: 311
|
||||
hl-color:: yellow
|
||||
id:: 6433ca28-1bdf-433d-8ed9-0d54bf5ba940
|
||||
collapsed:: true
|
||||
- share the same address space and thus can access the same data
|
||||
- context switch: the address space remains the same
|
||||
hl-page:: 311
|
||||
@ -32,6 +33,7 @@ file-path:: ../assets/ostep_1681115599584_0.pdf
|
||||
hl-page:: 323
|
||||
hl-color:: yellow
|
||||
id:: 6433eabf-48d6-4776-b66f-a5f7804d1ddc
|
||||
collapsed:: true
|
||||
- **indeterminate**: the results depend on the timing execution of the code.
|
||||
- race condition
|
||||
ls-type:: annotation
|
||||
@ -68,6 +70,7 @@ file-path:: ../assets/ostep_1681115599584_0.pdf
|
||||
ls-type:: annotation
|
||||
id:: 6433f35b-403b-4b25-b9f9-076e9e34777e
|
||||
hl-color:: yellow
|
||||
collapsed:: true
|
||||
- `pthread_create` `pthread_join` `pthread_mutex_lock` `pthread_cond_*`
|
||||
- Locks
|
||||
ls-type:: annotation
|
||||
@ -79,6 +82,7 @@ file-path:: ../assets/ostep_1681115599584_0.pdf
|
||||
ls-type:: annotation
|
||||
id:: 6433f4ba-f2e4-4743-a536-e2b7747433b7
|
||||
hl-color:: yellow
|
||||
collapsed:: true
|
||||
- **lock variable**: some type of variable, which holds the *state* of the lock(and maybe additional data such as its holder or a queue for acquisition)
|
||||
- **lock state**: available (or unlocked or free); acquired (or locked or held)
|
||||
- **lock routines**:
|
||||
@ -94,6 +98,7 @@ file-path:: ../assets/ostep_1681115599584_0.pdf
|
||||
hl-page:: 342
|
||||
hl-color:: yellow
|
||||
id:: 6433fbfd-a1bf-4fd9-a54d-e15189c77b15
|
||||
collapsed:: true
|
||||
- For *single-processor* systems, **disable interrupts** for critical sections.
|
||||
- Problems
|
||||
- disable interrupts is privileged. In the worst case, the OS may never regain control when the interrupt isn't going to be enabled.
|
||||
@ -105,6 +110,7 @@ file-path:: ../assets/ostep_1681115599584_0.pdf
|
||||
ls-type:: annotation
|
||||
id:: 6433fe7e-2221-41ee-ad6b-7deaa4459aa5
|
||||
hl-color:: yellow
|
||||
collapsed:: true
|
||||
- use a simple variable (flag) to indicate whether some thread has possession of a lock
|
||||
hl-page:: 343
|
||||
ls-type:: annotation
|
||||
@ -115,19 +121,282 @@ file-path:: ../assets/ostep_1681115599584_0.pdf
|
||||
- Problem
|
||||
- When interrupted between load and test, *mutual exclusion* is broken.
|
||||
- Low efficiency because of spin-waiting.
|
||||
- Spin Locks with Test-And-Set
|
||||
ls-type:: annotation
|
||||
hl-page:: 344
|
||||
hl-color:: yellow
|
||||
id:: 64340154-807c-4a7a-b783-045d5d6d3927
|
||||
- **test-and-set (or atomic exchange) instruction**
|
||||
hl-page:: 344
|
||||
- **spin lock**
|
||||
- ```c
|
||||
void lock(lock_t *lock) {
|
||||
while (TestAndSet(&lock->status, 1) == 1);
|
||||
}
|
||||
void unlock(lock_t *lock) { lock->status = 0; }
|
||||
```
|
||||
- Requires a preemptive scheduler(or it may spin forever)
|
||||
- No fairness guarantee
|
||||
- For single processor systems, terrible performance, because the thread holding the lock cannot make any progress to release the lock until it is scheduled again and thus all other threads waiting for the lock can do nothing but spinning even they are scheduled.
|
||||
- For multi-processor systems, spin lock may work well when thread B on CPU1 waits for thread A on CPU0, and the critical section is short. Because lock owner keeps making progress, spinning doesn't waste many cycles.
|
||||
- **Priority Inversion**: Threads with high priority wait for locks held by threads with low priority.
|
||||
hl-page:: 355
|
||||
ls-type:: annotation
|
||||
id:: 643401e0-fcec-41d3-9898-d5c4175ac464
|
||||
id:: 6435099b-0834-483e-9ef2-98a0b795cf00
|
||||
hl-color:: yellow
|
||||
-
|
||||
Solution: **priority inheritance** or give up the priority?
|
||||
- **Test-And-Set (Atomic Exchange)**
|
||||
hl-page:: 344
|
||||
ls-type:: annotation
|
||||
id:: 643401e0-fcec-41d3-9898-d5c4175ac464
|
||||
hl-color:: yellow
|
||||
collapsed:: true
|
||||
- Returns the old value pointed to by the `old_ptr`, and simultaneously updates said value to `new`.
|
||||
- "test" the old value (which is what is returned) while simultaneously "set" the memory location to a new value
|
||||
- ```c
|
||||
int TestAndSet(int *old_ptr, int new) {
|
||||
int old = *old_ptr;
|
||||
*old_ptr = new;
|
||||
return old;
|
||||
}
|
||||
```
|
||||
- **Compare-And-Swap**
|
||||
hl-page:: 348
|
||||
ls-type:: annotation
|
||||
id:: 6434f8ac-d762-40a4-abb0-2955c2c8b396
|
||||
hl-color:: yellow
|
||||
collapsed:: true
|
||||
- Test whether the value at the address specified by `ptr` is equal to `expected`.
|
||||
hl-page:: 348
|
||||
ls-type:: annotation
|
||||
id:: 6434fab0-08de-4f28-8d8e-f48f7e04aaaa
|
||||
hl-color:: yellow
|
||||
If so, update the memory location with the `new` value.
|
||||
If not, do nothing.
|
||||
Return the old value at the memory location.
|
||||
- ```c
|
||||
int CompareAndSwap(int *ptr, int expected, int new) {
|
||||
int original = *ptr;
|
||||
if (original == expected) *ptr = new;
|
||||
return orginial
|
||||
}
|
||||
```
|
||||
- Compare-and-swap flavor spin lock
|
||||
```C
|
||||
void lock(lock_t *lock) {
|
||||
while (CompareAndSwap(&lock->status, 0, 1) == 1) ;
|
||||
}
|
||||
```
|
||||
- **load-linked** and **store-conditional**
|
||||
hl-page:: 349
|
||||
ls-type:: annotation
|
||||
id:: 6434fde1-9d19-4381-805e-f2a972875dc2
|
||||
hl-color:: yellow
|
||||
collapsed:: true
|
||||
- The **load-linked** operates much like a typical load instruction, and simply fetches a value from memory and places it in a register.
|
||||
ls-type:: annotation
|
||||
hl-page:: 349
|
||||
hl-color:: yellow
|
||||
id:: 6434fe1c-47f3-422c-a317-be72f08d6aef
|
||||
- **store-conditional** only succeeds if no intervening store to the address has taken place.
|
||||
hl-page:: 349
|
||||
ls-type:: annotation
|
||||
id:: 6434fe62-0e92-4414-86cc-b0c37fcf51ec
|
||||
hl-color:: yellow
|
||||
On success, return 1 and update the value at `ptr` to value.
|
||||
On failure, return 0 and the value at `ptr` is not updated.
|
||||
- ```c
|
||||
int LL(int *ptr) { return *ptr; }
|
||||
int SC(int *ptr, int value) {
|
||||
if (/*no update to *ptr since LoadLinked to this address*/) {
|
||||
*ptr = value;
|
||||
return 1; // success!
|
||||
} else {
|
||||
return 0; // failed to update
|
||||
}
|
||||
}
|
||||
```
|
||||
- LL/SC flavor spin lock: very similar to the errant Load/Store lock, but the special instructions here can detect intervening
|
||||
```c
|
||||
void lock(lock_t *lock) {
|
||||
while (true) {
|
||||
while (LL(&lock->status) == 1) ; // test
|
||||
if (SC(&lock->status, 1) == 1) // set
|
||||
break;
|
||||
// else retry, in case lock->status is changed
|
||||
}
|
||||
}
|
||||
```
|
||||
- **Fetch-And-Add**
|
||||
ls-type:: annotation
|
||||
hl-page:: 350
|
||||
hl-color:: yellow
|
||||
id:: 64350170-c853-4080-9ed1-2777ea3a18c8
|
||||
collapsed:: true
|
||||
- Atomically increments a value while returning the old value at a particular address
|
||||
- ```c
|
||||
int FetchAndAdd(int *ptr) {
|
||||
int old = *ptr;
|
||||
*ptr = old + 1;
|
||||
return old;
|
||||
}
|
||||
```
|
||||
- **ticket lock**
|
||||
hl-page:: 351
|
||||
ls-type:: annotation
|
||||
id:: 64350331-8fbb-4c41-9ac1-1a4ba852f772
|
||||
hl-color:: yellow
|
||||
- ```C
|
||||
struct lock_t{
|
||||
int ticket;
|
||||
int turn;
|
||||
};
|
||||
void lock(lock_t *lock) {
|
||||
int myturn = FetchAndAdd(&lock->ticket);
|
||||
// atomically allocate a ticket as the thread's turn
|
||||
while (lock->turn != myturn) ;
|
||||
// wait for its turn
|
||||
}
|
||||
void unlock(lock_t *lock) {
|
||||
lock->turn += 1;
|
||||
}
|
||||
```
|
||||
- Ensure progress for all threads. Once a thread is assigned its ticket value, it will be scheduled at some point in the future (i.e. it will definitely get its turn as `unlock()` operations increase global `turn` value).
|
||||
hl-page:: 351
|
||||
ls-type:: annotation
|
||||
id:: 64350420-ca8a-4cac-af2f-f4e7deb5d1be
|
||||
hl-color:: yellow
|
||||
In contrast, test-and-set spin lock may starve, if it is very unlucky.(never succeeds in contention)
|
||||
- Simple Yield Lock
|
||||
hl-page:: 353
|
||||
ls-type:: annotation
|
||||
id:: 64350781-6995-41db-8b8e-2de0eb84136a
|
||||
hl-color:: yellow
|
||||
collapsed:: true
|
||||
- `yield`: a system call that moves the caller from the running state to the ready state, and thus promotes another thread to running.
|
||||
hl-page:: 353
|
||||
ls-type:: annotation
|
||||
id:: 643507af-1153-46c1-b232-31a9a203e5df
|
||||
hl-color:: yellow
|
||||
- ```C
|
||||
void lock(lock_t *lock) {
|
||||
while (TestAndSet(&lock->status, 1) == 1)
|
||||
yield();
|
||||
}
|
||||
```
|
||||
- Problem: Starvation is still possible; Context switch overhead, though better than spinning
|
||||
- Lock With Queues, Test-and-set, Yield, And Wakeup
|
||||
ls-type:: annotation
|
||||
hl-page:: 354
|
||||
hl-color:: yellow
|
||||
id:: 64350b44-dfae-4544-93f9-ff2b343fefd4
|
||||
- The real problem is: We have not much control over which thread to run next and thus causes potential waste.
|
||||
hl-page:: 353
|
||||
ls-type:: annotation
|
||||
id:: 64350b4e-9559-49d9-aa37-eda9fe425b7f
|
||||
hl-color:: yellow
|
||||
- `park()`: put a calling thread to sleep
|
||||
hl-page:: 354
|
||||
ls-type:: annotation
|
||||
id:: 64350bfb-64f7-4d41-8cc2-260dbec3372d
|
||||
hl-color:: yellow
|
||||
- `unpark(threadID)`: wake a particular thread
|
||||
hl-page:: 354
|
||||
ls-type:: annotation
|
||||
id:: 64350c01-39bb-4d15-b554-0287b13806ee
|
||||
hl-color:: yellow
|
||||
- implement
|
||||
```C
|
||||
struct lock_t{
|
||||
int lk;
|
||||
int guard; // spin lock for the whole lock
|
||||
queue_t *q; // control who gets the lock next
|
||||
};
|
||||
void lock(lock_t *lock) {
|
||||
while (TestAndSet(&m->guard, 1) == 1) ;
|
||||
if (m->lk == 0) {
|
||||
m->lk = 1;
|
||||
m->guard = 0;
|
||||
}
|
||||
else {
|
||||
m->q->add(get_tid());
|
||||
setpark(); // newly added
|
||||
m->guard = 0;
|
||||
// ---- wakeup/waiting race ----
|
||||
park();
|
||||
}
|
||||
}
|
||||
void unlock(lock_t *lock) {
|
||||
while (TestAndSet(&m->guard, 1) == 1) ;
|
||||
if (m->q->empty())
|
||||
m->flag = 0;
|
||||
else
|
||||
unpark(m->q->pop()); // should not clear flag here
|
||||
// Wake up Only one waiting thread
|
||||
m->guard = 0;
|
||||
}
|
||||
```
|
||||
- When a thread is woken up, it will be as if it is returning from `park()`. Thus when `unpark` a thread, pass the lock directly from the thread releasing the lock to the next thread acquiring it; flag is not set to 0 in-between.
|
||||
- wakeup/waiting race: If the thread is scheduled out just before it calls `park`, and then the lock owner calls `unpark` on that thread, it would sleep forever.
|
||||
hl-page:: 356
|
||||
ls-type:: annotation
|
||||
id:: 64351ba3-d4b5-4999-bc61-7733d5e0a061
|
||||
hl-color:: yellow
|
||||
- One solution is to use `setpark()`: indicate the thread is about to `park`. If it happens to be interrupted and another thread calls `unpark` before `park` is actually called, the subsequent park returns immediately instead of sleeping.
|
||||
- Peterson's algorithm: mutual exclusion lock for 2 threads without hardware atomic instruction. Use 2 intention flags and a turn flag.
|
||||
hl-page:: 345
|
||||
ls-type:: annotation
|
||||
id:: 6434edd3-2a7b-4e11-af18-29854e628bc6
|
||||
hl-color:: yellow
|
||||
- **two-phase lock**
|
||||
hl-page:: 358
|
||||
ls-type:: annotation
|
||||
id:: 643522a7-4b16-4998-9b2f-47a852681a16
|
||||
hl-color:: yellow
|
||||
- A combination of spin lock and sleep lock
|
||||
- In the first phase, the lock spins for a while, hoping that it can acquire the lock.
|
||||
hl-page:: 358
|
||||
ls-type:: annotation
|
||||
id:: 6435230e-d84a-4c91-8329-b7608b0d543a
|
||||
hl-color:: yellow
|
||||
- A second phase is entered if the lock is not acquired, where the caller is put to sleep, and only woken up when the lock becomes free later.
|
||||
ls-type:: annotation
|
||||
hl-page:: 358
|
||||
hl-color:: yellow
|
||||
id:: 64352344-d140-468c-987c-e8afa05c2171
|
||||
- Linux System Call **futex**
|
||||
hl-page:: 356
|
||||
ls-type:: annotation
|
||||
id:: 64351e9a-6505-4176-a6fb-ddf63f3245a8
|
||||
hl-color:: yellow
|
||||
- each `futex` is associated with ==a specific physical memory location==, and ==an in-kernel queue==
|
||||
- `futex_wake(address)` wakes one thread that is waiting on the queue.
|
||||
- `futex_wait(address, expected)` puts the calling thread to sleep, assuming the value at `address` is equal to `expected`. If it is not equal, the call returns immediately.
|
||||
- Figure 28.10: Linux-based Futex Locks
|
||||
ls-type:: annotation
|
||||
hl-page:: 357
|
||||
hl-color:: yellow
|
||||
id:: 64352221-d590-4371-a5f0-29e9cfa75ccb
|
||||
- efficacy
|
||||
ls-type:: annotation
|
||||
hl-page:: 341
|
||||
hl-color:: green
|
||||
id:: 6433fb69-1425-46b4-996f-f91da5d3e8d0
|
||||
id:: 6433fb69-1425-46b4-996f-f91da5d3e8d0
|
||||
- foil
|
||||
ls-type:: annotation
|
||||
hl-page:: 347
|
||||
hl-color:: green
|
||||
id:: 6434f523-44b7-40ab-8fea-528969c5acfd
|
||||
- delve
|
||||
ls-type:: annotation
|
||||
hl-page:: 349
|
||||
hl-color:: green
|
||||
id:: 6434fb8c-2b3b-4d80-83fb-3b34da4dcd28
|
||||
- brag
|
||||
ls-type:: annotation
|
||||
hl-page:: 351
|
||||
hl-color:: green
|
||||
id:: 643501c1-f11b-4e85-8125-d2a5a31f69b0
|
||||
- intergalactic
|
||||
ls-type:: annotation
|
||||
hl-page:: 355
|
||||
hl-color:: green
|
||||
id:: 643509b5-12a0-4ed9-8a96-f70b3fc0e373
|
||||
- scourge
|
||||
ls-type:: annotation
|
||||
hl-page:: 355
|
||||
hl-color:: green
|
||||
id:: 643509ba-662e-4d0a-906a-fd0987e24574
|
||||
Loading…
Reference in New Issue
Block a user