* tsd_remove_entry - remove a tsd entry for this thread * @entry: entry to remove * * Remove the thread specific data @entry for this thread. * If this is the last entry for this thread, also remove the PID entry. */
| 398 | * If this is the last entry for this thread, also remove the PID entry. |
| 399 | */ |
| 400 | static void |
| 401 | tsd_remove_entry(tsd_hash_entry_t *entry) |
| 402 | { |
| 403 | HLIST_HEAD(work); |
| 404 | tsd_hash_table_t *table; |
| 405 | tsd_hash_entry_t *pid_entry; |
| 406 | tsd_hash_bin_t *pid_entry_bin, *entry_bin; |
| 407 | ulong_t hash; |
| 408 | |
| 409 | table = tsd_hash_table; |
| 410 | ASSERT3P(table, !=, NULL); |
| 411 | ASSERT3P(entry, !=, NULL); |
| 412 | |
| 413 | spin_lock(&table->ht_lock); |
| 414 | |
| 415 | hash = hash_long((ulong_t)entry->he_key * |
| 416 | (ulong_t)entry->he_pid, table->ht_bits); |
| 417 | entry_bin = &table->ht_bins[hash]; |
| 418 | |
| 419 | /* save the possible pid_entry */ |
| 420 | pid_entry = list_entry(entry->he_pid_list.next, tsd_hash_entry_t, |
| 421 | he_pid_list); |
| 422 | |
| 423 | /* remove entry */ |
| 424 | spin_lock(&entry_bin->hb_lock); |
| 425 | tsd_hash_del(table, entry); |
| 426 | hlist_add_head(&entry->he_list, &work); |
| 427 | spin_unlock(&entry_bin->hb_lock); |
| 428 | |
| 429 | /* if pid_entry is indeed pid_entry, then remove it if it's empty */ |
| 430 | if (pid_entry->he_key == PID_KEY && |
| 431 | list_empty(&pid_entry->he_pid_list)) { |
| 432 | hash = hash_long((ulong_t)pid_entry->he_key * |
| 433 | (ulong_t)pid_entry->he_pid, table->ht_bits); |
| 434 | pid_entry_bin = &table->ht_bins[hash]; |
| 435 | |
| 436 | spin_lock(&pid_entry_bin->hb_lock); |
| 437 | tsd_hash_del(table, pid_entry); |
| 438 | hlist_add_head(&pid_entry->he_list, &work); |
| 439 | spin_unlock(&pid_entry_bin->hb_lock); |
| 440 | } |
| 441 | |
| 442 | spin_unlock(&table->ht_lock); |
| 443 | |
| 444 | tsd_hash_dtor(&work); |
| 445 | } |
| 446 | |
| 447 | /* |
| 448 | * tsd_set - set thread specific data |
no test coverage detected