What is the use of 3 bits promo_bits in the java obj header - hotspot

The source code of the hotspot define the obj markword as markOop,in it's Annotation,the markword has the status as follow:
// 32 bits:
// --------
// hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object)
// JavaThread*:23 epoch:2 age:4 biased_lock:1 lock:2 (biased object)
// size:32 ------------------------------------------>| (CMS free block)
// PromotedObject*:29 ---------->| promo_bits:3 ----->| (CMS promoted object)
//
// 64 bits:
// --------
// unused:25 hash:31 -->| unused:1 age:4 biased_lock:1 lock:2 (normal object)
// JavaThread*:54 epoch:2 unused:1 age:4 biased_lock:1 lock:2 (biased object)
// PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object)
// size:64 ----------------------------------------------------->| (CMS free block)
//
// --------
// unused:25 hash:31 -->| cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && normal object)
// JavaThread*:54 epoch:2 cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && biased object)
// narrowOop:32 unused:24 cms_free:1 unused:4 promo_bits:3 ----->| (COOPs && CMS promoted object)
// unused:21 size:35 -->| cms_free:1 unused:7 ------------------>| (COOPs && CMS free block)
it say that when the lock Promoted,the markOop is contain of (61 bits of the PromotedObject ptr,and 3 bits of the promo_bits).
but i find the diff statement in openJdk wiki:https://wiki.openjdk.java.net/display/HotSpot/Synchronization
in this wiki ,it say that when the lock promoted,the markOop is contain of (62 bits of the PromotedObject and 2 bit of lock status).
I don't know what is correct.
my question is: if the sourceCode Annotation is correct, What is the use of 3 promo_bits in the java obj header

Related

What is the problem of two each codes that can't maintain the counter value consistency

Here is TAS code
boolean TAS(*target)
{
boolean rv = *target; //Save the initial value
*target = true; //Set lock
return rv; //Return initial value
}
The following codes means two different tries for the increment operation on a thread safe counter using tas to maintain the counter value consistency.
code 1.
Counter::Increment() {
while (TAS(&lock)) ;
value++;
lock = FREE;
memory_barrier();
}
code 2.
Counter::Increment() {
while (lock == BUSY && TAS(&lock)) ;
value++;
lock = FREE;
memory_barrier();
}
What will be the issue of each codes that cannot handle consistency
Assuming that FREE == false and BUSY == true, here is a flow which breaks mutual exclusion:
Start thread 1:
Increment
TAS
rv = *lock; // FREE
Switch to thread 2:
Increment
TAS
rv = *lock; // FREE
*lock = BUSY;
return rv; // FREE
Load value 0 from memory and push it into the stack
Switch to thread 1:
*lock = BUSY;
return rv; // FREE
Load value 0 from memory and push it into the stack
Push 1 into the stack
Pop two integers from the stack and add them
Store the result (0 + 1) into value
Switch to thread 2:
Push 1 into the stack
Pop two integers from the stack and add them
Store the result (0 + 1) into value

How to programmatically detect the memory size/page number of an NFC chip

What is the easiest way to programmatically detect the memory size or page count of an NFC chip (MIFARE Ultralight or NTAGxxx) other than probing for specific page numbers and checking if they exist?
Is there a specific byte in the ATR returned or somewhere stored in the protected zone of the chip's memory that tells whether it's a specific NTAGxxx chip, or the page count or the byte count?
In general you can only determine this by extensive fingerprinting and by probing with read commands.
Fingerprinting: This means that you would need to have a database of manufacturer-specific characteristics (e.g. collected from datasheets and -- unfortunately by far more often -- from empirical testing, as such information is not (publicly? or at all?) documented for most tags) that you can check your tag against.
Probing:
Start at page 0
Read page
On success: increment read address by 4 pages and start over
On failure: decrement read address by 1 and try to read again until you find a readable address
On sector end: start over with next sector
That way you can find the last readable page address, which is not necessarily the "real" end of the tag memory (e.g. there might be protected pages at the end).
If your Ultralight and NTAG tags are EV1 tags (i.e. they implement the Ultralight EV1 command set), the expose a GET_VERSION command which you can use to retrieve storage size information. The version information in combination with a database of all existing tag fingerprints (you can get that information from the Ultraight/NTAG datasheets) will allow you to reliably1 determine the tag type and, consequently, the memory size.
1) With the exception of some counterfeit chips sold as "NTAG" that imitate parameters of real NTAG chips but seem to have memory sizes, lack of command support, etc. that do not match the chip of which they imitate the parameters.
When it comes to NFC tags that follow the NFC Forum Type 2 tag operation specifications, you could also rely on the tag memory size that is coded into the capability container. This memory size is not necessarily the physical memory size though.
I think, from the accepted answer the below code make sense,
int numberOfPages = 0;
int tagType = ulTag.getType();
if(tagType == MifareUltralight.TYPE_ULTRALIGHT) {
numberOfPages = 16;
} else if(tagType == MifareUltralight.TYPE_ULTRALIGHT_C) {
numberOfPages = 47;
}
The getMaxTransceiveLength() is to retrieve the maximum amount of bytes that can be sent with transceive(byte[]).
Transceive command use first 3 bytes for Flags, Command and Page number respectively.
We need to check the below code working or not ?
int totalBytes = ulTag.getMaxTransceiveLength() + 3;
int totalPages = totalBytes / ulTag.PAGE_SIZE;
for MIFARE ULTRALIGHT you can check version in this way.
public static final int OFFSET_128_BYTE = 0x025;
public static final int OFFSET_48_BYTE = 0x010;
public static int checkType(MifareUltralight mrfid){
int cfgOffset = -1;
byte[] response = null;
byte[] writeResponse = null;
try {
response = mrfid.transceive(new byte[]{
(byte) 0x60 // GET_VERSION
});
} catch (TagLostException tle) {
Utility.log("setPasswordAndEnable GET_VERSION, TagLostException ... ");
return cfgOffset;
} catch (IOException ioe) {
Utility.log("setPasswordAndEnable GET_VERSION, IOException ... ");
return cfgOffset;
}
if ((response != null) && (response.length >= 8)) {
// success
if ((response[0] == (byte) 0x00) && (response[1] == (byte) 0x04)) {
// tag is from NXP
if (response[2] == (byte) 0x03) {
// MIFARE Ultralight
if ((response[4] == (byte) 0x01) && (response[5] == (byte) 0x00)) {
// MIFARE Ultralight EV1 (V0)
switch (response[6]) {
case (byte) 0x0B:
// MF0UL11
cfgOffset = OFFSET_48_BYTE;
break;
case (byte) 0x0E:
// MF0UL21
cfgOffset = OFFSET_128_BYTE;
break;
default:
// unknown
break;
}
}
}
}
}
return cfgOffset;
}

Erasing page on stm32 fails with FLASH_ERROR_WRP

I am trying to erase one page in flash on an STM32F103RB like so:
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR | FLASH_FLAG_OPTERR);
FLASHStatus = FLASH_ErasePage(Page);
However, FLASH_ErasePage fails producing FLASH_ERROR_WRP
Manually enabling/disabling write protection in the stm32-linker tool doesn't fix the problem.
Basically FLASH_ErasePage fails with WRP error without trying to do anything if there's previous WRP error in the status register.
What comes to your FLASH_ClearFlag call, at least FLASH_FLAG_BSY will cause assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)); to fail (though I'm not really sure what happens in this case).
#define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFC0FD) == 0x00000000) && ((FLAG) != 0x00000000))
What is your page address ? Which address are you trying to access ?
For instance, this example is tested on STM32F100C8 in terms of not only erasing but also writing data correctly.
http://www.ozturkibrahim.com/TR/eeprom-emulation-on-stm32/
If using the HAL driver, your code might look like this (cut'n paste from an real project)
static HAL_StatusTypeDef Erase_Main_Program ()
{
FLASH_EraseInitTypeDef ins;
uint32_t sectorerror;
ins.TypeErase = FLASH_TYPEERASE_SECTORS;
ins.Banks = FLASH_BANK_1; /* Do not care, used for mass-erase */
#warning We currently erase from sector 2 (only keep 64KB of flash for boot))
ins.Sector = FLASH_SECTOR_4;
ins.NbSectors = 4;
ins.VoltageRange = FLASH_VOLTAGE_RANGE_3; /* voltage-range defines how big blocks can be erased at the same time */
return HAL_FLASHEx_Erase (&ins, &sectorerror);
}
The internal function in the HAL driver that actually does the work
void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange)
{
uint32_t tmp_psize = 0U;
/* Check the parameters */
assert_param(IS_FLASH_SECTOR(Sector));
assert_param(IS_VOLTAGERANGE(VoltageRange));
if(VoltageRange == FLASH_VOLTAGE_RANGE_1)
{
tmp_psize = FLASH_PSIZE_BYTE;
}
else if(VoltageRange == FLASH_VOLTAGE_RANGE_2)
{
tmp_psize = FLASH_PSIZE_HALF_WORD;
}
else if(VoltageRange == FLASH_VOLTAGE_RANGE_3)
{
tmp_psize = FLASH_PSIZE_WORD;
}
else
{
tmp_psize = FLASH_PSIZE_DOUBLE_WORD;
}
/* If the previous operation is completed, proceed to erase the sector */
CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
FLASH->CR |= tmp_psize;
CLEAR_BIT(FLASH->CR, FLASH_CR_SNB);
FLASH->CR |= FLASH_CR_SER | (Sector << POSITION_VAL(FLASH_CR_SNB));
FLASH->CR |= FLASH_CR_STRT;
}
Second thing to check. Is interrupts enabled, and is there any hardware access between the unlock call and the erase call?
I hope this helps

Subtracting using minus function in alloy

I have created a vending machine it works fine. I want to subtract 1 from the quantity of items once the transaction is completed. I have provided comments in my code for understanding. Ignore some of the comments in pred chocolate. Somehow I am trying to subtract but it just wont. I don't know what seems to be the problem. Any help is appreciated .
sig button {
qty:Int} // buttons on vending machine for selecting chocolates
//sig coin{}
sig choco{
value:Int, // Each chocolate has some cost as an attribute aka value.
choice :one button // Selecting option
}
fact {
// all c:choco | all c1:choco -c | c1.choice != c.choice
}
sig machine{
cust : one customer, // Customer entity
a,b,c,d,nullb ,ip: one button, // buttons on vending machine ,ip is the input selected by user
//oners,twors,fivers ,tenrs,null1: set coin,
ipp,opc2 : one Coin, // ipp = input rs , opc = balance rs
customeripb: cust one -> one ip, // customer presses a button
customeripc: cust one -> one ipp, // customer enters coins
customeropc: opc2 one -> one cust, //customer receives balance of coins
op: one choco , // output of chocolate from machine
customerop: op one -> one cust, // customer receives a chocolate
cadbury, kitkat, eclairs , gum,null: lone choco // types of chocolate
}
{
//#(fivers+tenrs+null+twors+oners) = 5
#(a+b+c+d) = 4 // no of buttons of a b c and d are 4 on machine
# (cadbury+kitkat+ eclairs +gum) =4 // no of options to choose = 4
cadbury=choice.a // cadbury corresponds to button a
cadbury.value= 10 // cadbury costs 10rs
kitkat=choice.b // kitkat corresponds to button b
kitkat.value=5 // kitkat costs 5rs
null.value=0 // null costs 0 rs
null=choice.nullb
// as such null doesnt exist it is just to specify no i/p no o/p and nulb is an imaginary button
eclairs=choice.c // eclairs corresponds to button c
eclairs.value=1 // eclairs costs 1 rs
gum=choice.d // gum corresponds to button d
gum.value=2 // gum costs 1 rs
a.qty>=10 and a.qty<=40
b.qty>=11 and b.qty<=40
c.qty>=12 and c.qty<=40
d.qty>=13 and d.qty<=40
nullb.qty=0
//ip=nullb //input button selection is never nullb(which is imaginary button)
ipp.value!=0 // input of coins is never = 0rs
/* all m:machine|all o:opc2
|all opp: op| all i:ip|all ii:ipp| all c:m.cust
|c -> i in m.customeripb and c->ii in m.customeripc and o->c in m.customerop and opp->c in m.customerop
*/
//button=!=none
}
sig customer //user of machine
{
}
abstract sig Coin { //each coin has a valueof rs
value: Int
}
sig Nullrs extends Coin {} { value = 0 } // void rs
sig Oners extends Coin {} { value = 1 } // one rs
sig Twors extends Coin {} { value = 2 } // twors
sig Fivers extends Coin {}{ value = 5 } // five rs
sig Tenrs extends Coin {} { value = 10 } // ten rs
sig Threers extends Coin {} { value = 3 } // this is only used in o/p to specify 3rs will come out
sig Fourrs extends Coin {} { value = 4 }// this is only used in o/p to specify 4rs will come out
sig Sixrs extends Coin {} { value = 6 }// this is only used in o/p to specify 6rs will come out
sig Sevenrs extends Coin {}{ value = 7 }// this is only used in o/p to specify 7rs will come out
sig Eightrs extends Coin {} { value = 8 } // this is only used in o/p to specify 8rs will come out
sig Niners extends Coin {} { value = 9} //// this is only used in o/p to specify 9rs will come out
pred show{} // show
pred chocolate [before,after:machine ] // machine has two states one before o/p and one after
{
before.cadbury=after.cadbury
before.kitkat=after.kitkat
before.eclairs=after.eclairs
before.gum=after.gum
//all chocolates will not change and are fixed
before.ipp.value=after.ipp.value
// input value of rs remains same i.e i/p is inside machine once inputed so it cant change
before.opc2.value=0 // before state o/p value of balance coins =0
before.op=before.null // beforestate o/p = no chocolate
before.ip!=before.nullb // input button pressed never equals nullb
after.ip!=after.nullb // input button pressed never equals nullb
//before.ip=after.ip // input button pressed remains same
after.op=after.kitkat or after.op=after.eclairs
before.null=after.null // imaginary null chocolate remains in same state
before.opc2!=none and after.opc2 !=none
// balance of coins is never empty in case of empty I have defined nullrs
(after.op.value=before.ipp.value=>after.opc2.value=0)
//
(after.op=after.null=>after.opc2.value=before.ipp.value)
(before.ipp.value > after.op.value=>after.opc2.value=before.ipp.value-after.op.value)
//(before.ipp.value=after.op.value=>after.opc2.value=0)
//opc2.value!=ipp.value
before.ip=before.a or before.ip=before.b or before.ip=before.c or before.ip=before.d
(after.op=after.cadbury ) => ( ( after.ip=after.a and after.a.qty=minus[before.a.qty,1])) else
(after.op=after.kitkat ) => ( (after.ip=after.b and after.b.qty=minus[before.b.qty, 1])) else
(after.op=after.eclairs ) =>( (after.ip=after.c and after.c.qty=minus[before.c.qty,1])) else
(after.op=after.gum ) =>((after.ip=after.d and after.d.qty=minus[before.d.qty,1])) else
(after.ip=before.ip and after.ip.qty=minus[before.ip.qty,0] )
after.op!=before.null => after.op.choice=before.ip
(after.op=before.gum=>before.ipp.value>=Twors.value)
after.op=before.cadbury=>before.ipp.value>=Tenrs.value
after.op=before.eclairs=>before.ipp.value>=Oners.value
after.op=before.kitkat=>before.ipp.value>=Fivers.value
(before.ipp=Oners or before.ipp=Twors or before.ipp=Fivers or before.ipp=Tenrs or before.ipp=Nullrs) and
before.ipp!=Threers and before.ipp!=Fourrs and before.ipp !=Sixrs and before.ipp!=Sevenrs and before.ipp!=Eightrs and before.ipp!=Niners
(before.ip=before.b and before.ipp.value < 5) => (after.op!=before.kitkat or after.op!=before.eclairs or after.op!=before.cadbury or after.op!=before.gum)and after.op=before.null
(before.ip=before.d and before.ipp.value < 2) => (after.op!=before.kitkat or after.op!=before.eclairs or after.op!=before.cadbury or after.op!=before.gum)and after.op=before.null
(before.ip=before.a and before.ipp.value < 10 )=> (after.op!=before.kitkat or after.op!=before.eclairs or after.op!=before.cadbury or after.op!=before.gum) and after.op=before.null
(before.ip=before.c and before.ipp.value >= 1) => (after.op!=before.kitkat or after.op!=before.null or after.op!=before.cadbury or after.op!=before.gum) and after.op=before.eclairs
(before.ip=before.c and before.ipp.value = 0) => (after.op!=before.kitkat or after.op!=before.null or after.op!=before.cadbury or after.op!=before.gum) and after.op=before.null
(before.ip=before.a and before.ipp.value =10) => (after.op!=before.kitkat or after.op!=before.null or after.op!=before.eclairs or after.op!=before.gum) and after.op= before.cadbury
(before.ip=before.d and before.ipp.value >= 2) => (after.op!=before.kitkat or after.op!=before.null or after.op!=before.cadbury or after.op!=before.eclairs) and after.op=before.gum
(before.ip=before.b and before.ipp.value >= 5) => (after.op!=before.eclairs or after.op!=before.null or after.op!=before.cadbury or after.op!=before.gum) and after.op=before.kitkat
}
run chocolate for exactly 2 machine, 8 button, 5 choco,9 Int,5 Coin,1 customer
In general, it would make sense to be more specific than "it doesn't work".
I'm assuming that what you mean by "it doesn't work" is that in the after machine you expect the quantity of the selected chocolate to be decreased by 1, but instead, it stays the same. The reason for that is your (if-then-else) or (if-then-else) or ... expression, which is logically flawed. What you probably wanted to express is to enforce at least one then branch (because you know that exactly one if condition will be satisfied), but that is not necessary to satisfy this whole disjunction.
More concretely, in
((after.op=after.cadbury)
=> (... and after.a.qty=minus[before.a.qty,1] and ...)
else (... and after.a.qty=before.a.qty and ...)
)
or
((after.op=after.kitkat)
=> (... and after.b.qty=minus[before.b.qty,1] and ...)
else (... and after.b.qty=before.b.qty and ...)
)
even if after.op is equal to after.cadbury, that does not enforce the then branch of that clause to be true, because to satisfy this whole expression, it is enough to satisfy the else branch of the next clause, which says that all quantities should stay the same.
What you want is some soft of if-then-elsif-...-else construct, e.g.,
(after.op = after.cadbury) => {
...
} else (after.op = after.kitkat) => {
...
} else {
...
}
If you do that, your machine will still not work, that is, your model will become unsatisfiable: your constraints enforce that both after and before machines share the same buttons1 and quantities are associated with buttons (the qty field is in the button sig), which means that quantities must be the same in both after and before machines. I don't really see any good reason to put qty in sig button.
[1]: by having before.cadbury=after.cadbury and ... in your chocolate predicate, and cadbury=choice.a and ... in your appended facts for sig machine

Optimal IP subnet matching

The following code appears to be the hottest spot in my program.
JAVA_OPTS=-Xprof output:
Compiled + native Method
5.7% 173 + 0 scala.collection.IndexedSeqOptimized$class.slice
5.1% 156 + 0 scala.collection.IndexedSeqOptimized$class.foreach
2.9% 87 + 0 java.util.regex.Pattern$BmpCharProperty.match
2.5% 76 + 0 scala.collection.IndexedSeqOptimized$class.sameElements
2.4% 73 + 0 trafacct.SubNet.contains
Slice, sameElements and even foreach calls seem to be most used from here too. Can someone give an advice or two on how to optimize contains() method? Maybe some techniques allowing Bytes analysis without converting them to integers? Or solid whole-sequence approach without slice?
Function SubNet.contains() matches an IP address against subnet.
object SubNet {
def toInts(bytes: Seq[Byte]): Seq[Int] = bytes.map(_.toInt & 0xFF)
}
case class SubNet(ip:InetAddress, maskLength:Int) extends HostCategory {
import SubNet.toInts
private val bytes: Int = maskLength / 8
private val subnet = toInts(ip.getAddress)
private val bits = bytes * 8 - maskLength
def contains(host: Host) = {
if (host.ip == null && ip == null) {
true
} else if (this.ip == null) {
false
} else {
val address = toInts(host.ip.getAddress)
if (address.length != subnet.length) {
false
} else {
if (address.slice(0, bytes) != subnet.slice(0, bytes)) {
false
} else {
((address(bytes) >> (8-bits) ^ subnet(bytes) >> (8-bits)) & 0xFF) == 0
}
}
}
}
}
I understand, that this optimization won't give me much better throughput, I just feel that I'm doing something wrong spending so much time inside this simple function.
This code should be IPv6 (16 bytes) compatible, and I don't like the idea of handling IPv4 case separately.
You're not doing anything wrong per se; you're just using collections that are meant for ease of use not performance when handling primitives.
If you want to speed this up, you'll get the largest boost by switching to using arrays and while loops. It's not entirely clear to me that the code you wrote even works for IPv6 except for IPv4 addresses stored in IPv6 format, since you could have a subnet with more than 256 items. Also, by testing lengths you're assuming no mixed IPv6/IPv4 representations of the same address.
I'd forget the whole "toInts" thing and just store byte arrays; then do something like (warning, untested)
def contains(host: Host): Boolean = {
//...
if (address.length != subnet.length) false
else {
var i = 0
while (i<address.length-1) {
if (address(i) != subnet(i)) return false
i += 1
}
(address(i)&0xFF) >> (8-bits) ^ (subnet(i)&0xFF) >> (8-bits) == 0
}
}
It's really not any more complicated than your original solution, and should run ~10x faster.
With this code, it does not validate correctly.
For example:
scala> val ip = java.net.InetAddress.getByName("::ffff:1.2.176.0")
ip: java.net.InetAddress = /1.2.176.0
scala> val prefix = new InetPrefix(ip, 20)
prefix: InetPrefix = InetPrefix#6febf6f9
scala> prefix.contains(java.net.InetAddress.getByName("::ffff:1.2.176.20"))
res11: Boolean = true
scala> prefix.contains(java.net.InetAddress.getByName("::ffff:1.2.191.20"))
res12: Boolean = false
But if you calculate that network: (1.2.176.0/20)
$ sipcalc 1.2.176.0/20
-[ipv4 : 1.2.176.0/20] - 0
[CIDR]
Host address - 1.2.176.0
Host address (decimal) - 16953344
Host address (hex) - 102B000
Network address - 1.2.176.0
Network mask - 255.255.240.0
Network mask (bits) - 20
Network mask (hex) - FFFFF000
Broadcast address - 1.2.191.255
Cisco wildcard - 0.0.15.255
Addresses in network - 4096
Network range - 1.2.176.0 - 1.2.191.255
Usable range - 1.2.176.1 - 1.2.191.254
-
I rewrote both (IPv4 and IPv6) in Scala put it for everyone on GitHub. It now also validates within ranges (so /20 etc will be regarded, which the old one did not do.)
You can find the code (i separated it into IPv4 and IPv6) at https://github.com/wasted/scala-util/blob/master/src/main/scala/io/wasted/util/InetPrefix.scala
I also created a blogpost about this.