MCPcopy Create free account
hub / github.com/Meituan-Dianping/SQLAdvisor / link_block

Function link_block

mysys/mf_keycache.c:1110–1210  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1108*/
1109
1110static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot,
1111 my_bool at_end)
1112{
1113 BLOCK_LINK *ins;
1114 BLOCK_LINK **pins;
1115
1116 DBUG_ASSERT((block->status & ~BLOCK_CHANGED) == (BLOCK_READ | BLOCK_IN_USE));
1117 DBUG_ASSERT(block->hash_link); /*backptr to block NULL from free_block()*/
1118 DBUG_ASSERT(!block->requests);
1119 DBUG_ASSERT(block->prev_changed && *block->prev_changed == block);
1120 DBUG_ASSERT(!block->next_used);
1121 DBUG_ASSERT(!block->prev_used);
1122
1123 if (!hot && keycache->waiting_for_block.last_thread)
1124 {
1125 /* Signal that in the LRU warm sub-chain an available block has appeared */
1126 struct st_my_thread_var *last_thread=
1127 keycache->waiting_for_block.last_thread;
1128 struct st_my_thread_var *first_thread= last_thread->next;
1129 struct st_my_thread_var *next_thread= first_thread;
1130 HASH_LINK *hash_link= (HASH_LINK *) first_thread->opt_info;
1131 struct st_my_thread_var *thread;
1132 do
1133 {
1134 thread= next_thread;
1135 next_thread= thread->next;
1136 /*
1137 We notify about the event all threads that ask
1138 for the same page as the first thread in the queue
1139 */
1140 if ((HASH_LINK *) thread->opt_info == hash_link)
1141 {
1142 KEYCACHE_DBUG_PRINT("link_block: signal", ("thread %ld", thread->id));
1143 keycache_pthread_cond_signal(&thread->suspend);
1144 unlink_from_queue(&keycache->waiting_for_block, thread);
1145 block->requests++;
1146 }
1147 }
1148 while (thread != last_thread);
1149 hash_link->block= block;
1150 /*
1151 NOTE: We assigned the block to the hash_link and signalled the
1152 requesting thread(s). But it is possible that other threads runs
1153 first. These threads see the hash_link assigned to a block which
1154 is assigned to another hash_link and not marked BLOCK_IN_SWITCH.
1155 This can be a problem for functions that do not select the block
1156 via its hash_link: flush and free. They do only see a block which
1157 is in a "normal" state and don't know that it will be evicted soon.
1158
1159 We cannot set BLOCK_IN_SWITCH here because only one of the
1160 requesting threads must handle the eviction. All others must wait
1161 for it to complete. If we set the flag here, the threads would not
1162 know who is in charge of the eviction. Without the flag, the first
1163 thread takes the stick and sets the flag.
1164
1165 But we need to note in the block that is has been selected for
1166 eviction. It must not be freed. The evicting thread will not
1167 expect the block in the free list. Before freeing we could also

Callers 1

unreg_requestFunction · 0.85

Calls 2

unlink_from_queueFunction · 0.85

Tested by

no test coverage detected