rems-project / cerberus

Cerberus C semantics
https://www.cl.cam.ac.uk/~pes20/cerberus/
Other
51 stars 28 forks source link

[CN] Locks, concurrency, higer-order resources (Can a spec provide different resources based on the argument?) #363

Open peterohanley opened 3 months ago

peterohanley commented 3 months ago

For a mutex, I'd like mutex_lock(foo) to provide different resources than mutex_lock(bar). This is easy if different functions are called for each mutex, but this is not possible because the specific mutex called might be dynamic. However, I think the kind of mutex is still static. Consider a mutex field guarding the rest of a struct. How can this be done?

dc-mak commented 3 months ago

Hm, I think this generally falls under "implementing support for locks", which is fair. Do you have a non-lock example of adjusting the resource based on argument?

septract commented 3 months ago

There's a big pile of papers in separation logic talking about how to do this (I added a couple to the pile). Ideally we want to be able to reason something like this:

mutex *make_mutex(predicate P) 
/*@ 
requires 
  take pre = P; 
ensures 
  take post_ = is_mutex(return, P); 
@*/

take_mutex(mutex *m) 
/*@ 
requires 
  take mut = is_mutex(m, P); 
ensures 
  take mut_ = locked_mutex(m, P); 
  take post_ = P; 
@*/ 

release_mutex(mutex *m) 
/*@ 
requires 
  take locked = locked_mutex(m,P); 
  take inv = P; 
ensures 
  take mut_ = is_mutex(m,P); 
@*/ 

That is, we can create locks with arbitrary predicate arguments and then create them dynamically. This is a big motivation for fancy higher-order logics like Iris, which let you do this in a sensible way.

However, obviously CN doesn't have any such support. The best you can do, I would imagine, is specialize the mutex to each instance of the predicate. That is, you have a mutex for each resource P, Q, whatever... This is an instance where having multiple specs for the same function could be useful, although you could always copy the code I suppose and name the lock per the protected resource.

dc-mak commented 3 months ago

Let me clarify. We're aware of the need to implement locks and Neel and Christopher have some ideas on how to implement them. What my question was about any non-lock examples of higher order resources? Or multiple specifications? Just to shape any design discussions.

peterohanley commented 3 months ago

This is related to locks but not exactly locks: concurrency management. Functions enter_critical, exit_critical, and yield. Yield will eventually return but probably no locks should be held while yielding. Entering a critical section disables preemption, and a lot of APIs like this also return some kind of value that should be passed to exit_critical. Yield must not be called in a critical section. It seems that yield must require the absence of an in_critical resource, or there must be a normal_execution resource in the environment all the time. Probably the latter because then you can have in_isr, in_signalhandler, etc. FreeRTOS for example has a lot of duplicated functions based on whether the caller is in ISR context or not. This token needs to be threaded around everywhere unfortunately.

lwli11 commented 1 month ago

I've been reading this thread, and thinking about utilizing mutexes in our code. To start, is there a definition for the mutex type?

Thanks!

dc-mak commented 1 month ago

Try this? https://github.com/rems-project/cerberus/issues/535#issuecomment-2311976807

lwli11 commented 1 month ago

Yes, but there isn't a mutex typedef, and I'm not sure which to use since CN's buggy about structs and unions: https://stackoverflow.com/questions/30585375/what-is-the-type-of-pthread-mutex-t

peterohanley commented 1 month ago

It looks like cerberus special cases it. runtime/libc/include/posix/pthread.h:

#define pthread_mutex_t       __cerbty_pthread_mutex_t

What happens when you try to run cn on the example code?

lwli11 commented 1 month ago

That definition works, but I'm looking for a definition of is_mutex, Locked, and predicate. Or are there already cerberus definitions for those somewhere?

peterohanley commented 1 month ago

You need to write new ones for your use case. A canned definition can't be written in cn at this time (this issue)

lwli11 commented 1 month ago

Ah, so I'm trying to understand what cerberus has already implemented. So the pthread_mutex_t type is defined, but not pthread_mutex_lock? Any other operations on pthread_mutex_t defined?

Thanks!

dc-mak commented 6 days ago

Unsure, you'll have to just try and see. Cerberus and CN have been implementing C library features on an as needed basis, and so there will be gaps.