Compare commits
10 Commits
dabb46879d
...
bac2
Author | SHA1 | Date | |
---|---|---|---|
40cd963202
|
|||
d2ffcf8c9a
|
|||
a66a649b48 | |||
df9e43e534
|
|||
babed7eb09
|
|||
990b77ed18
|
|||
025b0e2166
|
|||
c4e193e45f
|
|||
3b2f4c84d7
|
|||
58acfde2b4
|
9
bac2/modalDev/e23/question1/.gitattributes
vendored
Normal file
9
bac2/modalDev/e23/question1/.gitattributes
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
#
|
||||
# https://help.github.com/articles/dealing-with-line-endings/
|
||||
#
|
||||
# Linux start script should use lf
|
||||
/gradlew text eol=lf
|
||||
|
||||
# These are Windows script files and should use crlf
|
||||
*.bat text eol=crlf
|
||||
|
5
bac2/modalDev/e23/question1/.gitignore
vendored
Normal file
5
bac2/modalDev/e23/question1/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
# Ignore Gradle project-specific cache directory
|
||||
.gradle
|
||||
|
||||
# Ignore Gradle build output directory
|
||||
build
|
28
bac2/modalDev/e23/question1/.project
Normal file
28
bac2/modalDev/e23/question1/.project
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>question1</name>
|
||||
<comment>Project question1 created by Buildship.</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</natures>
|
||||
<filteredResources>
|
||||
<filter>
|
||||
<id>1705161555233</id>
|
||||
<name></name>
|
||||
<type>30</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.core.resources.regexFilterMatcher</id>
|
||||
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
</filteredResources>
|
||||
</projectDescription>
|
@ -0,0 +1,13 @@
|
||||
arguments=--init-script /home/tonitch/.dotfiles/vim/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/eclipse.jdt.ls/workspace/config_linux/org.eclipse.osgi/55/0/.cp/gradle/init/init.gradle
|
||||
auto.sync=false
|
||||
build.scans.enabled=false
|
||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
||||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
||||
gradle.user.home=
|
||||
java.home=/usr/lib/jvm/java-21-openjdk
|
||||
jvm.arguments=
|
||||
offline.mode=false
|
||||
override.workspace.settings=true
|
||||
show.console.view=true
|
||||
show.executions.view=true
|
32
bac2/modalDev/e23/question1/app/.classpath
Normal file
32
bac2/modalDev/e23/question1/app/.classpath
Normal file
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
34
bac2/modalDev/e23/question1/app/.project
Normal file
34
bac2/modalDev/e23/question1/app/.project
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>app</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</natures>
|
||||
<filteredResources>
|
||||
<filter>
|
||||
<id>1705162039553</id>
|
||||
<name></name>
|
||||
<type>30</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.core.resources.regexFilterMatcher</id>
|
||||
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
</filteredResources>
|
||||
</projectDescription>
|
@ -0,0 +1,13 @@
|
||||
arguments=
|
||||
auto.sync=false
|
||||
build.scans.enabled=false
|
||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
||||
connection.project.dir=..
|
||||
eclipse.preferences.version=1
|
||||
gradle.user.home=
|
||||
java.home=
|
||||
jvm.arguments=
|
||||
offline.mode=false
|
||||
override.workspace.settings=false
|
||||
show.console.view=false
|
||||
show.executions.view=false
|
@ -0,0 +1,11 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=21
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=21
|
44
bac2/modalDev/e23/question1/app/build.gradle.kts
Normal file
44
bac2/modalDev/e23/question1/app/build.gradle.kts
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file was generated by the Gradle 'init' task.
|
||||
*
|
||||
* This generated file contains a sample Java application project to get you started.
|
||||
* For more details on building Java & JVM projects, please refer to https://docs.gradle.org/8.5/userguide/building_java_projects.html in the Gradle documentation.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
// Apply the application plugin to add support for building a CLI application in Java.
|
||||
application
|
||||
eclipse
|
||||
}
|
||||
|
||||
repositories {
|
||||
// Use Maven Central for resolving dependencies.
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Use JUnit Jupiter for testing.
|
||||
testImplementation(libs.junit.jupiter)
|
||||
|
||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||
|
||||
// This dependency is used by the application.
|
||||
implementation(libs.guava)
|
||||
}
|
||||
|
||||
// Apply a specific Java toolchain to ease working on different environments.
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(21))
|
||||
}
|
||||
}
|
||||
|
||||
application {
|
||||
// Define the main class for the application.
|
||||
mainClass.set("question1.App")
|
||||
}
|
||||
|
||||
tasks.named<Test>("test") {
|
||||
// Use JUnit Platform for unit tests.
|
||||
useJUnitPlatform()
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* This Java source file was generated by the Gradle 'init' task.
|
||||
*/
|
||||
package question1;
|
||||
|
||||
public class App {
|
||||
public String getGreeting() {
|
||||
return "Hello World!";
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(new App().getGreeting());
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package question1;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class InventoryManagement {
|
||||
|
||||
// cnt[zone][product] = quantity
|
||||
HashMap<Integer, HashMap<Integer, Integer>> cnt = new HashMap<>();
|
||||
|
||||
// ajoute dans une zone du stock une quantité donnée d’un produit donné
|
||||
void replenish(int product, int quantity, int destination_zone) throws ZoneFullException{
|
||||
cnt.putIfAbsent(destination_zone, new HashMap<>());
|
||||
cnt.get(destination_zone).putIfAbsent(product, 0);
|
||||
Integer q = cnt.get(destination_zone).get(product) + quantity;
|
||||
if(q > 100)
|
||||
throw new ZoneFullException();
|
||||
cnt.get(destination_zone).put(product, q);
|
||||
}
|
||||
|
||||
// retire d’une zone spécifique du stock une quantité donnée d’un produit donné pour l’envoyer vers le réseau de distribution
|
||||
void distribute(int product, int source_zone, int quantity) throws StockOutException{
|
||||
cnt.putIfAbsent(source_zone, new HashMap<>());
|
||||
cnt.get(source_zone).putIfAbsent(product, 0);
|
||||
Integer q = cnt.get(source_zone).get(product) - quantity;
|
||||
if(q < 0)
|
||||
throw new StockOutException();
|
||||
cnt.get(source_zone).put(product, q);
|
||||
}
|
||||
|
||||
// déplace une quantité donnée d’un produit vers une autre zone
|
||||
void move(int product, int quantity, int source_zone, int destination_zone) throws StockOutException, ZoneFullException {
|
||||
distribute(product, source_zone, quantity);
|
||||
try {
|
||||
replenish(product, quantity, destination_zone);
|
||||
}catch(ZoneFullException e){
|
||||
replenish(product, quantity, source_zone);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// retourne la quantité disponible d’un produit donné dans le stock, toutes zones confondues
|
||||
int quantity(int product){
|
||||
int sum[] = {0};
|
||||
cnt.forEach((key, value) -> {
|
||||
sum[0] += value.getOrDefault(product, 0);
|
||||
});
|
||||
return sum[0];
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package question1;
|
||||
|
||||
public class StockOutException extends Exception{
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,4 @@
|
||||
package question1;
|
||||
|
||||
public class ZoneFullException extends Exception {}
|
||||
|
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* This Java source file was generated by the Gradle 'init' task.
|
||||
*/
|
||||
package question1;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class AppTest {
|
||||
@Test void appHasAGreeting() {
|
||||
App classUnderTest = new App();
|
||||
assertNotNull(classUnderTest.getGreeting(), "app should have a greeting");
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package question1;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class InventoryManagementTest {
|
||||
|
||||
@Test
|
||||
public void testExceptions() throws Exception {
|
||||
InventoryManagement iv = new InventoryManagement();
|
||||
iv.replenish(0, 10, 0);
|
||||
assertThrows(ZoneFullException.class, () -> iv.replenish(0, 96, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExceptions2() throws Exception {
|
||||
InventoryManagement iv = new InventoryManagement();
|
||||
assertThrows(StockOutException.class, () -> iv.distribute(0, 0, 92));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQuantity() throws Exception {
|
||||
InventoryManagement iv = new InventoryManagement();
|
||||
iv.replenish(2, 42, 0);
|
||||
iv.replenish(2, 21, 1);
|
||||
iv.replenish(2, 0, 3);
|
||||
assertEquals(63, iv.quantity(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMove() throws Exception {
|
||||
InventoryManagement iv = new InventoryManagement();
|
||||
iv.replenish(42, 50, 1);
|
||||
iv.move(42, 21, 1, 2);
|
||||
assertEquals(50, iv.quantity(42));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure() throws Exception {
|
||||
InventoryManagement iv = new InventoryManagement();
|
||||
iv.replenish(42, 50, 1);
|
||||
iv.replenish(42, 50, 2);
|
||||
assertEquals(5050, iv.quantity(42)); // Should return a Failure
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testError() throws Exception {
|
||||
InventoryManagement iv = new InventoryManagement();
|
||||
iv.replenish(42, 100, 1);
|
||||
iv.replenish(42, 1, 1); // Should create an error
|
||||
|
||||
}
|
||||
}
|
10
bac2/modalDev/e23/question1/gradle/libs.versions.toml
Normal file
10
bac2/modalDev/e23/question1/gradle/libs.versions.toml
Normal file
@ -0,0 +1,10 @@
|
||||
# This file was generated by the Gradle 'init' task.
|
||||
# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format
|
||||
|
||||
[versions]
|
||||
guava = "32.1.2-jre"
|
||||
junit-jupiter = "5.10.0"
|
||||
|
||||
[libraries]
|
||||
guava = { module = "com.google.guava:guava", version.ref = "guava" }
|
||||
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" }
|
BIN
bac2/modalDev/e23/question1/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
bac2/modalDev/e23/question1/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
7
bac2/modalDev/e23/question1/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
7
bac2/modalDev/e23/question1/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
249
bac2/modalDev/e23/question1/gradlew
vendored
Executable file
249
bac2/modalDev/e23/question1/gradlew
vendored
Executable file
@ -0,0 +1,249 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
92
bac2/modalDev/e23/question1/gradlew.bat
vendored
Normal file
92
bac2/modalDev/e23/question1/gradlew.bat
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
14
bac2/modalDev/e23/question1/settings.gradle.kts
Normal file
14
bac2/modalDev/e23/question1/settings.gradle.kts
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* This file was generated by the Gradle 'init' task.
|
||||
*
|
||||
* The settings file is used to specify which projects to include in your build.
|
||||
* For more detailed information on multi-project builds, please refer to https://docs.gradle.org/8.5/userguide/building_swift_projects.html in the Gradle documentation.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
// Apply the foojay-resolver plugin to allow automatic download of JDKs
|
||||
id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0"
|
||||
}
|
||||
|
||||
rootProject.name = "question1"
|
||||
include("app")
|
9
bac2/modalDev/tp1/.gitattributes
vendored
Normal file
9
bac2/modalDev/tp1/.gitattributes
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
#
|
||||
# https://help.github.com/articles/dealing-with-line-endings/
|
||||
#
|
||||
# Linux start script should use lf
|
||||
/gradlew text eol=lf
|
||||
|
||||
# These are Windows script files and should use crlf
|
||||
*.bat text eol=crlf
|
||||
|
5
bac2/modalDev/tp1/.gitignore
vendored
Normal file
5
bac2/modalDev/tp1/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
# Ignore Gradle project-specific cache directory
|
||||
.gradle
|
||||
|
||||
# Ignore Gradle build output directory
|
||||
build
|
28
bac2/modalDev/tp1/.project
Normal file
28
bac2/modalDev/tp1/.project
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>tp1</name>
|
||||
<comment>Project tp1 created by Buildship.</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</natures>
|
||||
<filteredResources>
|
||||
<filter>
|
||||
<id>1701330804548</id>
|
||||
<name></name>
|
||||
<type>30</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.core.resources.regexFilterMatcher</id>
|
||||
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
</filteredResources>
|
||||
</projectDescription>
|
13
bac2/modalDev/tp1/.settings/org.eclipse.buildship.core.prefs
Normal file
13
bac2/modalDev/tp1/.settings/org.eclipse.buildship.core.prefs
Normal file
@ -0,0 +1,13 @@
|
||||
arguments=--init-script /home/tonitch/.dotfiles/vim/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/eclipse.jdt.ls/workspace/config_linux/org.eclipse.osgi/51/0/.cp/gradle/init/init.gradle
|
||||
auto.sync=false
|
||||
build.scans.enabled=false
|
||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
||||
connection.project.dir=app
|
||||
eclipse.preferences.version=1
|
||||
gradle.user.home=
|
||||
java.home=/usr/lib/jvm/java-17-openjdk
|
||||
jvm.arguments=
|
||||
offline.mode=false
|
||||
override.workspace.settings=true
|
||||
show.console.view=true
|
||||
show.executions.view=true
|
BIN
bac2/modalDev/tp1/TP1.pdf
Normal file
BIN
bac2/modalDev/tp1/TP1.pdf
Normal file
Binary file not shown.
12
bac2/modalDev/tp1/answer.md
Normal file
12
bac2/modalDev/tp1/answer.md
Normal file
@ -0,0 +1,12 @@
|
||||
# TP's Answer
|
||||
|
||||
## Exercice 2.1
|
||||
|
||||
1)
|
||||
test1) ❎ devrais fail car $ E1 \neq E2 $
|
||||
test2) ✅
|
||||
test3) ❎ shoud throw an error (no real number)
|
||||
|
||||
2-4) dans fichiers
|
||||
|
||||
## Exercice 2.2
|
32
bac2/modalDev/tp1/app/.classpath
Normal file
32
bac2/modalDev/tp1/app/.classpath
Normal file
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
34
bac2/modalDev/tp1/app/.project
Normal file
34
bac2/modalDev/tp1/app/.project
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>app</name>
|
||||
<comment>Project app created by Buildship.</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</natures>
|
||||
<filteredResources>
|
||||
<filter>
|
||||
<id>1701330804524</id>
|
||||
<name></name>
|
||||
<type>30</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.core.resources.regexFilterMatcher</id>
|
||||
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
</filteredResources>
|
||||
</projectDescription>
|
@ -0,0 +1,13 @@
|
||||
arguments=
|
||||
auto.sync=false
|
||||
build.scans.enabled=false
|
||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
||||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
||||
gradle.user.home=
|
||||
java.home=
|
||||
jvm.arguments=
|
||||
offline.mode=false
|
||||
override.workspace.settings=false
|
||||
show.console.view=false
|
||||
show.executions.view=false
|
@ -0,0 +1,32 @@
|
||||
package tp1.ex2_1;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Suite de tests pour vérifier la méthode sqrt dans la classe Sqrt
|
||||
*/
|
||||
public class SolveEquationTest {
|
||||
@Test
|
||||
public void test1() {
|
||||
SolveEquation se = new SolveEquation(1.0, -2.0, -3.0);
|
||||
assertEquals(se.getNbSolutions(), 2);
|
||||
assertTrue(se.getSolutions().getE1()
|
||||
.equals(se.getSolutions().getE2()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
double epsilon = 0.0001;
|
||||
SolveEquation se = new SolveEquation(1.0, 0.0, 0.0);
|
||||
assertEquals(se.getSolutions().getE1(),
|
||||
se.getSolutions().getE2(), epsilon);
|
||||
assertEquals(se.getNbSolutions(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test3() {
|
||||
SolveEquation se = new SolveEquation(5.0, 0.0, 3.0);
|
||||
assertEquals(se.getSolutions().getE1(), se.getSolutions().getE2());
|
||||
}
|
||||
}
|
45
bac2/modalDev/tp1/app/build.gradle.kts
Normal file
45
bac2/modalDev/tp1/app/build.gradle.kts
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This file was generated by the Gradle 'init' task.
|
||||
*
|
||||
* This generated file contains a sample Java application project to get you started.
|
||||
* For more details on building Java & JVM projects, please refer to https://docs.gradle.org/8.4/userguide/building_java_projects.html in the Gradle documentation.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
// Apply the application plugin to add support for building a CLI application in Java.
|
||||
application
|
||||
}
|
||||
|
||||
repositories {
|
||||
// Use Maven Central for resolving dependencies.
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Use JUnit Jupiter for testing.
|
||||
testImplementation("org.junit.jupiter:junit-jupiter:5.9.3")
|
||||
|
||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||
|
||||
// This dependency is used by the application.
|
||||
implementation("com.google.guava:guava:32.1.1-jre")
|
||||
|
||||
implementation("org.mockito:mockito-core:5.7.0")
|
||||
}
|
||||
|
||||
// Apply a specific Java toolchain to ease working on different environments.
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(17))
|
||||
}
|
||||
}
|
||||
|
||||
application {
|
||||
// Define the main class for the application.
|
||||
mainClass.set("tp1.App")
|
||||
}
|
||||
|
||||
tasks.named<Test>("test") {
|
||||
// Use JUnit Platform for unit tests.
|
||||
useJUnitPlatform()
|
||||
}
|
15
bac2/modalDev/tp1/app/src/main/java/tp1/App.java
Normal file
15
bac2/modalDev/tp1/app/src/main/java/tp1/App.java
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* This Java source file was generated by the Gradle 'init' task.
|
||||
*/
|
||||
package tp1;
|
||||
|
||||
public class App {
|
||||
// for the sake of showing an example of testing
|
||||
public String getGreeting() {
|
||||
return "Hello World!";
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(new App().getGreeting());
|
||||
}
|
||||
}
|
27
bac2/modalDev/tp1/app/src/main/java/tp1/ex2_1/Pair.java
Normal file
27
bac2/modalDev/tp1/app/src/main/java/tp1/ex2_1/Pair.java
Normal file
@ -0,0 +1,27 @@
|
||||
package tp1.ex2_1;
|
||||
|
||||
public class Pair<T> {
|
||||
private T e1, e2;
|
||||
|
||||
public Pair(T e1, T e2) {
|
||||
this.e1 = e1;
|
||||
this.e2 = e2;
|
||||
}
|
||||
|
||||
public T getE1() {
|
||||
return e1;
|
||||
}
|
||||
|
||||
public T getE2() {
|
||||
return e2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Pair) {
|
||||
Pair<?> p = (Pair<?>) obj;
|
||||
return e1.equals(p.e1) && e2.equals(p.e2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package tp1.ex2_1;
|
||||
|
||||
public class SolveEquation {
|
||||
private double a, b, c;
|
||||
|
||||
public SolveEquation(double a, double b, double c) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.c = c;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gives the number of solutions of the equation .
|
||||
*
|
||||
* @return the number of solution .
|
||||
*
|
||||
* @throws ArithmeticException if there
|
||||
* is an infinite number of solutions .
|
||||
*/
|
||||
public int getNbSolutions() throws ArithmeticException {
|
||||
double delta = b * b - 4 * a * c;
|
||||
if (delta < 0)
|
||||
throw new ArithmeticException("No real solution");
|
||||
else if (delta == 0)
|
||||
return 1;
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* * Gives the equation ’s solutions for x .
|
||||
*
|
||||
* @return the 2 solutions of the equation . If there is
|
||||
* only 1 solution , the 2 members of the pair are equal .
|
||||
*
|
||||
* @throws ArithmeticException if there is no real
|
||||
* solution for x , or if there is an infinite number
|
||||
* of solutions .
|
||||
*/
|
||||
public Pair<Double> getSolutions() throws ArithmeticException {
|
||||
double delta = b * b - 4 * a * c;
|
||||
if (delta < 0)
|
||||
throw new ArithmeticException("No real solution");
|
||||
else if (delta == 0) {
|
||||
double x = -b / (2 * a);
|
||||
return new Pair<Double>(x, x);
|
||||
}
|
||||
else
|
||||
return new Pair<Double>(
|
||||
(-b - Math.sqrt(delta)) / (2 * a),
|
||||
(-b + Math.sqrt(delta)) / (2 * a));
|
||||
}
|
||||
}
|
40
bac2/modalDev/tp1/app/src/main/java/tp1/ex2_2/Sqrt.java
Normal file
40
bac2/modalDev/tp1/app/src/main/java/tp1/ex2_2/Sqrt.java
Normal file
@ -0,0 +1,40 @@
|
||||
package tp1.ex2_2;
|
||||
|
||||
import java.lang.Math;
|
||||
|
||||
/**
|
||||
* Calcule la racine carrée d'un nombre positif
|
||||
*/
|
||||
public class Sqrt
|
||||
{
|
||||
public static final double EPSILON = 1e-8;
|
||||
|
||||
/**
|
||||
* Cacule la racine carrée d'un nombre positif en utilisant la méhtode
|
||||
* de Newton.
|
||||
* Il s'agit de calculer la racine de l'équation x^2-b=0 avec b
|
||||
* le nombre dont on veut la racine carrée.
|
||||
* La méthode de Newton consiste à utiliser la formule suivante :
|
||||
* x_i = x_(i-1) - f(x_(i-1)) / f'(x_(i-1)).
|
||||
* @param val La valeur dont on cherche la racine carrée (val >= 0)
|
||||
* @return La racine carrée de val avec une précision de 1e-12.
|
||||
* @throws IllegalArgumentException Si val < 0
|
||||
*/
|
||||
public static double sqrt(double val) throws IllegalArgumentException
|
||||
{
|
||||
if(val < 0)
|
||||
throw new IllegalArgumentException("ne peut pas être négatif");
|
||||
if(val == 0 || val == 1)
|
||||
return val;
|
||||
|
||||
double curr = nextIteration(val, val);
|
||||
while(Math.abs(val - Math.pow(curr, 2)) > EPSILON){
|
||||
curr = nextIteration(val, curr);
|
||||
}
|
||||
return curr;
|
||||
}
|
||||
|
||||
private static double nextIteration(double val, double curr){
|
||||
return (curr + (val / curr))/2;
|
||||
}
|
||||
}
|
19
bac2/modalDev/tp1/app/src/main/java/tp1/ex2_3/Fibonacci.java
Normal file
19
bac2/modalDev/tp1/app/src/main/java/tp1/ex2_3/Fibonacci.java
Normal file
@ -0,0 +1,19 @@
|
||||
package tp1.ex2_3;
|
||||
|
||||
public class Fibonacci {
|
||||
public static int fibo(int n) throws IllegalArgumentException {
|
||||
if (n < 0) {
|
||||
throw new IllegalArgumentException();
|
||||
} else {
|
||||
int f_n_1 = 1;
|
||||
int f_n = 0;
|
||||
int tmp;
|
||||
for (int i = 0; i < n; i++) {
|
||||
tmp = f_n;
|
||||
f_n = f_n + f_n_1;
|
||||
f_n_1 = tmp;
|
||||
}
|
||||
return f_n;
|
||||
}
|
||||
}
|
||||
}
|
14
bac2/modalDev/tp1/app/src/test/java/tp1/AppTest.java
Normal file
14
bac2/modalDev/tp1/app/src/test/java/tp1/AppTest.java
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* This Java source file was generated by the Gradle 'init' task.
|
||||
*/
|
||||
package tp1;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class AppTest {
|
||||
@Test void appHasAGreeting() {
|
||||
App classUnderTest = new App();
|
||||
assertNotNull(classUnderTest.getGreeting(), "app should have a greeting");
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package tp1.ex2_1;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Suite de tests pour vérifier la méthode sqrt dans la classe Sqrt
|
||||
*/
|
||||
public class SolveEquationTest {
|
||||
@Test
|
||||
public void test1() {
|
||||
SolveEquation se = new SolveEquation(1.0, -2.0, -3.0);
|
||||
assertEquals(se.getNbSolutions(), 2);
|
||||
assertFalse(se.getSolutions().getE1()
|
||||
.equals(se.getSolutions().getE2()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
double epsilon = 0.0001;
|
||||
SolveEquation se = new SolveEquation(1.0, 0.0, 0.0);
|
||||
assertEquals(se.getSolutions().getE1(),
|
||||
se.getSolutions().getE2(), epsilon);
|
||||
assertEquals(se.getNbSolutions(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test3() {
|
||||
SolveEquation se = new SolveEquation(5.0, 0.0, 3.0);
|
||||
assertThrows(ArithmeticException.class, () -> se.getSolutions(), "No real solution");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test4(){
|
||||
SolveEquation se = new SolveEquation(3, 0, 0);
|
||||
assertEquals(se.getNbSolutions(), 1);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package tp1.ex2_1;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Suite de tests pour vérifier la méthode sqrt dans la classe Sqrt
|
||||
*/
|
||||
public class SolveEquationTest {
|
||||
@Test
|
||||
public void test1() {
|
||||
SolveEquation se = new SolveEquation(1.0, -2.0, -3.0);
|
||||
assertEquals(se.getNbSolutions(), 2);
|
||||
assertTrue(se.getSolutions().getE1()
|
||||
.equals(se.getSolutions().getE2()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
double epsilon = 0.0001;
|
||||
SolveEquation se = new SolveEquation(1.0, 0.0, 0.0);
|
||||
assertEquals(se.getSolutions().getE1(),
|
||||
se.getSolutions().getE2(), epsilon);
|
||||
assertEquals(se.getNbSolutions(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test3() {
|
||||
SolveEquation se = new SolveEquation(5.0, 0.0, 3.0);
|
||||
assertEquals(se.getSolutions().getE1(), se.getSolutions().getE2());
|
||||
}
|
||||
}
|
49
bac2/modalDev/tp1/app/src/test/java/tp1/ex2_2/SqrtTest.java
Normal file
49
bac2/modalDev/tp1/app/src/test/java/tp1/ex2_2/SqrtTest.java
Normal file
@ -0,0 +1,49 @@
|
||||
package tp1.ex2_2;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
||||
/**
|
||||
* Suite de tests pour vérifier la méthode sqrt dans la classe Sqrt
|
||||
*/
|
||||
public class SqrtTest {
|
||||
@Test
|
||||
public void testSortie(){
|
||||
assertTrue(Sqrt.sqrt(42) >= 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testprecision(){
|
||||
assertEquals(Math.sqrt(16), Sqrt.sqrt(16), Sqrt.EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidInput(){
|
||||
double t1 = Sqrt.sqrt(0.4);
|
||||
assertTrue(t1 > 0 && t1 < 1);
|
||||
|
||||
double t2 = Sqrt.sqrt(21);
|
||||
assertTrue(t2 > 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBorne(){
|
||||
assertEquals(0, Sqrt.sqrt(0));
|
||||
assertEquals(1, Sqrt.sqrt(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBig(){
|
||||
double val = assertTimeoutPreemptively(Duration.ofSeconds(1), () -> Sqrt.sqrt(1e16));
|
||||
assertEquals(Math.sqrt(1e16), val, Sqrt.EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalid(){
|
||||
assertThrows(IllegalArgumentException.class, () -> Sqrt.sqrt(-42));
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package tp1.ex2_3;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class FibonacciTest {
|
||||
@Test
|
||||
void test1() {
|
||||
assertEquals(2, Fibonacci.fibo(2));
|
||||
}
|
||||
|
||||
@Test void test2() {
|
||||
assertTrue(Fibonacci.fibo(-2) >= 0);
|
||||
}
|
||||
|
||||
@Test void test3() {
|
||||
assertTrue(Fibonacci.fibo(4) == 3);
|
||||
}
|
||||
}
|
BIN
bac2/modalDev/tp1/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
bac2/modalDev/tp1/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
7
bac2/modalDev/tp1/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
7
bac2/modalDev/tp1/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
249
bac2/modalDev/tp1/gradlew
vendored
Executable file
249
bac2/modalDev/tp1/gradlew
vendored
Executable file
@ -0,0 +1,249 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
92
bac2/modalDev/tp1/gradlew.bat
vendored
Normal file
92
bac2/modalDev/tp1/gradlew.bat
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
14
bac2/modalDev/tp1/settings.gradle.kts
Normal file
14
bac2/modalDev/tp1/settings.gradle.kts
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* This file was generated by the Gradle 'init' task.
|
||||
*
|
||||
* The settings file is used to specify which projects to include in your build.
|
||||
* For more detailed information on multi-project builds, please refer to https://docs.gradle.org/8.4/userguide/building_swift_projects.html in the Gradle documentation.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
// Apply the foojay-resolver plugin to allow automatic download of JDKs
|
||||
id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0"
|
||||
}
|
||||
|
||||
rootProject.name = "tp1"
|
||||
include("app")
|
@ -2,19 +2,27 @@
|
||||
CC = gcc
|
||||
CFLAGS = -g -Wall
|
||||
|
||||
all: ex1
|
||||
SRC = ex1 ex2 ex3 ex4 ex5 ex6 ex7 group
|
||||
|
||||
all: $(SRC)
|
||||
|
||||
group: group.o mergeSort.o
|
||||
$(CC) $(CFLAGS) -o $@ $+
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
ex1: ex1.o
|
||||
%: %.o
|
||||
$(CC) $(CFLAGS) -o $@ $+
|
||||
|
||||
clean:
|
||||
rm -f *.o core.*
|
||||
rm -f plot.png
|
||||
rm -f $(SRC)
|
||||
|
||||
mrproper: clean
|
||||
rm -f ex1
|
||||
|
||||
run: ex1
|
||||
run: group
|
||||
./$<
|
||||
|
||||
graph: run
|
||||
graph -Tpng plot > plot.png
|
||||
nsxiv plot.png
|
||||
|
14
bac2/os/chap3/ex2.c
Normal file
14
bac2/os/chap3/ex2.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define printvi(X) printf("%s = %d\n", #X, X);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printvi(getpid());
|
||||
|
||||
pid_t f = fork();
|
||||
if(f != 0)
|
||||
getchar();
|
||||
}
|
||||
|
25
bac2/os/chap3/ex3.c
Normal file
25
bac2/os/chap3/ex3.c
Normal file
@ -0,0 +1,25 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
#include <time.h>
|
||||
|
||||
#define printvi(X) printf("%s = %d\n", #X, X);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
pid_t f = fork();
|
||||
if(f == 0){
|
||||
srand(time(NULL));
|
||||
int delay = 1 + rand() % 10;
|
||||
int value = rand() % 256;
|
||||
printvi(delay);
|
||||
printvi(value);
|
||||
sleep(delay);
|
||||
return value;
|
||||
}
|
||||
|
||||
int child_ret = 0;
|
||||
wait(&child_ret);
|
||||
printvi(WEXITSTATUS(child_ret));
|
||||
}
|
29
bac2/os/chap3/ex4.c
Normal file
29
bac2/os/chap3/ex4.c
Normal file
@ -0,0 +1,29 @@
|
||||
#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define printvi(X) printf("%s = %d\n", #X, X);
|
||||
#define printvf(X) printf("%s = %lld\n", #X, X);
|
||||
|
||||
typedef struct timespec timespec_t;
|
||||
|
||||
timespec_t start, end;
|
||||
|
||||
long long int dtime(timespec_t *start, timespec_t *end){
|
||||
return (end->tv_sec - start->tv_sec) * 1e9 + end->tv_nsec - start->tv_nsec;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
FILE* fd = fopen("plot", "w");
|
||||
long long int time, time_sum;
|
||||
for (int i = 0; i < 10000; ++i) {
|
||||
clock_gettime(CLOCK_REALTIME, &start);
|
||||
usleep(1);
|
||||
clock_gettime(CLOCK_REALTIME, &end);
|
||||
time = dtime(&start, &end);
|
||||
time_sum += time;
|
||||
fprintf(fd, "%d %lld\n", i, time);
|
||||
}
|
||||
}
|
29
bac2/os/chap3/ex5.c
Normal file
29
bac2/os/chap3/ex5.c
Normal file
@ -0,0 +1,29 @@
|
||||
#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define printvi(X) printf("%s = %d\n", #X, X);
|
||||
#define printvf(X) printf("%s = %lld\n", #X, X);
|
||||
|
||||
typedef struct timespec timespec_t;
|
||||
|
||||
timespec_t start, end, s = {0, 1};
|
||||
|
||||
long long int dtime(timespec_t *start, timespec_t *end){
|
||||
return (end->tv_sec - start->tv_sec) * 1e9 + end->tv_nsec - start->tv_nsec;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
FILE* fd = fopen("plot", "w");
|
||||
long long int time, time_sum;
|
||||
for (int i = 0; i < 10000; ++i) {
|
||||
clock_gettime(CLOCK_REALTIME, &start);
|
||||
nanosleep(&s, NULL);
|
||||
clock_gettime(CLOCK_REALTIME, &end);
|
||||
time = dtime(&start, &end);
|
||||
time_sum += time;
|
||||
fprintf(fd, "%d %lld\n", i, time);
|
||||
}
|
||||
}
|
44
bac2/os/chap3/ex6.c
Normal file
44
bac2/os/chap3/ex6.c
Normal file
@ -0,0 +1,44 @@
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#define THREADS 9
|
||||
|
||||
int cmp(const void * first, const void *second){
|
||||
return (*(int*)first) - (*(int*)second);
|
||||
}
|
||||
|
||||
void* threaded(){
|
||||
int delay = rand() % 6;
|
||||
int value = rand() % 256;
|
||||
int *ret = malloc(sizeof(int));
|
||||
*ret = value;
|
||||
sleep(delay);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
srand(time(NULL));
|
||||
pthread_t threads[THREADS];
|
||||
int returned[THREADS];
|
||||
for (int i = 0; i < THREADS; ++i) {
|
||||
pthread_create(threads+i, NULL, threaded, NULL);
|
||||
}
|
||||
|
||||
int *ret= NULL;
|
||||
for (int i = 0; i < THREADS; ++i) {
|
||||
pthread_join(threads[i], (void*)&ret);
|
||||
returned[i] = *ret;
|
||||
}
|
||||
|
||||
qsort((void* ) returned, THREADS, sizeof(int), cmp);
|
||||
|
||||
for (int i = 0; i < THREADS; ++i) {
|
||||
printf("%d\n", returned[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
6
bac2/os/chap3/ex7.c
Normal file
6
bac2/os/chap3/ex7.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Hello World!\n");
|
||||
}
|
24
bac2/os/chap3/group.c
Normal file
24
bac2/os/chap3/group.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include "mergeSort.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define printlist(s, x) printf("%s = [", #x); for (int i = 0; i < s; ++i) { printf("%d, ", x[i]); } printf("\b\b]\n");
|
||||
|
||||
#define listSize 1000000
|
||||
int list[listSize];
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// liste de nombre aléatoires
|
||||
srand(time(NULL));
|
||||
for (int i = 0; i < listSize; ++i) {
|
||||
list[i] = rand()%listSize;
|
||||
}
|
||||
/* printlist(listSize, list); */
|
||||
|
||||
mrg_t args = merge_init(list, listSize);
|
||||
merge_sort(&args);
|
||||
printlist(listSize, list);
|
||||
}
|
18
bac2/os/chap3/group01-chap3/Makefile
Normal file
18
bac2/os/chap3/group01-chap3/Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
.PHONY: clean, all
|
||||
CC = gcc
|
||||
CFLAGS = -g -Wall
|
||||
|
||||
all: group
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
group: group.o mergeSort.o
|
||||
$(CC) $(CFLAGS) -o $@ $+ $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f *.o core.*
|
||||
rm -f group
|
||||
|
||||
run: group
|
||||
./$<
|
24
bac2/os/chap3/group01-chap3/group.c
Normal file
24
bac2/os/chap3/group01-chap3/group.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include "mergeSort.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define printlist(s, x) printf("%s = [", #x); for (int i = 0; i < s; ++i) { printf("%d, ", x[i]); } printf("\b\b]\n");
|
||||
|
||||
#define listSize 1000000
|
||||
int list[listSize];
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// liste de nombre aléatoires
|
||||
srand(time(NULL));
|
||||
for (int i = 0; i < listSize; ++i) {
|
||||
list[i] = rand()%listSize;
|
||||
}
|
||||
/* printlist(listSize, list); */
|
||||
|
||||
mrg_t args = merge_init(list, listSize);
|
||||
merge_sort(&args);
|
||||
printlist(listSize, list);
|
||||
}
|
58
bac2/os/chap3/group01-chap3/mergeSort.c
Normal file
58
bac2/os/chap3/group01-chap3/mergeSort.c
Normal file
@ -0,0 +1,58 @@
|
||||
#include "mergeSort.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
|
||||
void* merge_sort(void* args) {
|
||||
mrg_t* f = (mrg_t*) args;
|
||||
if(f->slice.start < f->slice.final) {
|
||||
int middle = (f->slice.start + f->slice.final) / 2;
|
||||
|
||||
mrg_t args1 = {f->array, f->_depth+1, {f->slice.start, middle}};
|
||||
mrg_t args2 = {f->array, f->_depth+1, { middle+1, f->slice.final}};
|
||||
|
||||
if(f->_depth * f->_depth < THREADS){
|
||||
pthread_t t1, t2;
|
||||
assert(!pthread_create(&t1, NULL, merge_sort, (void*) &args1));
|
||||
assert(!pthread_create(&t2, NULL, merge_sort, (void*) &args2));
|
||||
assert(!pthread_join(t1, NULL));
|
||||
assert(!pthread_join(t2, NULL));
|
||||
}else{
|
||||
merge_sort((void*) &args1);
|
||||
merge_sort((void*) &args2);
|
||||
}
|
||||
merge(f->array, f->slice.start, middle, f->slice.final);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void merge(int array[], uint8_t start, uint8_t middle, uint8_t final) {
|
||||
|
||||
uint8_t countL = middle - start + 1;
|
||||
int *arrayL = malloc(countL * sizeof(int));
|
||||
for(uint8_t currentL = 0; currentL < countL; currentL ++)
|
||||
arrayL[currentL] = array[start + currentL ];
|
||||
|
||||
uint8_t countR = final - middle;
|
||||
int* arrayR = malloc(countR * sizeof(int));
|
||||
for(uint8_t currentR = 0; currentR < countR; currentR ++)
|
||||
arrayR[currentR] = array[middle + 1 + currentR ];
|
||||
|
||||
uint8_t currentL, currentR, current;
|
||||
for(currentL = 0, currentR = 0, current = start;
|
||||
current <= final && currentL < countL && currentR < countR;
|
||||
current ++)
|
||||
if(arrayL[currentL] <= arrayR[currentR])
|
||||
array[current] = arrayL[currentL++];
|
||||
else
|
||||
array[current] = arrayR[currentR++];
|
||||
|
||||
while(currentR < countR)
|
||||
array[current++] = arrayR[currentR++];
|
||||
while(currentL < countL)
|
||||
array[current++] = arrayL[currentL++];
|
||||
|
||||
free(arrayL);
|
||||
free(arrayR);
|
||||
}
|
21
bac2/os/chap3/group01-chap3/mergeSort.h
Normal file
21
bac2/os/chap3/group01-chap3/mergeSort.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <pthread.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#define THREADS 4
|
||||
#define merge_init(array, size) {(array), 0, {1, (size)}}
|
||||
|
||||
typedef struct{
|
||||
int start;
|
||||
int final;
|
||||
} SLICE;
|
||||
|
||||
typedef struct {
|
||||
int* array;
|
||||
int _depth;
|
||||
SLICE slice;
|
||||
} mrg_t;
|
||||
|
||||
void* merge_sort(void*);
|
||||
void merge(int array[], uint8_t start, uint8_t middle, uint8_t final);
|
58
bac2/os/chap3/mergeSort.c
Normal file
58
bac2/os/chap3/mergeSort.c
Normal file
@ -0,0 +1,58 @@
|
||||
#include "mergeSort.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
|
||||
void* merge_sort(void* args) {
|
||||
mrg_t* f = (mrg_t*) args;
|
||||
if(f->slice.start < f->slice.final) {
|
||||
int middle = (f->slice.start + f->slice.final) / 2;
|
||||
|
||||
mrg_t args1 = {f->array, f->_depth+1, {f->slice.start, middle}};
|
||||
mrg_t args2 = {f->array, f->_depth+1, { middle+1, f->slice.final}};
|
||||
|
||||
if(f->_depth * f->_depth < THREADS){
|
||||
pthread_t t1, t2;
|
||||
assert(!pthread_create(&t1, NULL, merge_sort, (void*) &args1));
|
||||
assert(!pthread_create(&t2, NULL, merge_sort, (void*) &args2));
|
||||
assert(!pthread_join(t1, NULL));
|
||||
assert(!pthread_join(t2, NULL));
|
||||
}else{
|
||||
merge_sort((void*) &args1);
|
||||
merge_sort((void*) &args2);
|
||||
}
|
||||
merge(f->array, f->slice.start, middle, f->slice.final);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void merge(int array[], uint8_t start, uint8_t middle, uint8_t final) {
|
||||
|
||||
uint8_t countL = middle - start + 1;
|
||||
int *arrayL = malloc(countL * sizeof(int));
|
||||
for(uint8_t currentL = 0; currentL < countL; currentL ++)
|
||||
arrayL[currentL] = array[start + currentL ];
|
||||
|
||||
uint8_t countR = final - middle;
|
||||
int* arrayR = malloc(countR * sizeof(int));
|
||||
for(uint8_t currentR = 0; currentR < countR; currentR ++)
|
||||
arrayR[currentR] = array[middle + 1 + currentR ];
|
||||
|
||||
uint8_t currentL, currentR, current;
|
||||
for(currentL = 0, currentR = 0, current = start;
|
||||
current <= final && currentL < countL && currentR < countR;
|
||||
current ++)
|
||||
if(arrayL[currentL] <= arrayR[currentR])
|
||||
array[current] = arrayL[currentL++];
|
||||
else
|
||||
array[current] = arrayR[currentR++];
|
||||
|
||||
while(currentR < countR)
|
||||
array[current++] = arrayR[currentR++];
|
||||
while(currentL < countL)
|
||||
array[current++] = arrayL[currentL++];
|
||||
|
||||
free(arrayL);
|
||||
free(arrayR);
|
||||
}
|
21
bac2/os/chap3/mergeSort.h
Normal file
21
bac2/os/chap3/mergeSort.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <pthread.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#define THREADS 4
|
||||
#define merge_init(array, size) {(array), 0, {1, (size)}}
|
||||
|
||||
typedef struct{
|
||||
int start;
|
||||
int final;
|
||||
} SLICE;
|
||||
|
||||
typedef struct {
|
||||
int* array;
|
||||
int _depth;
|
||||
SLICE slice;
|
||||
} mrg_t;
|
||||
|
||||
void* merge_sort(void*);
|
||||
void merge(int array[], uint8_t start, uint8_t middle, uint8_t final);
|
10000
bac2/os/chap3/plot
Normal file
10000
bac2/os/chap3/plot
Normal file
File diff suppressed because it is too large
Load Diff
27
bac2/os/chap4/Makefile
Normal file
27
bac2/os/chap4/Makefile
Normal file
@ -0,0 +1,27 @@
|
||||
.PHONY: clean, mrproper, run
|
||||
CC = gcc
|
||||
CFLAGS = -g -Wall
|
||||
|
||||
exos = ex4 group
|
||||
|
||||
all: $(exos)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
ex1: ex1.o RingBuffer.o
|
||||
$(CC) $(CFLAGS) -o $@ $+
|
||||
|
||||
ex%: ex%.o
|
||||
$(CC) $(CFLAGS) -o $@ $+
|
||||
|
||||
group: group.o
|
||||
$(CC) $(CFLAGS) -o $@ $+
|
||||
|
||||
clean:
|
||||
rm -f *.o core.*
|
||||
rm -f out group
|
||||
rm -f ${exos}
|
||||
|
||||
run: group
|
||||
./$<
|
20
bac2/os/chap4/RingBuffer.c
Normal file
20
bac2/os/chap4/RingBuffer.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include "RingBuffer.h"
|
||||
|
||||
void rb_push(rb_t* rb, int el){
|
||||
if(rb->filled)
|
||||
return;
|
||||
rb->data[rb->w_pos] = el;
|
||||
rb->w_pos = (rb->w_pos + 1) % rb->size;
|
||||
if(rb->w_pos == rb->r_pos)
|
||||
rb->filled = true;
|
||||
}
|
||||
int rb_pop(rb_t* rb){
|
||||
if(rb->w_pos == rb->r_pos && !rb->filled){
|
||||
rb->error = true;
|
||||
return 0;
|
||||
}
|
||||
int ret = rb->data[rb->r_pos];
|
||||
rb->r_pos = (rb->r_pos + 1) % rb->size;
|
||||
rb->filled = false;
|
||||
return ret;
|
||||
}
|
27
bac2/os/chap4/RingBuffer.h
Normal file
27
bac2/os/chap4/RingBuffer.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define rb_init(size, type)\
|
||||
{(size),\
|
||||
0, 0, false, false,\
|
||||
type,\
|
||||
malloc(sizeof(int)*(size)),\
|
||||
PTHREAD_MUTEX_INITIALIZER};
|
||||
|
||||
#define rb_free(rb) free(rb.data)
|
||||
|
||||
typedef struct rb{
|
||||
size_t size;
|
||||
size_t w_pos, r_pos;
|
||||
bool filled;
|
||||
bool error;
|
||||
enum {DROP, WAIT} type;
|
||||
int* data;
|
||||
pthread_mutex_t m;
|
||||
} rb_t;
|
||||
|
||||
void rb_push(rb_t*, int);
|
||||
int rb_pop(rb_t*);
|
46
bac2/os/chap4/ex1.c
Normal file
46
bac2/os/chap4/ex1.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include "RingBuffer.h"
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define THREADS 10
|
||||
|
||||
void* process(void* args);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
srand(time(NULL));
|
||||
rb_t rb = rb_init(50, DROP);
|
||||
pthread_t threads[THREADS];
|
||||
|
||||
int even, odd = {0};
|
||||
|
||||
for (int i = 0; i < THREADS; ++i) {
|
||||
pthread_create(threads+i, NULL, process, (void*) &rb);
|
||||
}
|
||||
int val;
|
||||
while(true){
|
||||
usleep(250);
|
||||
val = rb_pop(&rb);
|
||||
printf("got -> %d\n", val);
|
||||
|
||||
if(val % 2)
|
||||
odd++;
|
||||
else
|
||||
even++;
|
||||
|
||||
printf("%d nombres pairs et %d nombre impairs\n", even, odd);
|
||||
}
|
||||
|
||||
rb_free(rb);
|
||||
}
|
||||
|
||||
void* process(void* args){
|
||||
rb_t *rb = (rb_t*) args;
|
||||
|
||||
while(true){
|
||||
usleep((rand() % 4500) + 500);
|
||||
rb_push(rb, rand());
|
||||
}
|
||||
}
|
46
bac2/os/chap4/ex2.c
Normal file
46
bac2/os/chap4/ex2.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include "RingBuffer.h"
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define THREADS 10
|
||||
|
||||
void* process(void* args);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
srand(time(NULL));
|
||||
rb_t rb = rb_init(50, WAIT);
|
||||
pthread_t threads[THREADS];
|
||||
|
||||
int even, odd = {0};
|
||||
|
||||
for (int i = 0; i < THREADS; ++i) {
|
||||
pthread_create(threads+i, NULL, process, (void*) &rb);
|
||||
}
|
||||
int val;
|
||||
while(true){
|
||||
usleep(250);
|
||||
val = rb_pop(&rb);
|
||||
printf("got -> %d\n", val);
|
||||
|
||||
if(val % 2)
|
||||
odd++;
|
||||
else
|
||||
even++;
|
||||
|
||||
printf("%d nombres pairs et %d nombre impairs\n", even, odd);
|
||||
}
|
||||
|
||||
rb_free(rb);
|
||||
}
|
||||
|
||||
void* process(void* args){
|
||||
rb_t *rb = (rb_t*) args;
|
||||
|
||||
while(true){
|
||||
usleep((rand() % 4500) + 500);
|
||||
rb_push(rb, rand());
|
||||
}
|
||||
}
|
34
bac2/os/chap4/ex4.c
Normal file
34
bac2/os/chap4/ex4.c
Normal file
@ -0,0 +1,34 @@
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define SIZE 32768
|
||||
|
||||
pthread_t child_thread;
|
||||
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
int table[SIZE];
|
||||
|
||||
int cmp(const void* a1, const void* a2){
|
||||
return *((int*)a2) - *((int*)a1);
|
||||
}
|
||||
|
||||
void* child(void* args){
|
||||
pthread_mutex_lock(&mutex);
|
||||
for (int i = 0; i < SIZE; ++i) {
|
||||
table[i] = rand();
|
||||
}
|
||||
pthread_mutex_unlock(&mutex);
|
||||
sleep(1);
|
||||
pthread_mutex_lock(&mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
pthread_create(&child_thread, NULL, child, NULL);
|
||||
|
||||
pthread_mutex_lock(&mutex);
|
||||
qsort(table, SIZE, sizeof(int), cmp);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
45
bac2/os/chap4/group.c
Normal file
45
bac2/os/chap4/group.c
Normal file
@ -0,0 +1,45 @@
|
||||
/***************************************************************************
|
||||
* Le dinner des philosophes *
|
||||
* Two phase locking: *
|
||||
* - array de baguettes *
|
||||
* - manger(): tente l'acquisition des deux. attente passive si non dispo *
|
||||
****************************************************************************/
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#define TABLE_SIZE 5
|
||||
|
||||
#define RIGHT(x) ((x)) % TABLE_SIZE
|
||||
#define LEFT(x) ((x)+1) % TABLE_SIZE
|
||||
|
||||
typedef unsigned int PHILOSOPHE; // philosophe's id in the table
|
||||
|
||||
pthread_mutex_t baguettes[TABLE_SIZE], tableLock;
|
||||
int main(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void penser(){
|
||||
usleep(100 + rand() % 500);
|
||||
}
|
||||
|
||||
void manger(){
|
||||
usleep(100 + rand() % 500);
|
||||
}
|
||||
|
||||
void prendre(){
|
||||
|
||||
}
|
||||
void deposer(){
|
||||
|
||||
}
|
||||
|
||||
void* thread_philosophe(void* arg){
|
||||
while(42){
|
||||
penser();
|
||||
prendre();
|
||||
manger();
|
||||
deposer();
|
||||
}
|
||||
}
|
11
bac2/os/chap4/philosophes.h
Normal file
11
bac2/os/chap4/philosophes.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef PHILOSOPHES_H
|
||||
#define PHILOSOPHES_H
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef PHILOSPHES_IMPLEMENTATION
|
||||
|
||||
#endif /* end of implementation */
|
||||
|
||||
#endif /* end of include guard: PHILOSOPHES_H */
|
BIN
bac2/os/synthèse/process_diag.png
Normal file
BIN
bac2/os/synthèse/process_diag.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 117 KiB |
BIN
bac2/os/synthèse/process_exe.png
Normal file
BIN
bac2/os/synthèse/process_exe.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
BIN
bac2/os/synthèse/prog_components.png
Normal file
BIN
bac2/os/synthèse/prog_components.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
BIN
bac2/os/synthèse/syllabus-umons-2022-12-22.pdf
Normal file
BIN
bac2/os/synthèse/syllabus-umons-2022-12-22.pdf
Normal file
Binary file not shown.
389
bac2/os/synthèse/syntheses.tex
Normal file
389
bac2/os/synthèse/syntheses.tex
Normal file
@ -0,0 +1,389 @@
|
||||
\documentclass{article}
|
||||
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage[french]{babel}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{amsmath, amsfonts, amssymb, amsthm}
|
||||
|
||||
\title{Synthèse Système d'éxploitation}
|
||||
\author{Debucquoy Anthony}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\maketitle
|
||||
\tableofcontents
|
||||
\newpage
|
||||
|
||||
Ce document est une synthèse du cours de système d'exploitation. Il n'est pas complet et ne
|
||||
peut pas se substituer à une lecture du document originale. Il permet toutefois de lister les
|
||||
diffèrents points et d'y accompagner une brève explication.
|
||||
|
||||
\section{Events}
|
||||
|
||||
Un programme est composé:
|
||||
\begin{itemize}
|
||||
\item \textbf{Du code machine}: exécuté par la machine
|
||||
\item \textbf{D'un espace de données}: Stock les données statiques et dynamiques
|
||||
\item \textbf{D'une stack}: Stoque les variables locales et les appels
|
||||
\end{itemize}
|
||||
Ces composants se trouvent dans un "espace d'adresssage" commun et sont liés logiquements par le
|
||||
biais d'appels (lw, j, ...)
|
||||
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=0.8\textwidth]{prog_components.png}
|
||||
\caption{Composents d'un programme}
|
||||
\end{figure}
|
||||
|
||||
Lors de l'éxécution, les composents sont placés dans la mémoire afin d'y être accésible par le processeur.
|
||||
L'entièretée d'un programme est alors définie par 4 éléments:
|
||||
|
||||
\begin{enumerate}
|
||||
\item La valeur des registres
|
||||
\item le contenu de la stack (et le pointeur vers son sommet)
|
||||
\item L'espaces de données utilisés
|
||||
\item L'IP (instruction pointer)
|
||||
\end{enumerate}
|
||||
|
||||
Nous pouvons alors sauvegarder l'état (instantané) du programme.
|
||||
|
||||
|
||||
\subsection{Gestion d'évènements}
|
||||
|
||||
Nous distingons 2 types d'évènements traités par le processeur:
|
||||
\begin{enumerate}
|
||||
\item erreur / exceptions: ayant une origine \textbf{interne} au processeur
|
||||
ex: division par zero, op-code invalide, right-fault, ...
|
||||
\item evènement / interuptions: ayant une origine \textbf{externe} au processeur
|
||||
ex: clavier, fichier pret, packet, clk, ...
|
||||
\end{enumerate}
|
||||
|
||||
Suite à ces évènements, le programme sera mis en pause pour pouvoir traiter l'évènement. Puis
|
||||
le programme pourra (ou non) reprendre son cours. Dans le cas d'un évènement \textbf{récupérable},
|
||||
le programme continue. Dans l'un cas d'un évènement \textbf{irécupérable}, le programme s'arrète.
|
||||
Pour que le programme puisse poursuivre, il faut sauvegarder son contexte. cette "snapshot" est
|
||||
placée sur la stack. (cette stack peut basculer vers une autre pendant l'évènement pour éviter
|
||||
de laisser la posibilitée au programme de récupérer des informations sur l'évent sans autorisation).
|
||||
Cette sauvegarde sert à la fois pour les programmes récupérable pour la reprise/poursuite mais également
|
||||
pour les programmes irécupérables, ces informations sont utiles au dévelopeur pour le debug de l'app.
|
||||
Il est également nécéssaire de libèrer les resources aloués.
|
||||
|
||||
\subsection{Reprise ou poursuite}
|
||||
Lors que l'évènement à été pris en charge par le processeur, nous envisageons deux scénario.
|
||||
\begin{enumerate}
|
||||
\item \textbf{reprise}: retente l'éxécution du IP
|
||||
\item \textbf{pouruite}: passe à l'instruction suivante
|
||||
\end{enumerate}
|
||||
|
||||
En générale, les intéruptions constituent tous des évènements récupérables avec poursuite.
|
||||
|
||||
\subsection{Déroutement}
|
||||
|
||||
Chaques architectures implémente sa propre méthode de déroutement. voici quelques examples:
|
||||
\begin{itemize}
|
||||
\item \textbf{Registre de cause}: C'est un registre mis à jours lors d'une exception ou d'une
|
||||
intéruption. au terme du cycle d'éxécution, le processeur consulte ce registre pour savoir
|
||||
si un déroutement est nécéssaire et dans ce cas vers quel adresse.
|
||||
\item \textbf{Vectorisation}: chaques évent est un numéro dans une table de descripteur(IDT). Ce
|
||||
descripteur est l'adresse de la fonction de gestion de l'évènement.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Niveau de privilège}
|
||||
|
||||
Le jeu d'instruction du processeur contient des instructions "système" qui ne sont pas accésibles en
|
||||
principe à tout les utilisateurs. Un programme typiquement fait appel à l'OS qui à son tours fait
|
||||
les appels systèmes. on parle de ring 3/0 (0 étant le plus privilégié/OS)
|
||||
|
||||
\subsection{Basculement de stack}
|
||||
|
||||
Lors d'un déroutement, L'os utilise son propre stack. (après avoir sauvegardé le contexte du
|
||||
programme) ainsi, le programme ne peu pas accéder a son contenu lors de la continuation.
|
||||
|
||||
\subsection{Multiple évènements}
|
||||
Lorsque plusieurs évènements surviennents, la prioritée est : Abandon > Reprise > Poursuite.
|
||||
Il est également envisageable qu'un évènement survienne pendant la gestin d'un autre évènement. Dans
|
||||
ce cas, étant donné que nous utilisons le stack pour le stockage du contexte du programme, il est
|
||||
tout à fait envisageable d'utiliser ce même stack pour le stockage du contexte de la gestion du dit
|
||||
évènement. Nous avons alors une imbrication des évènement à la manière de fonctions récursives.
|
||||
Dans le cas ou nous authorisons plusierus évènements à dérouter en même temps, il peut être
|
||||
nécéssaire d'implémenter un ordre de priorité. Pour ce faire une solution est d'utiliser un masque
|
||||
d'interruption. Un évènement place alors les bits de sa prioritée. un évènement postèrieur est
|
||||
déclencher ou non selon son propre masque de priorité.
|
||||
|
||||
\section{Memoire}
|
||||
|
||||
Nous avons vu qu'un programme étais composé de trois compostantes: le code machine, l'espace de
|
||||
données et le stack. Ces composantes sont liées logiquement au sein du programme à l'aide d'adresse.
|
||||
(branchements, ...). Deux problèmes se posent alors:
|
||||
|
||||
\begin{enumerate}
|
||||
\item \textbf{La concurence d'adresse}: Il est possible que les adresses choisies soient déjà
|
||||
utilisées par un autre programme. Il est également important de vérifier quelles mémoires
|
||||
sont accédées pour éviter qu'un programme accède à des donnes ne lui appartenant pas.
|
||||
\item \textbf{Gestion de la mémoire disponible}: L'OS doit savoir quelle partie de la mémoire
|
||||
est libre et quelle partie est utilisé.
|
||||
\end{enumerate}
|
||||
|
||||
Il nous faut résoudre ces problèmes de manière efficace et performante. car ces opérations sont les
|
||||
plus utilisées
|
||||
|
||||
\subsection{Projection et protection}
|
||||
|
||||
\begin{itemize}
|
||||
\item \textbf{Adressage absolu}: Cas de figure le plus directe. Les adresses du programmes sont
|
||||
copiées précisément aux adresses de la mémoire choisies au moment de la compilation.
|
||||
Le programme fonctionne alors parfaitement. Si certaine des adresses du programme ne sont
|
||||
pas libres, Nous pourions comprometre l'intègritée du système. Il n'est également pas
|
||||
possible de vérifier si le programme accède a des adresse qui ne sont pas autorisées.
|
||||
\item \textbf{Adressage relatif}: Nous définissons un décalage (offset) au démarage du
|
||||
programme. Cet offset sera appliqué à tout les adresse utilisées dans le programme.
|
||||
\begin{itemize}
|
||||
\item \textbf{static}: Modifie les adresse en y ajoutant l'offset (adresse de base) à la
|
||||
volée lors de la mise en mémoire. Pour celà, l'éxécutable doit contenir une table
|
||||
contenant les emplacement des adresse à modifier. Cette aproche n'empèche toujours
|
||||
pas l'accés à des adresse hors mémoire. De plus, les adresse générées pendant le
|
||||
déroulement du programme ne seront pas corigées
|
||||
\item \textbf{dynamique}: L'ajout de l'offset se fait à chaques accés mémoires pendant
|
||||
l'éxécution. nous stockong également la \textbf{limite} (la taille du programme) qui
|
||||
permet de vérifier, lors d'un accès mémoire, si cette addresse est inférieur à
|
||||
limite. si ça n'est pas le cas c'est que le programme tente de d'accèder à une
|
||||
adresse ne lui appartenant pas. dans le cas contraire, l'adresse est additionée à
|
||||
\textbf{base}. Un avantage de cette aproche est que le programme peut à tout moment
|
||||
être déplacer dans la mémoire en métant à jour \textbf{base} et \textbf{limit}. A
|
||||
contrario, chaques appel mémoire demande deux opérations (une comparaison et une
|
||||
addition). ajout non négligable même si ces opérations font partie des plus rapides
|
||||
du procésseur
|
||||
\end{itemize}
|
||||
\item \textbf{Segmentation}: Le programme est ségmenté dans la mémoire physique. chaques
|
||||
ségments est encodé dans un \textbf{déscripteur de ségment} à l'aide de sa \textbf{base} et
|
||||
\textbf{limit} (il est également possible de stocker le type, la permission, la direction,
|
||||
la présence et un champ pour savoir si l'adresse a été modifiée ultérieurement). ces
|
||||
déscripteurs sont stocké dans une \textbf{table de segments} en mémoire physique. Pour
|
||||
gagner du temps cette table est stocké dans un registre de sélécteur de ségment.
|
||||
Ces ségments sont crées à la compilation et la table de segments est liée au programme.
|
||||
|
||||
Un avantage de la ségmentation est \textbf{le partage de segment}. En effet, il est possible
|
||||
pour plusieurs programmes de partager un segment de mémoire physique commun (ex: librairies).
|
||||
\item \textbf{Pagination}: Meilleure solution pour la souplesse dans la gestion de mémoire. Nous
|
||||
considérons deux espaces. La pagination repose sur un découpage uniforme de ces deux espaces (e.g. 4Kib, 4Mib).
|
||||
\begin{itemize}
|
||||
\item \textbf{espace physique} : dont la taille dépend de l'architecture du processeur
|
||||
(16/32/64 bits). Cet espace sera découpé en \textbf{pages}
|
||||
\item \textbf{espace virtuel} : dont la taille dépend du controlleur et de la quantitée
|
||||
de mémoire disponible. Cet espace sera découpé en \textbf{cadre}
|
||||
\end{itemize}
|
||||
Par conséquent, une page peut être contenue dans un cadre. Pour localiser l'endroit où une
|
||||
page réside en mémoire physique, nous utilisons une \textbf{table des pages} (propre à
|
||||
chaques programmes) \textbf{exhaustive} (contient une entrée pour chaques pages) et est
|
||||
stockée dans la mémoire physique. L'MMU (\textit{Memory Management Unit}) s'occupe de la
|
||||
traduction d'une page vers un cadre. La taille de la table des pages peut être trouvé par
|
||||
\[\text{Taille} = \frac{\text{Espace virtuel}}{\text{Taille de page}} \times \text{Taille d'une
|
||||
entrée}\]
|
||||
Chaques entrées dans la table des pages contient un numéro de cadre qui identifie l'adresse
|
||||
du cadre occupé par la page en question.(Nous y accompagnons un bit de présence, permission,
|
||||
référencée, modifiée).
|
||||
Un accés mémoire par le procésseur sépare l'adresse virtuelle en deux parties, suivant la
|
||||
taille de découpage. Nous avons donc une portion qui encode le numéro de page (utilisé en
|
||||
indice dans la table des pages) ainsi que l'offset qui sera apliqué une fois l'adresse
|
||||
physique trouvée. L'utilisation du bit de présence est expliqué ci-dessous, il permet en
|
||||
effet l'éxécution d'un programme quelque soit la quantité de mémoire physique disponible
|
||||
pour le stocker.
|
||||
\end{itemize}
|
||||
|
||||
Les méthodes utilisant le \textbf{bit de présence} permetent l'éxistance partielle d'un programme en mémoire.
|
||||
Dans le cas d'un appel vers une mémoire non présente, le processeur déclanche une \textbf{excéption}
|
||||
de type défaut de page qui va recharger la partie concernée en mémoire physique. Si au moins un
|
||||
cadre est disponible, il peut être pris. Si ça n'est pas le cas, un remplacmeent doit être
|
||||
effectué \ref{sec:Eviction} Eviction de page
|
||||
Il devra alors modifier les entrées base et limites en conséquence ainsi que mettre le bit de
|
||||
présence à 1.
|
||||
|
||||
\label{sec:Eviction}
|
||||
L'éviction d'une entrée dans la table des pages prends en compte le bit \textbf{modifié}. Celà
|
||||
permet d'éviter de perdre du temps d'écriture car si la page n'est pas modifiée, elle est encore
|
||||
accècible. IL existe alors plusieurs stratégies d'évicitions:
|
||||
\begin{itemize}
|
||||
\item \textbf{Least Recently Used}: Eviction de la page la moins utilisée. nécéssite de
|
||||
connaitre le temps depuis le dernier accès
|
||||
\item \textbf{Not Recently Used} permet une simplification du LRU, un simple bit est tenu à
|
||||
jours à la place du temps.
|
||||
\item \textbf{First In First Out}: la page la plus ancienne est choisie. une structure de type
|
||||
\textit{FIFO} peut être utilisée. Il est également possible d'implémenter la stratégie de la
|
||||
\textbf{dernière change}. C'est à dire, d'implémenter l'utilisation du bit de référence
|
||||
(régulièrement mis à jours par l'os) pour garder les pages régulièrement chargées. Il est
|
||||
finalement possible d'implémenter une structure circulaire.
|
||||
\end{itemize}
|
||||
|
||||
la \textbf{Préemption} est le fait de libèrer de la mémoire d'un programme qui ne s'éxécute pas à
|
||||
l'instant pour la donner à un autre programme en cours.
|
||||
|
||||
\subsection{Gestion de la mémoire physique}
|
||||
|
||||
Le système d'exploitation doit pouvoir, à tout moment, connaitre l'état d'occupation de la mémoire
|
||||
physique. L'allocation de mémoire est alors plus dynamique.
|
||||
\begin{itemize}
|
||||
\item \textbf{Bitmap}: tableau de bits, la mémoire physique est découpée en unités d'allocation
|
||||
de taille constante. on place les bits respectifs selon si l'espace est aloué ou non.
|
||||
\[\text{Nombres d'unités} = \frac{\text{Mémoire physique}}{\text{Taille d'une unité}}\]
|
||||
\[\text{Taille du bitmap} = \frac{\text{Nombres d'unités}}{8}\]
|
||||
Nous pouvons alors trouver le bit corespondant à une unitée en divisant l'adresse par la
|
||||
taille d'une unitée. Il suffit alors à l'os de trouver des suites de bits consécutifs libre
|
||||
pour alouer de la mémoire en conséquence.
|
||||
\item \textbf{Liste chainée}: chaques noed est une plage d'adresse particulière. un champ
|
||||
contient:
|
||||
\begin{itemize}
|
||||
\item état: libre ou aloué
|
||||
\item base
|
||||
\item longeur
|
||||
\item suivant
|
||||
\end{itemize}
|
||||
Nous avons finalement une chaine d'état alternant entre libre et aloué. lorsqu'un programme
|
||||
souhaite alouer une plage, il parcours la liste afin de trouver une plage libre dont la
|
||||
taille est supérieur à celle demandée. et de crée une maille de la chaine avec l'état
|
||||
aloué. lorsque nous avons deux états consécutifs, nous pouvons les fusioner en gardant
|
||||
l'adresse du premier mayon et en sommant les longeurs.
|
||||
|
||||
\end{itemize}
|
||||
|
||||
\section{Processus}
|
||||
|
||||
Un processus représente la mise en activité d'un programme qui réside en mémoire. (complétement ou
|
||||
partiellement). Ce processus va occuper un processeur en utilisant le context de sa stack lorsque
|
||||
son code sera en cours d'éxécution. Ces processus auront la capacitée de faire des appels systems
|
||||
(syscall) qui seront transmis à l'OS pour exécution. Il est donc nécéssaire d'alterner entre
|
||||
l'éxécution du processus et celui de l'os (notament pour les évènements/syscall).
|
||||
|
||||
\begin{figure}[h]
|
||||
\center
|
||||
\includegraphics[width=0.8\textwidth]{process_exe.png}
|
||||
\caption{Temps d'éxécution d'un processus}
|
||||
\end{figure}
|
||||
|
||||
Le temps d'éxécution du programme augmente donc. Il est même souvent nécéssaire de partager le
|
||||
processeur avec d'autre programmes en cours d'éxécution. (\textit{interleaving})
|
||||
|
||||
Tout les processus sont stockés dans la \textbf{table des processus} attaché à leurs état. Cet état
|
||||
peut être: \textbf{éxécution, pret, bloqué, zombie} et chaques processus contient un context
|
||||
nécéssaire à son fonctionnement. Il est également nécéssaire de sauvegarder l'état de la mémoire.
|
||||
(avec sa table des segments ou la table des pages). Finalement nous devons garder les divers
|
||||
descripteurs de resources (fichiers ouvers, ... et leurs status, décalage dans le fichiers, ...)
|
||||
|
||||
L'\textbf{état} est un élément éssentiel pour le processus. Celui-ci est constament dans l'un des
|
||||
états décrits ci-dessous. Celà permet de savoir comment le processus est censé se comporter à un
|
||||
instant t.
|
||||
|
||||
\begin{itemize}
|
||||
\item \textbf{éxécution}: Le processus suis son éxécution courante. peut être utilisateur, où
|
||||
les instructions du programme s'enchainent et passe en éxécution système lors d'un
|
||||
évènement. Une fois cet évènement traité, le système redonne la main à l'utilisateur qui
|
||||
peut continuer l'éxécution du programme. Il est également possible que l'évènement soit
|
||||
irrécupérable. dans ce cas, le programme se termine est passe à l'état \textbf{zombie}
|
||||
\item \textbf{prêt}: le processus est pret à etre éxécuté mais le processeur est actuellement
|
||||
occupé. une fois celui-ci libéré, il choisit (en fonction de méthodes discutés plus tard) un
|
||||
processus à l'état prêt et commence son éxécution.
|
||||
\item \textbf{bloqué}: Le processus ne peux pas continuer car il n'a pas les resources
|
||||
nécéssaire. Il peut par example attendre un signal réseau, une touche clavier, ... une fois
|
||||
cet élément reçu, le processus passe à l'état \textbf{prèt}. Le tout se fait pendant
|
||||
l'éxécution d'un évènement. ce qui implique que le procéssus en cours donne la main au
|
||||
système.
|
||||
\item \textbf{Zombie}: Un processus à l'état zombie ne peux plus rien faire. Il donne son état à
|
||||
son processus parent qui peut, une fois cet état reçu, terminer le processus.
|
||||
\end{itemize}
|
||||
|
||||
Un procéssus peut créer à son tours d'autre processus (parents/enfants) Le système fonctionne alors
|
||||
sous forme d'arborescence de processus, tous défini par leurs entrée dans la table des processus.
|
||||
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=0.8\textwidth]{process_diag.png}
|
||||
\caption{cycles de vie des processus}
|
||||
\end{figure}
|
||||
|
||||
Suite à cet agencement, il est nécéssaire de trouver des méthode d'ordonnancement. Ces méthodes
|
||||
doivent s'assurer la bonne répartition du temps processeur qui sont pret. Nous en étudierons sous 3
|
||||
type des systèmes différents.
|
||||
|
||||
Un point important à éviter est la \textbf{famine}. c'est à dire qu'une tache resterait à pret sans
|
||||
jammais se voir éxécuter.
|
||||
|
||||
|
||||
\subsection{systèmes batch}
|
||||
|
||||
éxécute des taches de manière régulière. chaques tache est simples mais effectuée sur une quantitée
|
||||
importante de données. Les taches sont garantie de terminer et il est possible d'estimer le temps
|
||||
d'une tache donnée.
|
||||
Il faut alors une équité dans les resources distribuées.
|
||||
|
||||
Nous regardons deux unitées. le \textit{Throughput}: nombre de taches par unité de temps, à
|
||||
maximiser; le \textit{Turnaround}: temps moyen entre création et terminaison, à minimiser.
|
||||
|
||||
\begin{itemize}
|
||||
\item \textbf{First come first served (FCFS)}: Par ordre d'arrivé à l'état pret. Peut
|
||||
s'implémenter à l'aide d'une file. cette méthode est équitable et évite la famine car toutes
|
||||
les taches finirons par s'éxécuter. Mais ne garantis pas une utilisation optimale des
|
||||
\item \textbf{Shortest job first (SJF)}: Nous pouvons éstimer la durée des tache (car batch)
|
||||
donc nous pouvons priorisé les taches courtes. Cette stratégie minimise le turnaround mais
|
||||
n'est pas équitable vis à vis des tache longues. nous avons un risque de famines.
|
||||
\item \textbf{Shortest Remaining Task First (SRTF)}: Nous gardons le temps restant d'éxécution
|
||||
de chaques processus. l'ordre d'éxécution suis alors cette liste.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Systèmes intéractifs}
|
||||
|
||||
Centré autours de l'utilisateur et l'intéraction. Nous voulons une équité entre les utilisateurs et
|
||||
les resources utilisées. Nous utilisons les métriques suivantes: \textit{latence}: le temps qui
|
||||
s'écoule entre une action de l'utilisateur et la réaction du système, \textit{Proportionalité}
|
||||
en adéquation avec les attentes de l'utilisateur.
|
||||
|
||||
\begin{itemize}
|
||||
\item \textbf{Round-Robin}: Le temps CPU est divisé en \textit{quantum} de temps de durée fixe.
|
||||
Ces quantums sont distribués aux processus prets. Nous pouvons l'implémenter à l'aide d'une
|
||||
liste cylindrique. l'Os configure un timer pour générer une intérruption à la fin du quantum
|
||||
de temps pour passer à l'éxécution suivante. Cette stratégie garantit une répartition
|
||||
équitable du CPU entre les procéssus. Il ne faut pas que le quantum soit trop bas car au
|
||||
final il y aurais plus de temps nécéssaire à la commutation qu'à l'éxécution des processus.
|
||||
\item \textbf{Priority Schéduling}: Mise en place d'un niveau de priorité par processus.
|
||||
\item \textbf{Guaranteed Scheduling}: A pour but une répartition du nombre de processs face à un
|
||||
délai garanti.
|
||||
\[\text{Délai garanti} = \frac{\text{Temps depuis sa création}}{\text{Nombre de processus}}\]
|
||||
L'ordonnanceur réalise un suivi du temps d'éxécution par chaque processus.
|
||||
\[\rho = \frac{\text{Temps reçu}}{\text{Délai garanti}}\]
|
||||
L'ordonnancement se base alors sur la valeur minimale.
|
||||
\item \textbf{Fair-share scheduling} : Deux niveau de round robin, un pour les utilisateurs et
|
||||
un par processus d'un utilisateur. Celà permet une répartition équitable du temps CPU par
|
||||
utilisateur.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Systèmes temps réel}
|
||||
|
||||
Système nécéssitant un controle du temps (réel) critique. Il se doit de réagir dans un temps
|
||||
déterminé. (example système de défense anti-missile scannant continuellement son périmètre.)
|
||||
Dans ces système. chaques évènements est précisément calibré pour être traités dans un temps
|
||||
impartis avec échéances strictes. Ce système est ordonnancable uniquement si
|
||||
\[\sum_{i=1}^m \frac{C_i}{P_i} \leq 1\]
|
||||
avec $P$ intervalle entre deux occurence d'évènements et $C$ Temps nécéssaire au traitement.
|
||||
|
||||
\vspace{1cm}Un thread (processus léger) permet un découpage des traitement qui, au sein d'un processus, peuvent
|
||||
être effectué de mainère indépendante les uns des autres (\textbf{multi-threading} )
|
||||
Le coup de la gestion d'un thread est moindre que celui d'un processus. car celui-ci prends toutes
|
||||
les resources déjà alouées de son thread principal. Il suffit juste d'effectuer une allocation de
|
||||
mémoire pour héberger le stack du thread engendré. La continuation est nest rendu également plus
|
||||
simple.
|
||||
L'implémentation d'un thread peut se faire à deux niveaux.
|
||||
\begin{itemize}
|
||||
\item \textbf{User-level}: l'os n'a pas conscience des threads, c'est à l'application de gérer
|
||||
son ordonencement. Mais n'est pas très évicace faces aux évènements car un blocage
|
||||
(ouverture de fichiers, ...) bloquera tout les autres threads
|
||||
\item \textbf{Kernel-level}: la stratègie d'ordonencement apliqués aux processus est appliqué
|
||||
aux threads. Le blocage n'a donc pas de conséquence sur les autres threads du même
|
||||
processus.
|
||||
\end{itemize}
|
||||
|
||||
\section{Concurence}
|
||||
|
||||
\section{Systèmes de fichiers}
|
||||
|
||||
\section{Entrées-sorties}
|
||||
|
||||
\end{document}
|
23
bac2/pgl/usecase/Makefile
Normal file
23
bac2/pgl/usecase/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
.PHONY: all clean run
|
||||
|
||||
all: extension_messagerie.pdf
|
||||
|
||||
%.pdf: %.tex
|
||||
pdflatex $<
|
||||
|
||||
extension_messagerie.pdf: extension_messagerie.tex extension_messagerie.bbl use_case_messagerie.tex
|
||||
pdflatex extension_messagerie.tex
|
||||
|
||||
use_case_messagerie.tex: use_case_messagerie.uml
|
||||
plantuml -tlatex:nopreamble use_case_messagerie.uml
|
||||
|
||||
extension_messagerie.bbl: references.bib
|
||||
biber $<
|
||||
|
||||
clean:
|
||||
latexmk -C
|
||||
rm -f use_case_messagerie.tex
|
||||
rm -f extension_messagerie.{bbl,run.xml}
|
||||
|
||||
run: extension_messagerie.pdf
|
||||
xdg-open $<
|
98
bac2/pgl/usecase/extension_messagerie.tex
Normal file
98
bac2/pgl/usecase/extension_messagerie.tex
Normal file
@ -0,0 +1,98 @@
|
||||
\documentclass{article}
|
||||
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage{amsmath, amsfonts, amssymb, amsthm}
|
||||
\usepackage{tikz}
|
||||
\usepackage{biblatex}
|
||||
|
||||
\author{Debucquoy Anthony}
|
||||
\title{Extension messagerie}
|
||||
|
||||
\addbibresource{references.bib}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\section{Use case diagram}
|
||||
|
||||
|
||||
\begin{figure}
|
||||
\resizebox{345pt}{!}{
|
||||
\input{./use_case_messagerie.tex}
|
||||
}
|
||||
\caption{Use Case Diagram of the messaging extension}
|
||||
\label{fig:useCase:msg_ext}
|
||||
\end{figure}
|
||||
|
||||
In the diagram Figure~\ref{fig:useCase:msg_ext},
|
||||
the <<extend>> definition is not pulled from the "Genie logiciel" course
|
||||
of the University of Mons (UMONS). It is in fact the definition from
|
||||
the Dan Pilone's pocket reference \cite{Pilone2006-fn}.
|
||||
|
||||
\subsection{Answer topic}
|
||||
|
||||
The user should be able to answer to a topic created by a teacher.
|
||||
This answer will depend on the type of topic. The answer could be a selection on a poll,
|
||||
a private answer (which mean that the answer is not visible to the other users except to the professor).
|
||||
The answer could finally be a basic answer to the topic and be visible to other users browsing the topic.
|
||||
|
||||
\subsection{Create discutions}
|
||||
|
||||
The user can select multiple users and group them into a discussion.
|
||||
In this discussion, users will be able to exchange messages readable by
|
||||
every other members of the discussion
|
||||
|
||||
\subsubsection{Send messages}
|
||||
|
||||
Allow the creation of a message in a discussion.
|
||||
The text sent to others shall be received by other users
|
||||
and these users shall be notified of this message by the notification
|
||||
system.
|
||||
|
||||
\subsection{Ask appointment}
|
||||
|
||||
A student can ask for an appointment to a teacher.
|
||||
In this request, the student will have to give a date, a time
|
||||
and a subject he want to propose to the teacher.
|
||||
|
||||
\subsubsection{Export to calendar}
|
||||
|
||||
When an appointment is made. The program can export the event
|
||||
to an open format that can be read by calendar software to add
|
||||
the event to the user's calendar.
|
||||
|
||||
\subsection{Manage appointment}
|
||||
|
||||
When a teacher received an appointment, he is able to
|
||||
validate, deny or propose a new appointment schedule to the
|
||||
student.
|
||||
|
||||
\subsubsection{Propose new appointment}
|
||||
|
||||
If the teacher can't attend to an appointment because of his
|
||||
schedule, he can make a new time proposal and send it to
|
||||
the student. The student then receive a notification of
|
||||
the proposed modifications.
|
||||
|
||||
\subsection{Create forum}
|
||||
|
||||
The teacher can create a new forum under a specific course
|
||||
The new forum will then make every student of this course
|
||||
follow the forum and its topic.
|
||||
|
||||
\subsubsection{Post topics}
|
||||
|
||||
The teacher can post a new topic inside a forum to let
|
||||
the student know of something specific or to ask a question to
|
||||
them.
|
||||
|
||||
\subsubsection{Post poll}
|
||||
|
||||
When posting a topic to a forum, the teacher can choose to
|
||||
make the post as a poll. In that case, student will have to vote
|
||||
for one of the options or if allowed by the teacher, create a new option.
|
||||
|
||||
\printbibliography
|
||||
|
||||
\end{document}
|
||||
|
9
bac2/pgl/usecase/references.bib
Normal file
9
bac2/pgl/usecase/references.bib
Normal file
@ -0,0 +1,9 @@
|
||||
@BOOK{Pilone2006-fn,
|
||||
title = "{UML} 2.0 Pocket Reference",
|
||||
author = "Pilone, Dan",
|
||||
publisher = "O'Reilly Media",
|
||||
month = mar,
|
||||
year = 2006,
|
||||
address = "Sebastopol, CA",
|
||||
language = "en"
|
||||
}
|
39
bac2/pgl/usecase/use_case_messagerie.uml
Normal file
39
bac2/pgl/usecase/use_case_messagerie.uml
Normal file
@ -0,0 +1,39 @@
|
||||
@startuml
|
||||
|
||||
left to right direction
|
||||
|
||||
:Student: as s
|
||||
:Teacher: as t
|
||||
|
||||
|
||||
package "Messagerie"{
|
||||
|
||||
(Answer topics) as at
|
||||
(Ask appointement) as aa
|
||||
(Create Discution) as cd
|
||||
(Create Forum) as cf
|
||||
(Manage appointement) as ma
|
||||
|
||||
s -- at
|
||||
s -- aa
|
||||
s -- cd
|
||||
|
||||
t -- cd
|
||||
t -- cf
|
||||
t -- ma
|
||||
|
||||
(Export to calendar) as etc
|
||||
|
||||
aa <-- etc : << extend >>
|
||||
ma <-- etc : << extend >>
|
||||
|
||||
(Post topics) as pt
|
||||
cf <-- pt : << include >>
|
||||
pt <|-- (Post poll)
|
||||
cd <-- (Send messages) : << include >>
|
||||
|
||||
ma <-- (Propose new appointment) : << exlude>> \n [refuse]
|
||||
|
||||
}
|
||||
|
||||
@enduml
|
BIN
bac2/uml/ATM_usecase.png
Normal file
BIN
bac2/uml/ATM_usecase.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 96 KiB |
BIN
bac2/uml/activity.png
Normal file
BIN
bac2/uml/activity.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 137 KiB |
201
bac2/uml/notes.md
Normal file
201
bac2/uml/notes.md
Normal file
@ -0,0 +1,201 @@
|
||||
Notes de cours UML
|
||||
==================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Nous devons voir les diagrammes :
|
||||
|
||||
- de cas d'utilisation
|
||||
- d'interraction overview
|
||||
- **de Class**
|
||||
- **d'état**
|
||||
- d'objet
|
||||
- d'activitée
|
||||
- de séquence
|
||||
|
||||
Modélisation logicielle
|
||||
------------------------
|
||||
|
||||
un **modèle** est une représentation simplifiée d'une partie de la réalité dans un but spécifique.
|
||||
Ces modèles ont pour "valeurs":
|
||||
|
||||
- L'abstraction
|
||||
- Compréhension
|
||||
- Précision
|
||||
- Prédictibilité
|
||||
- Rentabilité
|
||||
|
||||
Dans tout les diagrammes uml, les commentaire sont encadrée et reliés avec des ligne discontinue
|
||||
|
||||
Diagramme de cas d'utilisation
|
||||
------------------------------
|
||||
|
||||
Représente une "vitrine" du produit avec ces fonctions principales d'un point de vue utilisateurs.
|
||||
|
||||
Représente:
|
||||
|
||||
- Un système (carré entourant une partie du diagramme)
|
||||
- Un ensemble de cas d'utilisation (dans un oval)
|
||||
- Accompagné d'une descriptin semi-structurée
|
||||
- Toujours lié à un acteur (sauf <\<include\>> et <\<exlude\>>)
|
||||
- Les acteurs (bonnome batons)
|
||||
- Les relations entre eux
|
||||
|
||||
Attention de ne pas modéliser des dépendances causales ou séquentielles.
|
||||
|
||||
### Relations
|
||||
|
||||
- extension: ajoute un comportement supplémentaire à un point d'extension.
|
||||
- Dans le cas d'une condition, ajouter "[condition]" à la flèche
|
||||
- inclusion: inclus dans le comportement d'un autre cas d'utilisation
|
||||
- généralisation: remplace un cas d'u par un autre qui fournit plus de détails.
|
||||
- peut être entre cas d'u: spécialisation
|
||||
- peut être entre acteurs: héritage
|
||||
|
||||

|
||||
|
||||
Diagramme d'interaction
|
||||
-----------------------
|
||||
|
||||
Permet de faire un diagramme d'activité avec les use case. C'est en quelques sorte un use case
|
||||
diagramme séquentielle et causale.
|
||||
|
||||
Activity diagram
|
||||
----------------
|
||||
|
||||
Permet de modéliser un comportement dynamique, une succession d'activités dans un système pour une
|
||||
certaine tâche ainsi que son flux de controle.
|
||||
|
||||
Resemble à un diagramme d'état sans les états.
|
||||
|
||||
- activité: rectangle arrondi
|
||||
- transitions: flèches
|
||||
- chaques activités doit avoir une transition sortante et peut avoir plusieurs transition
|
||||
entrante.
|
||||
- Entrée: cèrcle noir
|
||||
- Sortie: Cible
|
||||
- Fin de flux: cercle baré
|
||||
- Point de jonction/ Décision: losange
|
||||
- choix entre deux séquence mutuellement exclusive.
|
||||
- Condition notées en "[condition]"
|
||||
- sert à merge des chemins alternatifs (!pas chemins concurents)
|
||||
- barre de synchronisation: ligne épaisse avec transition entrante et sortantes.
|
||||
- Un fork qui n'est pas join doit se terminer par un point de sortie (pour une terminaison de
|
||||
l'acitivité complète) ou par un symbole de fin de flux (dans le cas ou l'activité continue
|
||||
même sans cette branche).
|
||||
- swimlanes: couloirs d'activité
|
||||
- Objets: Rectangle
|
||||
- Récurence: Sablier avec "[timeline]" pour spécifier la récurence
|
||||
- Signal: Rectangle avec flèche et anti-flèche
|
||||
-
|
||||
Il est possible de représenter des sous activitées en dessinant un diagramme d'activité dans un
|
||||
rectangle.
|
||||
|
||||

|
||||
|
||||
Class diagram
|
||||
-------------
|
||||
|
||||
Représente les structures statiques d'un système (classes, interfaces et leurs relations)
|
||||
|
||||
- Classes: Rectangle
|
||||
- Noun in PascalCase
|
||||
- Si interface, noté <\<interface\>>
|
||||
- Souligné si instance (et/ou :Type)
|
||||
- Attributs: listées dans rectangle de classe
|
||||
- noun camelCase
|
||||
- peut avoir un type (primitif ou complexe)
|
||||
- peut avoir une valeur par défaut
|
||||
- une portée (class scope = souligné)
|
||||
- une liste de valeurs possibles (enum)
|
||||
- une visibilité (+, -, #, ~)
|
||||
- Opérations: listées dans rectangle de classe
|
||||
- verb in camelCase
|
||||
- peut avoir un type de retour
|
||||
- peut avoir des arguments
|
||||
- une portée
|
||||
- une visibilité (+, -, #, ~)
|
||||
- Les getter & setter des attr ne sont généralement pas mentionnées.
|
||||
- Associations: ligne
|
||||
- connexion bidirectionnelle entre classe
|
||||
- peut être accompagné en annonation du role de cette association (de part et d'autre)
|
||||
- peut être accompagné d'une quantification: m .. n avec * signifiant zero ou plus
|
||||
- peut être étiquetée par explicité ( works for |> )
|
||||
- peut être associé à elle même
|
||||
- Ajouter une croix à la base d'une association permet de la rendre uni-directionnelle
|
||||
- Gnéralisations: Flèche ouverte
|
||||
- Contraintes: commentaire
|
||||
- "{or}" exclusion mutuelle
|
||||
- Agrégation: diamand (<>--)
|
||||
- apartient-à ou est-une-partie-de ou est-composé-de
|
||||
- Composition: diamand solide (<@>--)
|
||||
- agrégat mais avec dépendance forte (si l'agrégat est détruit alors ses parties aussi)
|
||||
|
||||
Sequence
|
||||
--------
|
||||
|
||||
Décrire comment le programme doit se comporter. Comportement des diagrammes statiques.
|
||||
La verticalitée représente le temps.
|
||||
|
||||
- Objets: Etiquette au dessus des lifeline (sous forme d'instance avec :)
|
||||
- Plusieurs instance = plusieurs rectangles superposés
|
||||
- lifeline: ligne verticale
|
||||
- Activation: boite sur la ligne de vie
|
||||
- message: flèches entre les lignes de vies
|
||||
- retour: flèche pointiée
|
||||
- Création: objet au bout d'un message
|
||||
- destruction: X en bas d'une ligne de vie
|
||||
- Opérateurs: Rectangle d'une zone avec label
|
||||
- loop (while [...] do ...)
|
||||
- alt (if [...] then ... else ...)
|
||||
- opt (if [...] then ...)
|
||||
- break (if [...] then ... exit)
|
||||
- par (parallel)
|
||||
- neg (invalide)
|
||||
- critical (section critique)
|
||||
|
||||
D'autre diagrammes peuvent être utilisé à l'intérieur du diagramme de séquence
|
||||
|
||||
Stateshart
|
||||
----------
|
||||
|
||||
Un stateshart décrit le comportement d'un système, d'une partie d'un système ou d'un objet
|
||||
|
||||
Resemble fortement à un activity diagram mais représente des états.
|
||||
|
||||
- Etat initial: Cercle noir
|
||||
- Etat final: target
|
||||
- State: rectangle arondi
|
||||
- peut être un diagrame d'état lui même
|
||||
- transition d'état : flèche avec condition de la transition
|
||||
- actions: format: "event [guard] / action"
|
||||
- sur la flèche si lors de la transition
|
||||
- interne avec mots clés (events)
|
||||
- entry: lorsque le système entre dans un état
|
||||
- exit: lorsque le système sort d'un état
|
||||
- every x s / after x s: se déclenche selon l'évent
|
||||
- guard: Condition pour que la transition ai lieu
|
||||
- il vaut mieux etre détermiste (avoir des guard mutuelement exclusif)
|
||||
- Transition composite: diamand (<>)
|
||||
- etat historique: cercle avec H ou H*
|
||||
- mémorise le dernier état visité
|
||||
- Une transition peut en sortir dans le cas ou cet état n'aurais jammais été défini
|
||||
|
||||
Le stateshart est décrit dans un document.
|
||||
|
||||
```stateshart
|
||||
interface <interface>
|
||||
|
||||
in event <name>
|
||||
...
|
||||
|
||||
out event <name>
|
||||
...
|
||||
|
||||
|
||||
interface <interface2>
|
||||
|
||||
operation <name>(<parm>):<ret>
|
||||
|
||||
```
|
Reference in New Issue
Block a user