1349 // ... we spin for a short while...
1350 os::sleep(tid, sleep_time_millis, false);
1351 if (_overflow_list == NULL) {
1352 // nothing left to take
1353 return false;
1354 } else if (_overflow_list != BUSY) {
1355 // try and grab the prefix
1356 prefix = cast_to_oop(Atomic::xchg_ptr(BUSY, &_overflow_list));
1357 }
1358 }
1359 if (prefix == NULL || prefix == BUSY) {
1360 // Nothing to take or waited long enough
1361 if (prefix == NULL) {
1362 // Write back the NULL in case we overwrote it with BUSY above
1363 // and it is still the same value.
1364 (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
1365 }
1366 return false;
1367 }
1368 assert(prefix != NULL && prefix != BUSY, "Error");
1369 size_t i = 1;
1370 oop cur = prefix;
1371 while (i < objsFromOverflow && cur->klass_or_null() != NULL) {
1372 i++; cur = cur->list_ptr_from_klass();
1373 }
1374
1375 // Reattach remaining (suffix) to overflow list
1376 if (cur->klass_or_null() == NULL) {
1377 // Write back the NULL in lieu of the BUSY we wrote
1378 // above and it is still the same value.
1379 if (_overflow_list == BUSY) {
1380 (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
1381 }
1382 } else {
1383 assert(cur->klass_or_null() != (Klass*)(address)BUSY, "Error");
1384 oop suffix = cur->list_ptr_from_klass(); // suffix will be put back on global list
1385 cur->set_klass_to_list_ptr(NULL); // break off suffix
1386 // It's possible that the list is still in the empty(busy) state
1387 // we left it in a short while ago; in that case we may be
1388 // able to place back the suffix.
1389 oop observed_overflow_list = _overflow_list;
1390 oop cur_overflow_list = observed_overflow_list;
1391 bool attached = false;
1392 while (observed_overflow_list == BUSY || observed_overflow_list == NULL) {
1393 observed_overflow_list =
1394 (oop) Atomic::cmpxchg_ptr(suffix, &_overflow_list, cur_overflow_list);
1395 if (cur_overflow_list == observed_overflow_list) {
1396 attached = true;
1397 break;
1398 } else cur_overflow_list = observed_overflow_list;
1399 }
1400 if (!attached) {
1401 // Too bad, someone else got in in between; we'll need to do a splice.
1402 // Find the last item of suffix list
1403 oop last = suffix;
1404 while (last->klass_or_null() != NULL) {
1405 last = last->list_ptr_from_klass();
1406 }
1407 // Atomically prepend suffix to current overflow list
1408 observed_overflow_list = _overflow_list;
1409 do {
1410 cur_overflow_list = observed_overflow_list;
1411 if (cur_overflow_list != BUSY) {
1412 // Do the splice ...
1413 last->set_klass_to_list_ptr(cur_overflow_list);
1414 } else { // cur_overflow_list == BUSY
1415 last->set_klass_to_list_ptr(NULL);
1416 }
1417 observed_overflow_list =
1418 (oop)Atomic::cmpxchg_ptr(suffix, &_overflow_list, cur_overflow_list);
1419 } while (cur_overflow_list != observed_overflow_list);
1420 }
1421 }
1422
1423 // Push objects on prefix list onto this thread's work queue
1424 assert(prefix != NULL && prefix != BUSY, "program logic");
1425 cur = prefix;
|
1349 // ... we spin for a short while...
1350 os::sleep(tid, sleep_time_millis, false);
1351 if (_overflow_list == NULL) {
1352 // nothing left to take
1353 return false;
1354 } else if (_overflow_list != BUSY) {
1355 // try and grab the prefix
1356 prefix = cast_to_oop(Atomic::xchg_ptr(BUSY, &_overflow_list));
1357 }
1358 }
1359 if (prefix == NULL || prefix == BUSY) {
1360 // Nothing to take or waited long enough
1361 if (prefix == NULL) {
1362 // Write back the NULL in case we overwrote it with BUSY above
1363 // and it is still the same value.
1364 (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
1365 }
1366 return false;
1367 }
1368 assert(prefix != NULL && prefix != BUSY, "Error");
1369 oop cur = prefix;
1370 for (size_t i = 1; i < objsFromOverflow; ++i) {
1371 oop next = cur->list_ptr_from_klass();
1372 if (next == NULL) break;
1373 cur = next;
1374 }
1375 assert(cur != NULL, "Loop postcondition");
1376
1377 // Reattach remaining (suffix) to overflow list
1378 oop suffix = cur->list_ptr_from_klass();
1379 if (suffix == NULL) {
1380 // Write back the NULL in lieu of the BUSY we wrote
1381 // above and it is still the same value.
1382 if (_overflow_list == BUSY) {
1383 (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
1384 }
1385 } else {
1386 assert(suffix != BUSY, "Error");
1387 // suffix will be put back on global list
1388 cur->set_klass_to_list_ptr(NULL); // break off suffix
1389 // It's possible that the list is still in the empty(busy) state
1390 // we left it in a short while ago; in that case we may be
1391 // able to place back the suffix.
1392 oop observed_overflow_list = _overflow_list;
1393 oop cur_overflow_list = observed_overflow_list;
1394 bool attached = false;
1395 while (observed_overflow_list == BUSY || observed_overflow_list == NULL) {
1396 observed_overflow_list =
1397 (oop) Atomic::cmpxchg_ptr(suffix, &_overflow_list, cur_overflow_list);
1398 if (cur_overflow_list == observed_overflow_list) {
1399 attached = true;
1400 break;
1401 } else cur_overflow_list = observed_overflow_list;
1402 }
1403 if (!attached) {
1404 // Too bad, someone else got in in between; we'll need to do a splice.
1405 // Find the last item of suffix list
1406 oop last = suffix;
1407 while (true) {
1408 oop next = last->list_ptr_from_klass();
1409 if (next == NULL) break;
1410 last = next;
1411 }
1412 // Atomically prepend suffix to current overflow list
1413 observed_overflow_list = _overflow_list;
1414 do {
1415 cur_overflow_list = observed_overflow_list;
1416 if (cur_overflow_list != BUSY) {
1417 // Do the splice ...
1418 last->set_klass_to_list_ptr(cur_overflow_list);
1419 } else { // cur_overflow_list == BUSY
1420 last->set_klass_to_list_ptr(NULL);
1421 }
1422 observed_overflow_list =
1423 (oop)Atomic::cmpxchg_ptr(suffix, &_overflow_list, cur_overflow_list);
1424 } while (cur_overflow_list != observed_overflow_list);
1425 }
1426 }
1427
1428 // Push objects on prefix list onto this thread's work queue
1429 assert(prefix != NULL && prefix != BUSY, "program logic");
1430 cur = prefix;
|