kernel/source/ipc/memticket.cpp
// the reason that we need the user to pass in the entire ticket instead of just the ticket id is because
// you can collect a ticket more than once (eg to get two separate regions to the same memory, for whatever reason).
the reason that we need the user to pass in the entire ticket instead of just the ticket id is because
you can collect a ticket more than once .
the reason that we need the user to pass in the entire ticket instead of just the ticket id is because you can collect a ticket more than once .
void releaseMemticket(const mem_ticket_t& ticket)
	{
		auto [ cleanup, tktid ] = tickets.map([&](auto& tkts) -> krt::pair<bool, memticket_id> {
			auto it = tkts.find(ticket.ticketId);
			if(it == tkts.end())
			{
				warn("memticket", "process {} tried to release nonexistent ticket {}",
					scheduler::getCurrentProcess()->processId, ticket.ticketId);
				return { false, 0 };
			}
			auto tik = &it->value;
			return LockedSection(&tik->physicalPages.mtx, [&]() -> krt::pair<bool, memticket_id> {
				auto proc = scheduler::getCurrentProcess();
				auto it = tik->collectors.find(proc);
				if(it == tik->collectors.end())
					return { false, 0 };
				auto it2 = it->value.find(VirtAddr(ticket.ptr));
				if(it2 == it->value.end())
					return { false, 0 };
				auto svmr = krt::move(it2->value);
				it->value.erase(it2);
				if(it->value.empty())
				{
					tik->collectors.erase(it);
					proc->collectedTickets.lock()->remove_all(tik->id);
				}
				vmm::deallocateAddrSpace(svmr.addr, svmr.numPages, proc);
				vmm::unmapAddress(svmr.addr, svmr.numPages,  true, proc);
				proc->addrspace.lock()->removeSharedRegion(krt::move(svmr));
				dbg("memticket", "pid {} released ticket ({}, {p} -> {p})", scheduler::getCurrentProcess()->processId, tik->id,
					ticket.ptr, (addr_t) ticket.ptr + ticket.len);
				tik->deref();
				if(tik->refcount == 0)
					return { true, tik->id };
				return { false, 0 };
			});
		});
		if(cleanup)
		{
			dbg("memticket", "cleaning up ticket {}", tktid);
			tickets.lock()->remove(tktid);
		}
	}
void releaseMemticket ( const mem_ticket_t & ticket ) { auto [ cleanup , tktid ] = tickets . map ( [ & ] ( auto & tkts ) -> krt :: pair < bool , memticket_id > { auto it = tkts . find ( ticket . ticketId ) ; if ( it == tkts . end ( ) ) { warn ( " " , " " , scheduler :: getCurrentProcess ( ) -> processId , ticket . ticketId ) ; return { false , 0 } ; } auto tik = & it -> value ; return LockedSection ( & tik -> physicalPages . mtx , [ & ] ( ) -> krt :: pair < bool , memticket_id > { auto proc = scheduler :: getCurrentProcess ( ) ; auto it = tik -> collectors . find ( proc ) ; if ( it == tik -> collectors . end ( ) ) return { false , 0 } ; auto it2 = it -> value . find ( VirtAddr ( ticket . ptr ) ) ; if ( it2 == it -> value . end ( ) ) return { false , 0 } ; auto svmr = krt :: move ( it2 -> value ) ; it -> value . erase ( it2 ) ; if ( it -> value . empty ( ) ) { tik -> collectors . erase ( it ) ; proc -> collectedTickets . lock ( ) -> remove_all ( tik -> id ) ; } vmm :: deallocateAddrSpace ( svmr . addr , svmr . numPages , proc ) ; vmm :: unmapAddress ( svmr . addr , svmr . numPages , true , proc ) ; proc -> addrspace . lock ( ) -> removeSharedRegion ( krt :: move ( svmr ) ) ; dbg ( " " , " " , scheduler :: getCurrentProcess ( ) -> processId , tik -> id , ticket . ptr , ( addr_t ) ticket . ptr + ticket . len ) ; tik -> deref ( ) ; if ( tik -> refcount == 0 ) return { true , tik -> id } ; return { false , 0 } ; } ) ; } ) ; if ( cleanup ) { dbg ( " " , " " , tktid ) ; tickets . lock ( ) -> remove ( tktid ) ; } }
the reason that we need the user to pass in the entire ticket instead of just the ticket id is because
you can collect a ticket more than once (eg to get two separate regions to the same memory, for whatever reason).
the reason that we need the user to pass in the entire ticket instead of just the ticket id is because you can collect a ticket more than once ( eg to get two separate regions to the same memory for whatever reason ) .
// check if this process collected it at all // find the matching ticket // delete it // if this process released all its collections for *this ticket*, then remove it // also remove the ticket from the process's list // remove the collected ticket from the address space /* ignore: */