rem: atomic_add(&sUsedPorts, -1); return B_NO_MEMORY;
add: status = B_NO_MEMORY; goto err1;
context: create_port(int32 queueLength, const char *name){	cpu_status state;	char nameBuffer[B_OS_NAME_LENGTH];	sem_id readSem, writeSem;	port_id returnValue;	team_id	owner;	int i;	if (!sPortsActive)		return B_BAD_PORT_ID;	// check queue length	if (queueLength < 1		|| queueLength > MAX_QUEUE_LENGTH)		return B_BAD_VALUE;	// check early on if there are any free port slots to use	if (atomic_add(&sUsedPorts, 1) >= sMaxPorts) {		atomic_add(&sUsedPorts, -1);		return B_NO_MORE_PORTS;	}	// check & dup name	if (name == NULL)		name = "unnamed port";	// ToDo: we could save the memory and use the semaphore name only instead	strlcpy(nameBuffer, name, B_OS_NAME_LENGTH);	name = strdup(nameBuffer);	if (name == NULL) {		atomic_add(&sUsedPorts, -1);		return B_NO_MEMORY;	}	// create read sem with owner set to -1	// ToDo: should be B_SYSTEM_TEAM	readSem = create_sem_etc(0, name, -1);	if (readSem < B_OK) {		// cleanup		free((char *)name);		atomic_add(&sUsedPorts, -1);		return readSem;	}	// create write sem	writeSem = create_sem_etc(queueLength, name, -1);	if (writeSem < 0) {		// cleanup		delete_sem(readSem);		free((char *)name);		atomic_add(&sUsedPorts, -1);		return writeSem;	}	owner = team_get_current_team_id();	state = disable_interrupts();	GRAB_PORT_LIST_LOCK();	// find the first empty spot	for (i = 0; i < sMaxPorts; i++) {		if (sPorts[i].id == -1) {			// make the port_id be a multiple of the slot it's in			if (i >= sNextPort % sMaxPorts)				sNextPort += i - sNextPort % sMaxPorts;			else				sNextPort += sMaxPorts - (sNextPort % sMaxPorts - i);			GRAB_PORT_LOCK(sPorts[i]);			sPorts[i].id = sNextPort++;			atomic_add(&sUsedPorts, 1);			RELEASE_PORT_LIST_LOCK();			sPorts[i].capacity = queueLength;			sPorts[i].owner = owner;			sPorts[i].name = name;			sPorts[i].read_sem	= readSem;			sPorts[i].write_sem	= writeSem;			list_init(&sPorts[i].msg_queue);			sPorts[i].total_count = 0;			returnValue = sPorts[i].id;						RELEASE_PORT_LOCK(sPorts[i]);			goto out;		}	}	// ToDo: due to sUsedPorts, this cannot happen anymore - as	//		long as sMaxPorts stays constant over the kernel run	//		time (which it should be). IOW we could simply panic()	//		here.	// not enough ports...	RELEASE_PORT_LIST_LOCK();	returnValue = B_NO_MORE_PORTS;	dprintf("create_port(): B_NO_MORE_PORTS\n");	// cleanup	delete_sem(writeSem);	delete_sem(readSem);	free((char *)name);	atomic_add(&sUsedPorts, -1);out:	restore_interrupts(state);	return returnValue;}