A control-theoretic approach to self-adaptive systems and an application to cloud-based software